From 7b95a04032c00665584348ad33013c2228a3260e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 10 Jul 2024 21:55:19 -0700 Subject: [PATCH 001/730] Initial commit --- .gitignore | 5 + .prettierrc | 6 + README.md | 27 ++ package.json | 28 ++ pnpm-lock.yaml | 630 ++++++++++++++++++++++++++++++++++++++ src/index.ts | 1 + src/lib/multipart.spec.ts | 305 ++++++++++++++++++ src/lib/multipart.ts | 297 ++++++++++++++++++ tsconfig.json | 16 + tsconfig.lib.json | 9 + tsconfig.spec.json | 8 + 11 files changed, 1332 insertions(+) create mode 100644 .gitignore create mode 100644 .prettierrc create mode 100644 README.md create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 src/index.ts create mode 100644 src/lib/multipart.spec.ts create mode 100644 src/lib/multipart.ts create mode 100644 tsconfig.json create mode 100644 tsconfig.lib.json create mode 100644 tsconfig.spec.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..c9282d7e5e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.tsimp +dist +node_modules + +*.tsbuildinfo \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000000..0a2ab133399 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "printWidth": 100, + "singleQuote": true, + "semi": true, + "useTabs": true +} diff --git a/README.md b/README.md new file mode 100644 index 00000000000..3428af920ee --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# multipart-web-stream + +This is a streaming multipart parser for JavaScript with no dependencies. + +Usage: + +```typescript +import { parseMultipartFormData, MultipartParseError } from 'multipart-web-stream'; + +function handleMultipartRequest(request: Request): void { + try { + // The parser `yield`s each part as a MultipartPart as it becomes available. + for await (let part of parseMultipartFormData(request)) { + console.log(part.name); + console.log(part.filename); + console.log(part.contentType); + console.log(new TextDecoder().decode(part.content)); + } + } catch (error) { + if (error instanceof MultipartParseError) { + console.error('Failed to parse multipart/form-data:', error.message); + } else { + console.error('An unexpected error occurred:', error); + } + } +} +``` diff --git a/package.json b/package.json new file mode 100644 index 00000000000..93a4b9555c9 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "multipart-web-stream", + "version": "0.1.0", + "description": "A multipart parser for fetch streams", + "scripts": { + "build": "pnpm run build:cjs && pnpm run build:esm", + "build:cjs": "tsc --outDir dist --project tsconfig.lib.json", + "build:esm": "esbuild src/index.ts --bundle --format=esm --target=node16 --outfile=dist/index.mjs", + "test": "node --import tsimp/import --test ./src/**/*.spec.ts" + }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js", + "default": "./dist/index.js" + }, + "./package.json": "./package.json" + }, + "author": "Michael Jackson ", + "license": "MIT", + "devDependencies": { + "@types/node": "^20.14.10", + "esbuild": "^0.23.0", + "tsimp": "^2.0.11", + "typescript": "^5.5.3" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000000..c08d4393129 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,630 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@types/node': + specifier: ^20.14.10 + version: 20.14.10 + esbuild: + specifier: ^0.23.0 + version: 0.23.0 + tsimp: + specifier: ^2.0.11 + version: 2.0.11(typescript@5.5.3) + typescript: + specifier: ^5.5.3 + version: 5.5.3 + +packages: + + '@esbuild/aix-ppc64@0.23.0': + resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.23.0': + resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.23.0': + resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.23.0': + resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.23.0': + resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.23.0': + resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.23.0': + resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.23.0': + resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.23.0': + resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.23.0': + resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.23.0': + resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.23.0': + resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.23.0': + resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.23.0': + resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.23.0': + resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.23.0': + resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.23.0': + resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.23.0': + resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.23.0': + resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.23.0': + resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.23.0': + resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.23.0': + resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.23.0': + resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.23.0': + resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@isaacs/cached@1.0.1': + resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} + + '@isaacs/catcher@1.0.4': + resolution: {integrity: sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@types/node@20.14.10': + resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + esbuild@0.23.0: + resolution: {integrity: sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==} + engines: {node: '>=18'} + hasBin: true + + foreground-child@3.2.1: + resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} + engines: {node: '>=14'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.2: + resolution: {integrity: sha512-qH3nOSj8q/8+Eg8LUPOq3C+6HWkpUioIjDsq1+D4zY91oZvpPttw8GwtF1nReRYKXl+1AORyFqtm2f5Q1SB6/Q==} + engines: {node: 14 >=14.21 || 16 >=16.20 || >=18} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + rimraf@5.0.9: + resolution: {integrity: sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==} + engines: {node: 14 >=14.20 || 16 >=16.20 || >=18} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sock-daemon@1.4.2: + resolution: {integrity: sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg==} + engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} + + socket-post-message@1.0.3: + resolution: {integrity: sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + tsimp@2.0.11: + resolution: {integrity: sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==} + engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.1.0 + + typescript@5.5.3: + resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + walk-up-path@3.0.1: + resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + +snapshots: + + '@esbuild/aix-ppc64@0.23.0': + optional: true + + '@esbuild/android-arm64@0.23.0': + optional: true + + '@esbuild/android-arm@0.23.0': + optional: true + + '@esbuild/android-x64@0.23.0': + optional: true + + '@esbuild/darwin-arm64@0.23.0': + optional: true + + '@esbuild/darwin-x64@0.23.0': + optional: true + + '@esbuild/freebsd-arm64@0.23.0': + optional: true + + '@esbuild/freebsd-x64@0.23.0': + optional: true + + '@esbuild/linux-arm64@0.23.0': + optional: true + + '@esbuild/linux-arm@0.23.0': + optional: true + + '@esbuild/linux-ia32@0.23.0': + optional: true + + '@esbuild/linux-loong64@0.23.0': + optional: true + + '@esbuild/linux-mips64el@0.23.0': + optional: true + + '@esbuild/linux-ppc64@0.23.0': + optional: true + + '@esbuild/linux-riscv64@0.23.0': + optional: true + + '@esbuild/linux-s390x@0.23.0': + optional: true + + '@esbuild/linux-x64@0.23.0': + optional: true + + '@esbuild/netbsd-x64@0.23.0': + optional: true + + '@esbuild/openbsd-arm64@0.23.0': + optional: true + + '@esbuild/openbsd-x64@0.23.0': + optional: true + + '@esbuild/sunos-x64@0.23.0': + optional: true + + '@esbuild/win32-arm64@0.23.0': + optional: true + + '@esbuild/win32-ia32@0.23.0': + optional: true + + '@esbuild/win32-x64@0.23.0': + optional: true + + '@isaacs/cached@1.0.1': + dependencies: + '@isaacs/catcher': 1.0.4 + + '@isaacs/catcher@1.0.4': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@types/node@20.14.10': + dependencies: + undici-types: 5.26.5 + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + balanced-match@1.0.2: {} + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + esbuild@0.23.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.23.0 + '@esbuild/android-arm': 0.23.0 + '@esbuild/android-arm64': 0.23.0 + '@esbuild/android-x64': 0.23.0 + '@esbuild/darwin-arm64': 0.23.0 + '@esbuild/darwin-x64': 0.23.0 + '@esbuild/freebsd-arm64': 0.23.0 + '@esbuild/freebsd-x64': 0.23.0 + '@esbuild/linux-arm': 0.23.0 + '@esbuild/linux-arm64': 0.23.0 + '@esbuild/linux-ia32': 0.23.0 + '@esbuild/linux-loong64': 0.23.0 + '@esbuild/linux-mips64el': 0.23.0 + '@esbuild/linux-ppc64': 0.23.0 + '@esbuild/linux-riscv64': 0.23.0 + '@esbuild/linux-s390x': 0.23.0 + '@esbuild/linux-x64': 0.23.0 + '@esbuild/netbsd-x64': 0.23.0 + '@esbuild/openbsd-arm64': 0.23.0 + '@esbuild/openbsd-x64': 0.23.0 + '@esbuild/sunos-x64': 0.23.0 + '@esbuild/win32-arm64': 0.23.0 + '@esbuild/win32-ia32': 0.23.0 + '@esbuild/win32-x64': 0.23.0 + + foreground-child@3.2.1: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + glob@10.4.5: + dependencies: + foreground-child: 3.2.1 + jackspeak: 3.4.2 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 1.11.1 + + is-fullwidth-code-point@3.0.0: {} + + isexe@2.0.0: {} + + jackspeak@3.4.2: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + lru-cache@10.4.3: {} + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + + mkdirp@3.0.1: {} + + package-json-from-dist@1.0.0: {} + + path-key@3.1.1: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + pirates@4.0.6: {} + + rimraf@5.0.9: + dependencies: + glob: 10.4.5 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + sock-daemon@1.4.2: + dependencies: + rimraf: 5.0.9 + signal-exit: 4.1.0 + socket-post-message: 1.0.3 + + socket-post-message@1.0.3: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + tsimp@2.0.11(typescript@5.5.3): + dependencies: + '@isaacs/cached': 1.0.1 + '@isaacs/catcher': 1.0.4 + foreground-child: 3.2.1 + mkdirp: 3.0.1 + pirates: 4.0.6 + rimraf: 5.0.9 + signal-exit: 4.1.0 + sock-daemon: 1.4.2 + typescript: 5.5.3 + walk-up-path: 3.0.1 + + typescript@5.5.3: {} + + undici-types@5.26.5: {} + + walk-up-path@3.0.1: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 00000000000..fc39d16a996 --- /dev/null +++ b/src/index.ts @@ -0,0 +1 @@ +export { MultipartParseError, MultipartPart, isMultipartFormData, MultipartParseOptions, parseMultipartFormData } from './lib/multipart.js'; diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts new file mode 100644 index 00000000000..ad37a578e1e --- /dev/null +++ b/src/lib/multipart.spec.ts @@ -0,0 +1,305 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { MultipartParseError, parseMultipartFormData } from './multipart.js'; + +const CRLF = '\r\n'; + +function createReadableStreamFromString( + content: string, + chunkSize = 1024 * 16 // 16 KB is default on node servers +): ReadableStream { + let encoder = new TextEncoder(); + + return new ReadableStream({ + start(controller) { + let offset = 0; + + function pushChunk() { + if (offset < content.length) { + let chunk = content.slice(offset, offset + chunkSize); + controller.enqueue(encoder.encode(chunk)); + offset += chunkSize; + setTimeout(pushChunk, 0); + } else { + controller.close(); + } + } + + pushChunk(); + }, + }); +} + +function createMockRequest( + body: string, + headers: { [key: string]: string }, + chunkSize?: number +): Request { + return { + headers: new Headers(headers), + body: createReadableStreamFromString(body, chunkSize), + } as unknown as Request; +} + +describe('Multipart Form Data Parser', async () => { + let boundary = 'boundary123'; + + it('Successfully parses a simple multipart form', async () => { + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + '', + 'value1', + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'field1'); + assert.equal(new TextDecoder().decode(parts[0].content), 'value1'); + }); + + it('Handles multiple parts correctly', async () => { + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + '', + 'value1', + `--${boundary}`, + 'Content-Disposition: form-data; name="field2"', + '', + 'value2', + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 2); + assert.equal(parts[0].name, 'field1'); + assert.equal(new TextDecoder().decode(parts[0].content), 'value1'); + assert.equal(parts[1].name, 'field2'); + assert.equal(new TextDecoder().decode(parts[1].content), 'value2'); + }); + + it('Handles file uploads correctly', async () => { + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="file1"; filename="test.txt"', + 'Content-Type: text/plain', + '', + 'File content here', + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'file1'); + assert.equal(parts[0].filename, 'test.txt'); + assert.equal(parts[0].contentType, 'text/plain'); + assert.equal(new TextDecoder().decode(parts[0].content), 'File content here'); + }); + + it('Handles multiple fields and a file upload', async () => { + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + '', + 'value1', + `--${boundary}`, + 'Content-Disposition: form-data; name="field2"', + '', + 'value2', + `--${boundary}`, + 'Content-Disposition: form-data; name="file1"; filename="test.txt"', + 'Content-Type: text/plain', + '', + 'File content here', + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 3); + assert.equal(parts[0].name, 'field1'); + assert.equal(new TextDecoder().decode(parts[0].content), 'value1'); + assert.equal(parts[1].name, 'field2'); + assert.equal(new TextDecoder().decode(parts[1].content), 'value2'); + assert.equal(parts[2].name, 'file1'); + assert.equal(parts[2].filename, 'test.txt'); + assert.equal(parts[2].contentType, 'text/plain'); + assert.equal(new TextDecoder().decode(parts[2].content), 'File content here'); + }); + + it('Throws error when Content-Type is not multipart/form-data', async () => { + let body = 'Some body'; + let request = createMockRequest(body, { 'Content-Type': 'text/plain' }); + + await assert.rejects(async () => { + await parseMultipartFormData(request).next(); + }, MultipartParseError); + }); + + it('Throws error when boundary is missing', async () => { + let body = 'Some body'; + let request = createMockRequest(body, { 'Content-Type': 'multipart/form-data' }); + + await assert.rejects(async () => { + await parseMultipartFormData(request).next(); + }, MultipartParseError); + }); + + it('Throws error when headers exceed maximum size', async () => { + let largeHeader = 'X-Large-Header: ' + 'a'.repeat(1024 * 1024); // 1MB header + let body = [ + `--${boundary}`, + largeHeader, + 'Content-Disposition: form-data; name="field1"', + '', + 'value1', + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest( + body, + { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + 1024 * 256 + ); + + await assert.rejects(async () => { + await parseMultipartFormData(request, { maxHeaderSize: 1024 }).next(); + }, MultipartParseError); + }); + + it('Throws error when part exceeds maximum size', async () => { + let largeContent = 'a'.repeat(1024 * 1024 * 11); // 11MB content + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + '', + largeContent, + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest( + body, + { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + 1024 * 1024 + ); + + await assert.rejects(async () => { + await parseMultipartFormData(request, { maxPartSize: 1024 * 1024 * 10 }).next(); + }, MultipartParseError); + }); + + it('Handles malformed messages', async () => { + let body = [`--${boundary}`, 'Invalid-Header', '', 'Some content', `--${boundary}--`].join( + CRLF + ); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].headers.get('Invalid-Header'), null); + assert.equal(new TextDecoder().decode(parts[0].content), 'Some content'); + }); + + it('Throws error when final boundary is missing', async () => { + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + '', + 'value1', + `--${boundary}`, + ].join(CRLF); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + await assert.rejects(async () => { + for await (let part of parseMultipartFormData(request)) { + // Consume all parts + } + }, MultipartParseError); + }); + + it('Handles empty parts correctly', async () => { + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="empty"', + '', + '', + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'empty'); + assert.equal(parts[0].content.byteLength, 0); + }); + + it('Parses complex Content-Disposition correctly', async () => { + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="file"; filename="name with spaces.txt"; filename*=utf-8\'\'encoded%20filename.txt', + '', + 'content', + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'file'); + assert.equal(parts[0].filename, 'encoded filename.txt'); + assert.equal(parts[0].contentDisposition.filename, 'name with spaces.txt'); + assert.equal(parts[0].contentDisposition.filenameSplat, "utf-8''encoded%20filename.txt"); + }); +}); diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts new file mode 100644 index 00000000000..2482b574e44 --- /dev/null +++ b/src/lib/multipart.ts @@ -0,0 +1,297 @@ +const CRLF = '\r\n'; + +const DefaultMaxHeaderSize = 1024 * 1024; // 1 MB +const DefaultMaxPartSize = 1024 * 1024 * 10; // 10 MB + +export class MultipartParseError extends Error { + constructor(message: string) { + super(message); + this.name = 'MultipartParseError'; + } +} + +export interface ContentDisposition { + type: string | null; + name: string | null; + filename: string | null; + filenameSplat: string | null; + creationDate: Date | null; + modificationDate: Date | null; + readDate: Date | null; + size: number | null; +} + +export class MultipartPart { + private _parsedContentDisposition: ContentDisposition | null = null; + + constructor(public headers: Headers, public content: Uint8Array) {} + + get contentDisposition(): ContentDisposition { + if (this._parsedContentDisposition) { + return this._parsedContentDisposition; + } + + let header = this.headers.get('Content-Disposition'); + if (!header) { + return (this._parsedContentDisposition = { + type: null, + name: null, + filename: null, + filenameSplat: null, + creationDate: null, + modificationDate: null, + readDate: null, + size: null, + }); + } + + let parts = header.split(';').map((part) => part.trim()); + let type = parts.shift() || null; + let params: { [key: string]: string } = {}; + + for (let part of parts) { + let [key, value] = part.split('='); + if (key && value) { + params[key.toLowerCase()] = value.replace(/^["']|["']$/g, ''); + } + } + + return (this._parsedContentDisposition = { + type, + name: params['name'] || null, + filename: params['filename'] || null, + filenameSplat: params['filename*'] || null, + creationDate: params['creation-date'] ? new Date(params['creation-date']) : null, + modificationDate: params['modification-date'] ? new Date(params['modification-date']) : null, + readDate: params['read-date'] ? new Date(params['read-date']) : null, + size: params['size'] ? parseInt(params['size'], 10) : null, + }); + } + + get contentType(): string | null { + return this.headers.get('content-type') || null; + } + + get filename(): string | null { + if (this.contentDisposition.filenameSplat) { + try { + let [encodingPart, _languagePart, ...filenameParts] = + this.contentDisposition.filenameSplat.split("'"); + let encoding = encodingPart.toLowerCase(); + let encodedFilename = filenameParts.join("'"); + + let filename = decodeURIComponent(encodedFilename.replace(/%([0-9A-Fa-f]{2})/g, '%$1')); + + if (encoding !== 'utf-8') { + console.warn(`Unsupported encoding: ${encoding}. Treating as UTF-8.`); + } + + return filename; + } catch (error) { + throw new Error(`Failed to decode internationalized filename*: ${error}`); + } + } + + return this.contentDisposition.filename; + } + + get name(): string | null { + return this.contentDisposition.name; + } +} + +export function isMultipartFormData(request: Request): boolean { + let contentType = request.headers.get('Content-Type'); + return contentType != null && contentType.startsWith('multipart/form-data'); +} + +export interface MultipartParseOptions { + maxHeaderSize?: number; + maxPartSize?: number; +} + +const textEncoder = new TextEncoder(); +const textDecoder = new TextDecoder(); +const findDoubleCRLF = createSeqFinder(textEncoder.encode(CRLF + CRLF)); + +/** + * Parses a multipart/form-data request body and yields each part as a MultipartPart object. + * + * Throws MultipartParseError if the parse fails for some reason. + * + * + * Example: + * + * ```typescript + * import { parseMultipartFormData, MultipartParseError } from 'multipart-web-stream'; + * + * function handleMultipartRequest(request: Request): void { + * try { + * for await (let part of parseMultipartFormData(request)) { + * console.log(part.name); + * console.log(part.filename); + * console.log(part.contentType); + * console.log(new TextDecoder().decode(part.content)); + * } + * } catch (error) { + * if (error instanceof MultipartParseError) { + * console.error('Failed to parse multipart/form-data:', error.message); + * } else { + * console.error('An unexpected error occurred:', error); + * } + * } + * } + * ``` + * + * @param request + * @param options + */ +export async function* parseMultipartFormData( + request: Request, + options: MultipartParseOptions = {} +): AsyncGenerator { + let maxHeaderSize = options.maxHeaderSize || DefaultMaxHeaderSize; + let maxPartSize = options.maxPartSize || DefaultMaxPartSize; + + if (!request.body) { + throw new MultipartParseError('Request body is empty'); + } + if (!isMultipartFormData(request)) { + throw new MultipartParseError('Request is not multipart/form-data'); + } + + let boundaryMatch = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(request.headers.get('Content-Type')!); + if (!boundaryMatch) { + throw new MultipartParseError('Invalid Content-Type header: missing boundary'); + } + + let boundary = boundaryMatch[1] || boundaryMatch[2]; // handle quoted and unquoted boundaries + let boundarySeq = textEncoder.encode(`--${boundary}`); + let findBoundary = createSeqFinder(boundarySeq); + + let initialBoundaryFound = false; + let isFinished = false; + let reader = request.body.getReader(); + let buffer = new Uint8Array(0); + let boundarySearchStartIndex = 0; + + try { + while (!isFinished) { + const { done, value } = await reader.read(); + if (done) { + if (!isFinished) { + throw new MultipartParseError('Unexpected end of stream: final boundary not found'); + } + break; + } + + buffer = Uint8Array.from([...buffer, ...value]); + + while (true) { + let boundaryIndex = findBoundary(buffer, boundarySearchStartIndex); + if (boundaryIndex === -1) { + // No boundary found, remember the last search index + boundarySearchStartIndex = Math.max(0, buffer.length - boundarySeq.length); + break; + } + + if (initialBoundaryFound) { + let partData = buffer.subarray(0, boundaryIndex - 2); // -2 to remove \r\n before boundary + let headerEndIndex = findDoubleCRLF(partData); + + let headers: Headers; + let content: Uint8Array; + if (headerEndIndex !== -1) { + if (headerEndIndex > maxHeaderSize) { + throw new MultipartParseError( + `Headers size exceeds maximum allowed size of ${maxHeaderSize} bytes` + ); + } + + headers = parseHeaders(partData.subarray(0, headerEndIndex)); + content = partData.subarray(headerEndIndex + 4); // +4 to remove \r\n\r\n after headers + } else { + // No headers found, treat entire part as content + headers = new Headers(); + content = partData; + } + + if (content.length > maxPartSize) { + throw new MultipartParseError( + `Part size exceeds maximum allowed size of ${maxPartSize} bytes` + ); + } + + yield new MultipartPart(headers, content); + } else { + initialBoundaryFound = true; + } + + buffer = buffer.subarray(boundaryIndex + boundarySeq.length); + boundarySearchStartIndex = 0; + + if (buffer.length > 1 && buffer[0] === 45 && buffer[1] === 45) { + isFinished = true; + buffer = buffer.subarray(2); // Keep any data after final boundary + break; + } + } + } + + if (buffer.length > 0) { + throw new MultipartParseError('Unexpected data after final boundary'); + } + } finally { + reader.releaseLock(); + } +} + +function parseHeaders(headerData: Uint8Array): Headers { + let headers = new Headers(); + + let lines = textDecoder.decode(headerData).split(CRLF); + for (let line of lines) { + let [key, value] = line.split(':').map((s) => s.trim()); + if (key && value) { + headers.append(key, value); + } + } + + return headers; +} + +function createSeqFinder(needle: Uint8Array): (haystack: Uint8Array, offset?: number) => number { + let skipTable = new Map(); + for (let i = 0; i < needle.length - 1; i++) { + skipTable.set(needle[i], needle.length - 1 - i); + } + + return (haystack: Uint8Array, offset = 0) => findSeq(haystack, needle, skipTable, offset); +} + +function findSeq( + haystack: Uint8Array, + needle: Uint8Array, + skipTable: Map, + offset: number +): number { + // boyer-moore-horspool algorithm + if (needle.length === 0) { + return offset; + } + + let i = offset + needle.length - 1; + while (i < haystack.length) { + let j = needle.length - 1; + while (j >= 0 && haystack[i] === needle[j]) { + i--; + j--; + } + if (j < 0) { + return i + 1; + } + i += Math.max(needle.length - j, skipTable.get(haystack[i]) || needle.length); + } + + return -1; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000000..5b33c551e80 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "lib": ["DOM"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true + }, + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/tsconfig.lib.json b/tsconfig.lib.json new file mode 100644 index 00000000000..1d3c16996df --- /dev/null +++ b/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.spec.ts"], + "compilerOptions": { + "composite": true, + "rootDir": "src" + } +} diff --git a/tsconfig.spec.json b/tsconfig.spec.json new file mode 100644 index 00000000000..591b372431e --- /dev/null +++ b/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": { + "composite": true, + "types": ["node"] + } +} From 9c1796008b4552e5cef0647aa3ba48366cd9cf91 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 10 Jul 2024 21:58:22 -0700 Subject: [PATCH 002/730] Use spaces for indentation --- .prettierrc | 2 +- README.md | 30 +- package.json | 52 ++-- src/index.ts | 8 +- src/lib/multipart.spec.ts | 576 +++++++++++++++++++------------------- src/lib/multipart.ts | 450 ++++++++++++++--------------- tsconfig.json | 28 +- tsconfig.lib.json | 14 +- tsconfig.spec.json | 12 +- 9 files changed, 589 insertions(+), 583 deletions(-) diff --git a/.prettierrc b/.prettierrc index 0a2ab133399..0aac4a10c5e 100644 --- a/.prettierrc +++ b/.prettierrc @@ -2,5 +2,5 @@ "printWidth": 100, "singleQuote": true, "semi": true, - "useTabs": true + "useTabs": false } diff --git a/README.md b/README.md index 3428af920ee..13e76d8f5d5 100644 --- a/README.md +++ b/README.md @@ -8,20 +8,20 @@ Usage: import { parseMultipartFormData, MultipartParseError } from 'multipart-web-stream'; function handleMultipartRequest(request: Request): void { - try { - // The parser `yield`s each part as a MultipartPart as it becomes available. - for await (let part of parseMultipartFormData(request)) { - console.log(part.name); - console.log(part.filename); - console.log(part.contentType); - console.log(new TextDecoder().decode(part.content)); - } - } catch (error) { - if (error instanceof MultipartParseError) { - console.error('Failed to parse multipart/form-data:', error.message); - } else { - console.error('An unexpected error occurred:', error); - } - } + try { + // The parser `yield`s each part as a MultipartPart as it becomes available. + for await (let part of parseMultipartFormData(request)) { + console.log(part.name); + console.log(part.filename); + console.log(part.contentType); + console.log(new TextDecoder().decode(part.content)); + } + } catch (error) { + if (error instanceof MultipartParseError) { + console.error('Failed to parse multipart/form-data:', error.message); + } else { + console.error('An unexpected error occurred:', error); + } + } } ``` diff --git a/package.json b/package.json index 93a4b9555c9..8eca9fe5bc6 100644 --- a/package.json +++ b/package.json @@ -1,28 +1,28 @@ { - "name": "multipart-web-stream", - "version": "0.1.0", - "description": "A multipart parser for fetch streams", - "scripts": { - "build": "pnpm run build:cjs && pnpm run build:esm", - "build:cjs": "tsc --outDir dist --project tsconfig.lib.json", - "build:esm": "esbuild src/index.ts --bundle --format=esm --target=node16 --outfile=dist/index.mjs", - "test": "node --import tsimp/import --test ./src/**/*.spec.ts" - }, - "exports": { - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.mjs", - "require": "./dist/index.js", - "default": "./dist/index.js" - }, - "./package.json": "./package.json" - }, - "author": "Michael Jackson ", - "license": "MIT", - "devDependencies": { - "@types/node": "^20.14.10", - "esbuild": "^0.23.0", - "tsimp": "^2.0.11", - "typescript": "^5.5.3" - } + "name": "multipart-web-stream", + "version": "0.1.0", + "description": "A multipart parser for fetch streams", + "scripts": { + "build": "pnpm run build:cjs && pnpm run build:esm", + "build:cjs": "tsc --outDir dist --project tsconfig.lib.json", + "build:esm": "esbuild src/index.ts --bundle --format=esm --target=node16 --outfile=dist/index.mjs", + "test": "node --import tsimp/import --test ./src/**/*.spec.ts" + }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js", + "default": "./dist/index.js" + }, + "./package.json": "./package.json" + }, + "author": "Michael Jackson ", + "license": "MIT", + "devDependencies": { + "@types/node": "^20.14.10", + "esbuild": "^0.23.0", + "tsimp": "^2.0.11", + "typescript": "^5.5.3" + } } diff --git a/src/index.ts b/src/index.ts index fc39d16a996..56b4fa96093 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,7 @@ -export { MultipartParseError, MultipartPart, isMultipartFormData, MultipartParseOptions, parseMultipartFormData } from './lib/multipart.js'; +export { + MultipartParseError, + MultipartPart, + isMultipartFormData, + MultipartParseOptions, + parseMultipartFormData, +} from './lib/multipart.js'; diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index ad37a578e1e..f1646e573cd 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -6,300 +6,300 @@ import { MultipartParseError, parseMultipartFormData } from './multipart.js'; const CRLF = '\r\n'; function createReadableStreamFromString( - content: string, - chunkSize = 1024 * 16 // 16 KB is default on node servers + content: string, + chunkSize = 1024 * 16 // 16 KB is default on node servers ): ReadableStream { - let encoder = new TextEncoder(); - - return new ReadableStream({ - start(controller) { - let offset = 0; - - function pushChunk() { - if (offset < content.length) { - let chunk = content.slice(offset, offset + chunkSize); - controller.enqueue(encoder.encode(chunk)); - offset += chunkSize; - setTimeout(pushChunk, 0); - } else { - controller.close(); - } - } - - pushChunk(); - }, - }); + let encoder = new TextEncoder(); + + return new ReadableStream({ + start(controller) { + let offset = 0; + + function pushChunk() { + if (offset < content.length) { + let chunk = content.slice(offset, offset + chunkSize); + controller.enqueue(encoder.encode(chunk)); + offset += chunkSize; + setTimeout(pushChunk, 0); + } else { + controller.close(); + } + } + + pushChunk(); + }, + }); } function createMockRequest( - body: string, - headers: { [key: string]: string }, - chunkSize?: number + body: string, + headers: { [key: string]: string }, + chunkSize?: number ): Request { - return { - headers: new Headers(headers), - body: createReadableStreamFromString(body, chunkSize), - } as unknown as Request; + return { + headers: new Headers(headers), + body: createReadableStreamFromString(body, chunkSize), + } as unknown as Request; } describe('Multipart Form Data Parser', async () => { - let boundary = 'boundary123'; - - it('Successfully parses a simple multipart form', async () => { - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="field1"', - '', - 'value1', - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }); - - let parts = []; - for await (let part of parseMultipartFormData(request)) { - parts.push(part); - } - - assert.equal(parts.length, 1); - assert.equal(parts[0].name, 'field1'); - assert.equal(new TextDecoder().decode(parts[0].content), 'value1'); - }); - - it('Handles multiple parts correctly', async () => { - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="field1"', - '', - 'value1', - `--${boundary}`, - 'Content-Disposition: form-data; name="field2"', - '', - 'value2', - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }); - - let parts = []; - for await (let part of parseMultipartFormData(request)) { - parts.push(part); - } - - assert.equal(parts.length, 2); - assert.equal(parts[0].name, 'field1'); - assert.equal(new TextDecoder().decode(parts[0].content), 'value1'); - assert.equal(parts[1].name, 'field2'); - assert.equal(new TextDecoder().decode(parts[1].content), 'value2'); - }); - - it('Handles file uploads correctly', async () => { - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="file1"; filename="test.txt"', - 'Content-Type: text/plain', - '', - 'File content here', - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }); - - let parts = []; - for await (let part of parseMultipartFormData(request)) { - parts.push(part); - } - - assert.equal(parts.length, 1); - assert.equal(parts[0].name, 'file1'); - assert.equal(parts[0].filename, 'test.txt'); - assert.equal(parts[0].contentType, 'text/plain'); - assert.equal(new TextDecoder().decode(parts[0].content), 'File content here'); - }); - - it('Handles multiple fields and a file upload', async () => { - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="field1"', - '', - 'value1', - `--${boundary}`, - 'Content-Disposition: form-data; name="field2"', - '', - 'value2', - `--${boundary}`, - 'Content-Disposition: form-data; name="file1"; filename="test.txt"', - 'Content-Type: text/plain', - '', - 'File content here', - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }); - - let parts = []; - for await (let part of parseMultipartFormData(request)) { - parts.push(part); - } - - assert.equal(parts.length, 3); - assert.equal(parts[0].name, 'field1'); - assert.equal(new TextDecoder().decode(parts[0].content), 'value1'); - assert.equal(parts[1].name, 'field2'); - assert.equal(new TextDecoder().decode(parts[1].content), 'value2'); - assert.equal(parts[2].name, 'file1'); - assert.equal(parts[2].filename, 'test.txt'); - assert.equal(parts[2].contentType, 'text/plain'); - assert.equal(new TextDecoder().decode(parts[2].content), 'File content here'); - }); - - it('Throws error when Content-Type is not multipart/form-data', async () => { - let body = 'Some body'; - let request = createMockRequest(body, { 'Content-Type': 'text/plain' }); - - await assert.rejects(async () => { - await parseMultipartFormData(request).next(); - }, MultipartParseError); - }); - - it('Throws error when boundary is missing', async () => { - let body = 'Some body'; - let request = createMockRequest(body, { 'Content-Type': 'multipart/form-data' }); - - await assert.rejects(async () => { - await parseMultipartFormData(request).next(); - }, MultipartParseError); - }); - - it('Throws error when headers exceed maximum size', async () => { - let largeHeader = 'X-Large-Header: ' + 'a'.repeat(1024 * 1024); // 1MB header - let body = [ - `--${boundary}`, - largeHeader, - 'Content-Disposition: form-data; name="field1"', - '', - 'value1', - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest( - body, - { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }, - 1024 * 256 - ); - - await assert.rejects(async () => { - await parseMultipartFormData(request, { maxHeaderSize: 1024 }).next(); - }, MultipartParseError); - }); - - it('Throws error when part exceeds maximum size', async () => { - let largeContent = 'a'.repeat(1024 * 1024 * 11); // 11MB content - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="field1"', - '', - largeContent, - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest( - body, - { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }, - 1024 * 1024 - ); - - await assert.rejects(async () => { - await parseMultipartFormData(request, { maxPartSize: 1024 * 1024 * 10 }).next(); - }, MultipartParseError); - }); - - it('Handles malformed messages', async () => { - let body = [`--${boundary}`, 'Invalid-Header', '', 'Some content', `--${boundary}--`].join( - CRLF - ); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }); - - let parts = []; - for await (let part of parseMultipartFormData(request)) { - parts.push(part); - } - - assert.equal(parts.length, 1); - assert.equal(parts[0].headers.get('Invalid-Header'), null); - assert.equal(new TextDecoder().decode(parts[0].content), 'Some content'); - }); - - it('Throws error when final boundary is missing', async () => { - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="field1"', - '', - 'value1', - `--${boundary}`, - ].join(CRLF); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }); - - await assert.rejects(async () => { - for await (let part of parseMultipartFormData(request)) { - // Consume all parts - } - }, MultipartParseError); - }); - - it('Handles empty parts correctly', async () => { - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="empty"', - '', - '', - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }); - - let parts = []; - for await (let part of parseMultipartFormData(request)) { - parts.push(part); - } - - assert.equal(parts.length, 1); - assert.equal(parts[0].name, 'empty'); - assert.equal(parts[0].content.byteLength, 0); - }); - - it('Parses complex Content-Disposition correctly', async () => { - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="file"; filename="name with spaces.txt"; filename*=utf-8\'\'encoded%20filename.txt', - '', - 'content', - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }); - - let parts = []; - for await (let part of parseMultipartFormData(request)) { - parts.push(part); - } - - assert.equal(parts.length, 1); - assert.equal(parts[0].name, 'file'); - assert.equal(parts[0].filename, 'encoded filename.txt'); - assert.equal(parts[0].contentDisposition.filename, 'name with spaces.txt'); - assert.equal(parts[0].contentDisposition.filenameSplat, "utf-8''encoded%20filename.txt"); - }); + let boundary = 'boundary123'; + + it('Successfully parses a simple multipart form', async () => { + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + '', + 'value1', + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'field1'); + assert.equal(new TextDecoder().decode(parts[0].content), 'value1'); + }); + + it('Handles multiple parts correctly', async () => { + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + '', + 'value1', + `--${boundary}`, + 'Content-Disposition: form-data; name="field2"', + '', + 'value2', + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 2); + assert.equal(parts[0].name, 'field1'); + assert.equal(new TextDecoder().decode(parts[0].content), 'value1'); + assert.equal(parts[1].name, 'field2'); + assert.equal(new TextDecoder().decode(parts[1].content), 'value2'); + }); + + it('Handles file uploads correctly', async () => { + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="file1"; filename="test.txt"', + 'Content-Type: text/plain', + '', + 'File content here', + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'file1'); + assert.equal(parts[0].filename, 'test.txt'); + assert.equal(parts[0].contentType, 'text/plain'); + assert.equal(new TextDecoder().decode(parts[0].content), 'File content here'); + }); + + it('Handles multiple fields and a file upload', async () => { + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + '', + 'value1', + `--${boundary}`, + 'Content-Disposition: form-data; name="field2"', + '', + 'value2', + `--${boundary}`, + 'Content-Disposition: form-data; name="file1"; filename="test.txt"', + 'Content-Type: text/plain', + '', + 'File content here', + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 3); + assert.equal(parts[0].name, 'field1'); + assert.equal(new TextDecoder().decode(parts[0].content), 'value1'); + assert.equal(parts[1].name, 'field2'); + assert.equal(new TextDecoder().decode(parts[1].content), 'value2'); + assert.equal(parts[2].name, 'file1'); + assert.equal(parts[2].filename, 'test.txt'); + assert.equal(parts[2].contentType, 'text/plain'); + assert.equal(new TextDecoder().decode(parts[2].content), 'File content here'); + }); + + it('Throws error when Content-Type is not multipart/form-data', async () => { + let body = 'Some body'; + let request = createMockRequest(body, { 'Content-Type': 'text/plain' }); + + await assert.rejects(async () => { + await parseMultipartFormData(request).next(); + }, MultipartParseError); + }); + + it('Throws error when boundary is missing', async () => { + let body = 'Some body'; + let request = createMockRequest(body, { 'Content-Type': 'multipart/form-data' }); + + await assert.rejects(async () => { + await parseMultipartFormData(request).next(); + }, MultipartParseError); + }); + + it('Throws error when headers exceed maximum size', async () => { + let largeHeader = 'X-Large-Header: ' + 'a'.repeat(1024 * 1024); // 1MB header + let body = [ + `--${boundary}`, + largeHeader, + 'Content-Disposition: form-data; name="field1"', + '', + 'value1', + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest( + body, + { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + 1024 * 256 + ); + + await assert.rejects(async () => { + await parseMultipartFormData(request, { maxHeaderSize: 1024 }).next(); + }, MultipartParseError); + }); + + it('Throws error when part exceeds maximum size', async () => { + let largeContent = 'a'.repeat(1024 * 1024 * 11); // 11MB content + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + '', + largeContent, + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest( + body, + { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + 1024 * 1024 + ); + + await assert.rejects(async () => { + await parseMultipartFormData(request, { maxPartSize: 1024 * 1024 * 10 }).next(); + }, MultipartParseError); + }); + + it('Handles malformed messages', async () => { + let body = [`--${boundary}`, 'Invalid-Header', '', 'Some content', `--${boundary}--`].join( + CRLF + ); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].headers.get('Invalid-Header'), null); + assert.equal(new TextDecoder().decode(parts[0].content), 'Some content'); + }); + + it('Throws error when final boundary is missing', async () => { + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + '', + 'value1', + `--${boundary}`, + ].join(CRLF); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + await assert.rejects(async () => { + for await (let part of parseMultipartFormData(request)) { + // Consume all parts + } + }, MultipartParseError); + }); + + it('Handles empty parts correctly', async () => { + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="empty"', + '', + '', + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'empty'); + assert.equal(parts[0].content.byteLength, 0); + }); + + it('Parses complex Content-Disposition correctly', async () => { + let body = [ + `--${boundary}`, + 'Content-Disposition: form-data; name="file"; filename="name with spaces.txt"; filename*=utf-8\'\'encoded%20filename.txt', + '', + 'content', + `--${boundary}--`, + ].join(CRLF); + let request = createMockRequest(body, { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'file'); + assert.equal(parts[0].filename, 'encoded filename.txt'); + assert.equal(parts[0].contentDisposition.filename, 'name with spaces.txt'); + assert.equal(parts[0].contentDisposition.filenameSplat, "utf-8''encoded%20filename.txt"); + }); }); diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 2482b574e44..2e8a0fc6157 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -4,110 +4,110 @@ const DefaultMaxHeaderSize = 1024 * 1024; // 1 MB const DefaultMaxPartSize = 1024 * 1024 * 10; // 10 MB export class MultipartParseError extends Error { - constructor(message: string) { - super(message); - this.name = 'MultipartParseError'; - } + constructor(message: string) { + super(message); + this.name = 'MultipartParseError'; + } } export interface ContentDisposition { - type: string | null; - name: string | null; - filename: string | null; - filenameSplat: string | null; - creationDate: Date | null; - modificationDate: Date | null; - readDate: Date | null; - size: number | null; + type: string | null; + name: string | null; + filename: string | null; + filenameSplat: string | null; + creationDate: Date | null; + modificationDate: Date | null; + readDate: Date | null; + size: number | null; } export class MultipartPart { - private _parsedContentDisposition: ContentDisposition | null = null; - - constructor(public headers: Headers, public content: Uint8Array) {} - - get contentDisposition(): ContentDisposition { - if (this._parsedContentDisposition) { - return this._parsedContentDisposition; - } - - let header = this.headers.get('Content-Disposition'); - if (!header) { - return (this._parsedContentDisposition = { - type: null, - name: null, - filename: null, - filenameSplat: null, - creationDate: null, - modificationDate: null, - readDate: null, - size: null, - }); - } - - let parts = header.split(';').map((part) => part.trim()); - let type = parts.shift() || null; - let params: { [key: string]: string } = {}; - - for (let part of parts) { - let [key, value] = part.split('='); - if (key && value) { - params[key.toLowerCase()] = value.replace(/^["']|["']$/g, ''); - } - } - - return (this._parsedContentDisposition = { - type, - name: params['name'] || null, - filename: params['filename'] || null, - filenameSplat: params['filename*'] || null, - creationDate: params['creation-date'] ? new Date(params['creation-date']) : null, - modificationDate: params['modification-date'] ? new Date(params['modification-date']) : null, - readDate: params['read-date'] ? new Date(params['read-date']) : null, - size: params['size'] ? parseInt(params['size'], 10) : null, - }); - } - - get contentType(): string | null { - return this.headers.get('content-type') || null; - } - - get filename(): string | null { - if (this.contentDisposition.filenameSplat) { - try { - let [encodingPart, _languagePart, ...filenameParts] = - this.contentDisposition.filenameSplat.split("'"); - let encoding = encodingPart.toLowerCase(); - let encodedFilename = filenameParts.join("'"); - - let filename = decodeURIComponent(encodedFilename.replace(/%([0-9A-Fa-f]{2})/g, '%$1')); - - if (encoding !== 'utf-8') { - console.warn(`Unsupported encoding: ${encoding}. Treating as UTF-8.`); - } - - return filename; - } catch (error) { - throw new Error(`Failed to decode internationalized filename*: ${error}`); - } - } - - return this.contentDisposition.filename; - } - - get name(): string | null { - return this.contentDisposition.name; - } + private _parsedContentDisposition: ContentDisposition | null = null; + + constructor(public headers: Headers, public content: Uint8Array) {} + + get contentDisposition(): ContentDisposition { + if (this._parsedContentDisposition) { + return this._parsedContentDisposition; + } + + let header = this.headers.get('Content-Disposition'); + if (!header) { + return (this._parsedContentDisposition = { + type: null, + name: null, + filename: null, + filenameSplat: null, + creationDate: null, + modificationDate: null, + readDate: null, + size: null, + }); + } + + let parts = header.split(';').map((part) => part.trim()); + let type = parts.shift() || null; + let params: { [key: string]: string } = {}; + + for (let part of parts) { + let [key, value] = part.split('='); + if (key && value) { + params[key.toLowerCase()] = value.replace(/^["']|["']$/g, ''); + } + } + + return (this._parsedContentDisposition = { + type, + name: params['name'] || null, + filename: params['filename'] || null, + filenameSplat: params['filename*'] || null, + creationDate: params['creation-date'] ? new Date(params['creation-date']) : null, + modificationDate: params['modification-date'] ? new Date(params['modification-date']) : null, + readDate: params['read-date'] ? new Date(params['read-date']) : null, + size: params['size'] ? parseInt(params['size'], 10) : null, + }); + } + + get contentType(): string | null { + return this.headers.get('content-type') || null; + } + + get filename(): string | null { + if (this.contentDisposition.filenameSplat) { + try { + let [encodingPart, _languagePart, ...filenameParts] = + this.contentDisposition.filenameSplat.split("'"); + let encoding = encodingPart.toLowerCase(); + let encodedFilename = filenameParts.join("'"); + + let filename = decodeURIComponent(encodedFilename.replace(/%([0-9A-Fa-f]{2})/g, '%$1')); + + if (encoding !== 'utf-8') { + console.warn(`Unsupported encoding: ${encoding}. Treating as UTF-8.`); + } + + return filename; + } catch (error) { + throw new Error(`Failed to decode internationalized filename*: ${error}`); + } + } + + return this.contentDisposition.filename; + } + + get name(): string | null { + return this.contentDisposition.name; + } } export function isMultipartFormData(request: Request): boolean { - let contentType = request.headers.get('Content-Type'); - return contentType != null && contentType.startsWith('multipart/form-data'); + let contentType = request.headers.get('Content-Type'); + return contentType != null && contentType.startsWith('multipart/form-data'); } export interface MultipartParseOptions { - maxHeaderSize?: number; - maxPartSize?: number; + maxHeaderSize?: number; + maxPartSize?: number; } const textEncoder = new TextEncoder(); @@ -147,151 +147,151 @@ const findDoubleCRLF = createSeqFinder(textEncoder.encode(CRLF + CRLF)); * @param options */ export async function* parseMultipartFormData( - request: Request, - options: MultipartParseOptions = {} + request: Request, + options: MultipartParseOptions = {} ): AsyncGenerator { - let maxHeaderSize = options.maxHeaderSize || DefaultMaxHeaderSize; - let maxPartSize = options.maxPartSize || DefaultMaxPartSize; - - if (!request.body) { - throw new MultipartParseError('Request body is empty'); - } - if (!isMultipartFormData(request)) { - throw new MultipartParseError('Request is not multipart/form-data'); - } - - let boundaryMatch = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(request.headers.get('Content-Type')!); - if (!boundaryMatch) { - throw new MultipartParseError('Invalid Content-Type header: missing boundary'); - } - - let boundary = boundaryMatch[1] || boundaryMatch[2]; // handle quoted and unquoted boundaries - let boundarySeq = textEncoder.encode(`--${boundary}`); - let findBoundary = createSeqFinder(boundarySeq); - - let initialBoundaryFound = false; - let isFinished = false; - let reader = request.body.getReader(); - let buffer = new Uint8Array(0); - let boundarySearchStartIndex = 0; - - try { - while (!isFinished) { - const { done, value } = await reader.read(); - if (done) { - if (!isFinished) { - throw new MultipartParseError('Unexpected end of stream: final boundary not found'); - } - break; - } - - buffer = Uint8Array.from([...buffer, ...value]); - - while (true) { - let boundaryIndex = findBoundary(buffer, boundarySearchStartIndex); - if (boundaryIndex === -1) { - // No boundary found, remember the last search index - boundarySearchStartIndex = Math.max(0, buffer.length - boundarySeq.length); - break; - } - - if (initialBoundaryFound) { - let partData = buffer.subarray(0, boundaryIndex - 2); // -2 to remove \r\n before boundary - let headerEndIndex = findDoubleCRLF(partData); - - let headers: Headers; - let content: Uint8Array; - if (headerEndIndex !== -1) { - if (headerEndIndex > maxHeaderSize) { - throw new MultipartParseError( - `Headers size exceeds maximum allowed size of ${maxHeaderSize} bytes` - ); - } - - headers = parseHeaders(partData.subarray(0, headerEndIndex)); - content = partData.subarray(headerEndIndex + 4); // +4 to remove \r\n\r\n after headers - } else { - // No headers found, treat entire part as content - headers = new Headers(); - content = partData; - } - - if (content.length > maxPartSize) { - throw new MultipartParseError( - `Part size exceeds maximum allowed size of ${maxPartSize} bytes` - ); - } - - yield new MultipartPart(headers, content); - } else { - initialBoundaryFound = true; - } - - buffer = buffer.subarray(boundaryIndex + boundarySeq.length); - boundarySearchStartIndex = 0; - - if (buffer.length > 1 && buffer[0] === 45 && buffer[1] === 45) { - isFinished = true; - buffer = buffer.subarray(2); // Keep any data after final boundary - break; - } - } - } - - if (buffer.length > 0) { - throw new MultipartParseError('Unexpected data after final boundary'); - } - } finally { - reader.releaseLock(); - } + let maxHeaderSize = options.maxHeaderSize || DefaultMaxHeaderSize; + let maxPartSize = options.maxPartSize || DefaultMaxPartSize; + + if (!request.body) { + throw new MultipartParseError('Request body is empty'); + } + if (!isMultipartFormData(request)) { + throw new MultipartParseError('Request is not multipart/form-data'); + } + + let boundaryMatch = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(request.headers.get('Content-Type')!); + if (!boundaryMatch) { + throw new MultipartParseError('Invalid Content-Type header: missing boundary'); + } + + let boundary = boundaryMatch[1] || boundaryMatch[2]; // handle quoted and unquoted boundaries + let boundarySeq = textEncoder.encode(`--${boundary}`); + let findBoundary = createSeqFinder(boundarySeq); + + let initialBoundaryFound = false; + let isFinished = false; + let reader = request.body.getReader(); + let buffer = new Uint8Array(0); + let boundarySearchStartIndex = 0; + + try { + while (!isFinished) { + const { done, value } = await reader.read(); + if (done) { + if (!isFinished) { + throw new MultipartParseError('Unexpected end of stream: final boundary not found'); + } + break; + } + + buffer = Uint8Array.from([...buffer, ...value]); + + while (true) { + let boundaryIndex = findBoundary(buffer, boundarySearchStartIndex); + if (boundaryIndex === -1) { + // No boundary found, remember the last search index + boundarySearchStartIndex = Math.max(0, buffer.length - boundarySeq.length); + break; + } + + if (initialBoundaryFound) { + let partData = buffer.subarray(0, boundaryIndex - 2); // -2 to remove \r\n before boundary + let headerEndIndex = findDoubleCRLF(partData); + + let headers: Headers; + let content: Uint8Array; + if (headerEndIndex !== -1) { + if (headerEndIndex > maxHeaderSize) { + throw new MultipartParseError( + `Headers size exceeds maximum allowed size of ${maxHeaderSize} bytes` + ); + } + + headers = parseHeaders(partData.subarray(0, headerEndIndex)); + content = partData.subarray(headerEndIndex + 4); // +4 to remove \r\n\r\n after headers + } else { + // No headers found, treat entire part as content + headers = new Headers(); + content = partData; + } + + if (content.length > maxPartSize) { + throw new MultipartParseError( + `Part size exceeds maximum allowed size of ${maxPartSize} bytes` + ); + } + + yield new MultipartPart(headers, content); + } else { + initialBoundaryFound = true; + } + + buffer = buffer.subarray(boundaryIndex + boundarySeq.length); + boundarySearchStartIndex = 0; + + if (buffer.length > 1 && buffer[0] === 45 && buffer[1] === 45) { + isFinished = true; + buffer = buffer.subarray(2); // Keep any data after final boundary + break; + } + } + } + + if (buffer.length > 0) { + throw new MultipartParseError('Unexpected data after final boundary'); + } + } finally { + reader.releaseLock(); + } } function parseHeaders(headerData: Uint8Array): Headers { - let headers = new Headers(); + let headers = new Headers(); - let lines = textDecoder.decode(headerData).split(CRLF); - for (let line of lines) { - let [key, value] = line.split(':').map((s) => s.trim()); - if (key && value) { - headers.append(key, value); - } - } + let lines = textDecoder.decode(headerData).split(CRLF); + for (let line of lines) { + let [key, value] = line.split(':').map((s) => s.trim()); + if (key && value) { + headers.append(key, value); + } + } - return headers; + return headers; } function createSeqFinder(needle: Uint8Array): (haystack: Uint8Array, offset?: number) => number { - let skipTable = new Map(); - for (let i = 0; i < needle.length - 1; i++) { - skipTable.set(needle[i], needle.length - 1 - i); - } + let skipTable = new Map(); + for (let i = 0; i < needle.length - 1; i++) { + skipTable.set(needle[i], needle.length - 1 - i); + } - return (haystack: Uint8Array, offset = 0) => findSeq(haystack, needle, skipTable, offset); + return (haystack: Uint8Array, offset = 0) => findSeq(haystack, needle, skipTable, offset); } function findSeq( - haystack: Uint8Array, - needle: Uint8Array, - skipTable: Map, - offset: number + haystack: Uint8Array, + needle: Uint8Array, + skipTable: Map, + offset: number ): number { - // boyer-moore-horspool algorithm - if (needle.length === 0) { - return offset; - } - - let i = offset + needle.length - 1; - while (i < haystack.length) { - let j = needle.length - 1; - while (j >= 0 && haystack[i] === needle[j]) { - i--; - j--; - } - if (j < 0) { - return i + 1; - } - i += Math.max(needle.length - j, skipTable.get(haystack[i]) || needle.length); - } - - return -1; + // boyer-moore-horspool algorithm + if (needle.length === 0) { + return offset; + } + + let i = offset + needle.length - 1; + while (i < haystack.length) { + let j = needle.length - 1; + while (j >= 0 && haystack[i] === needle[j]) { + i--; + j--; + } + if (j < 0) { + return i + 1; + } + i += Math.max(needle.length - j, skipTable.get(haystack[i]) || needle.length); + } + + return -1; } diff --git a/tsconfig.json b/tsconfig.json index 5b33c551e80..1036256c789 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,16 +1,16 @@ { - "compilerOptions": { - "lib": ["DOM"], - "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true - }, - "references": [ - { - "path": "./tsconfig.lib.json" - }, - { - "path": "./tsconfig.spec.json" - } - ] + "compilerOptions": { + "lib": ["DOM"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true + }, + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] } diff --git a/tsconfig.lib.json b/tsconfig.lib.json index 1d3c16996df..8e712f7d6c8 100644 --- a/tsconfig.lib.json +++ b/tsconfig.lib.json @@ -1,9 +1,9 @@ { - "extends": "./tsconfig.json", - "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts"], - "compilerOptions": { - "composite": true, - "rootDir": "src" - } + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.spec.ts"], + "compilerOptions": { + "composite": true, + "rootDir": "src" + } } diff --git a/tsconfig.spec.json b/tsconfig.spec.json index 591b372431e..79d1e4a027a 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -1,8 +1,8 @@ { - "extends": "./tsconfig.json", - "include": ["src/**/*.ts"], - "compilerOptions": { - "composite": true, - "types": ["node"] - } + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": { + "composite": true, + "types": ["node"] + } } From 05f4097e2eebbbadaa5a80e5660a34e4bd466aad Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 10 Jul 2024 22:05:30 -0700 Subject: [PATCH 003/730] Fix the build --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 1036256c789..ba16aeed449 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "lib": ["DOM"], + "lib": ["DOM", "ES2020"], "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true From d8d24c3c280851445ce499084c7c146547b6446a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 10 Jul 2024 22:20:45 -0700 Subject: [PATCH 004/730] Update README --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 13e76d8f5d5..f6ce321252f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,13 @@ This is a streaming multipart parser for JavaScript with no dependencies. -Usage: +## Installation + +```sh +$ npm install multipart-web-stream +``` + +## Usage ```typescript import { parseMultipartFormData, MultipartParseError } from 'multipart-web-stream'; From ea2fecb6682af7df717d925f0616fab86073e46c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 11 Jul 2024 09:04:44 -0700 Subject: [PATCH 005/730] Small tweaks --- src/lib/multipart.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 2e8a0fc6157..01ddebadac1 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -69,7 +69,7 @@ export class MultipartPart { } get contentType(): string | null { - return this.headers.get('content-type') || null; + return this.headers.get('Content-Type') || null; } get filename(): string | null { @@ -153,12 +153,12 @@ export async function* parseMultipartFormData( let maxHeaderSize = options.maxHeaderSize || DefaultMaxHeaderSize; let maxPartSize = options.maxPartSize || DefaultMaxPartSize; - if (!request.body) { - throw new MultipartParseError('Request body is empty'); - } if (!isMultipartFormData(request)) { throw new MultipartParseError('Request is not multipart/form-data'); } + if (!request.body) { + throw new MultipartParseError('Request body is empty'); + } let boundaryMatch = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(request.headers.get('Content-Type')!); if (!boundaryMatch) { From 4d425a746e0de3a97ae87ef313a997e54b6a493b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 11 Jul 2024 23:38:38 -0700 Subject: [PATCH 006/730] Initial commit --- .gitignore | 5 + .prettierrc | 6 + README.md | 109 +++++ package.json | 20 + pnpm-lock.yaml | 629 ++++++++++++++++++++++++++++ src/index.ts | 9 + src/lib/content-disposition.spec.ts | 212 ++++++++++ src/lib/content-disposition.ts | 113 +++++ src/lib/content-type.spec.ts | 116 +++++ src/lib/content-type.ts | 62 +++ src/lib/cookie.spec.ts | 119 ++++++ src/lib/cookie.ts | 85 ++++ src/lib/header-names.spec.ts | 94 +++++ src/lib/header-names.ts | 20 + src/lib/header-value.ts | 3 + src/lib/param-values.ts | 13 + src/lib/super-headers.spec.ts | 184 ++++++++ src/lib/super-headers.ts | 150 +++++++ tsconfig.json | 16 + tsconfig.lib.json | 9 + tsconfig.spec.json | 8 + 21 files changed, 1982 insertions(+) create mode 100644 .gitignore create mode 100644 .prettierrc create mode 100644 README.md create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 src/index.ts create mode 100644 src/lib/content-disposition.spec.ts create mode 100644 src/lib/content-disposition.ts create mode 100644 src/lib/content-type.spec.ts create mode 100644 src/lib/content-type.ts create mode 100644 src/lib/cookie.spec.ts create mode 100644 src/lib/cookie.ts create mode 100644 src/lib/header-names.spec.ts create mode 100644 src/lib/header-names.ts create mode 100644 src/lib/header-value.ts create mode 100644 src/lib/param-values.ts create mode 100644 src/lib/super-headers.spec.ts create mode 100644 src/lib/super-headers.ts create mode 100644 tsconfig.json create mode 100644 tsconfig.lib.json create mode 100644 tsconfig.spec.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..c9282d7e5e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.tsimp +dist +node_modules + +*.tsbuildinfo \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000000..0aac4a10c5e --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "printWidth": 100, + "singleQuote": true, + "semi": true, + "useTabs": false +} diff --git a/README.md b/README.md new file mode 100644 index 00000000000..c9000d1e83f --- /dev/null +++ b/README.md @@ -0,0 +1,109 @@ +# fetch-super-headers + +This package is a suite of tools that make it a little more fun to work with fetch `Headers`. + +## Key Features + +- Drop-in replacement for the standard `Headers` object +- Strongly typed header-specific getters and setters (e.g., `contentType`, `cookie`) +- Easy parsing and manipulation of complex headers like Content-Type and Content-Disposition +- Iterable interface for easy header enumeration +- Convenient string conversion for HTTP message assembly + +## Installation + +```sh +$ npm install fetch-super-headers +``` + +## Usage + +fetch-super-headers is designed to be a drop-in replacement for `Headers`, with some additions that make working with HTTP +headers feel a lot more like working with JavaScript objects. + +```ts +import Headers from 'fetch-super-headers'; + +let headers = new Headers(); + +// Content-Type +headers.contentType = 'application/json; charset=utf-8'; + +console.log(headers.contentType.mediaType); // 'application/json' +console.log(headers.contentType.charset); // 'utf-8' + +headers.contentType.charset = 'iso-8859-1'; +console.log(headers.get('Content-Type')); // 'application/json; charset=iso-8859-1' + +// Content-Disposition +headers.contentDisposition = + 'attachment; filename="example.pdf"; filename*=UTF-8\'\'%E4%BE%8B%E5%AD%90.pdf'; + +console.log(headers.contentDisposition.type); // 'attachment' +console.log(headers.contentDisposition.filename); // 'example.pdf' +console.log(headers.contentDisposition.preferredFilename); // '例子.pdf' + +// Cookie +headers.cookie = 'session_id=abc123; user_id=12345'; + +console.log(headers.cookie.get('session_id')); // 'abc123' +console.log(headers.cookie.get('user_id')); // '12345' + +headers.cookie.set('theme', 'dark'); +console.log(headers.get('Cookie')); // 'session_id=abc123; user_id=12345; theme=dark' +``` + +Headers are iterable: + +```ts +let headers = new Headers({ + 'Content-Type': 'application/json', + 'X-API-Key': 'secret-key', + 'Accept-Language': 'en-US,en;q=0.9', +}); + +for (let [name, value] of headers) { + console.log(`${name}: ${value}`); +} +// Content-Type: application/json +// X-Api-Key: secret-key +// Accept-Language: en-US,en;q=0.9 +``` + +And you can easily build them from an exising `Headers` object, like the one you get in a `fetch` response: + +```ts +let response = await fetch('https://example.com'); +let headers = new Headers(response.headers); +``` + +If you're assembling HTTP messages, you can easily convert to a multiline string suitable for using as a Request/Response +header block: + +```ts +let headers = new Headers(); +headers.set('content-type', 'text/html'); // or headers.contentType = 'text/html' +headers.set('X-Custom-Header', 'value'); + +console.log(headers.toString()); +// Content-Type: text/html +// X-Custom-Header: value +``` + +In addition to the high-level API, fetch-super-headers also exposes all of the low-level parsers it uses for each individual HTTP +header as public API, so you can use them in your own projects easily. + +```ts +import { ContentType } from 'fetch-super-headers'; + +let contentType = new ContentType('text/html; charset=utf-8'); +console.log(contentType.charset); +``` + +## Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. Make sure to follow the existing coding style and add tests for any new functionality. + +## License + +MIT License diff --git a/package.json b/package.json new file mode 100644 index 00000000000..2495d65bf98 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "fetch-super-headers", + "version": "0.1.0", + "description": "A suite of tools that make it a little more fun to work with fetch Headers", + "main": "dist/index.js", + "scripts": { + "build": "pnpm run build:cjs && pnpm run build:esm", + "build:cjs": "tsc --outDir dist --project tsconfig.lib.json", + "build:esm": "esbuild src/index.ts --bundle --format=esm --target=node16 --outfile=dist/index.mjs", + "test": "node --import tsimp/import --test ./src/**/*.spec.ts" + }, + "author": "Michael Jackson ", + "license": "MIT", + "devDependencies": { + "@types/node": "^20.14.10", + "esbuild": "^0.23.0", + "tsimp": "^2.0.11", + "typescript": "^5.5.3" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000000..f78a2e8d200 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,629 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@types/node': + specifier: ^20.14.10 + version: 20.14.10 + esbuild: + specifier: ^0.23.0 + version: 0.23.0 + tsimp: + specifier: ^2.0.11 + version: 2.0.11(typescript@5.5.3) + typescript: + specifier: ^5.5.3 + version: 5.5.3 + +packages: + + '@esbuild/aix-ppc64@0.23.0': + resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.23.0': + resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.23.0': + resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.23.0': + resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.23.0': + resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.23.0': + resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.23.0': + resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.23.0': + resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.23.0': + resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.23.0': + resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.23.0': + resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.23.0': + resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.23.0': + resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.23.0': + resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.23.0': + resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.23.0': + resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.23.0': + resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.23.0': + resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.23.0': + resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.23.0': + resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.23.0': + resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.23.0': + resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.23.0': + resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.23.0': + resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@isaacs/cached@1.0.1': + resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} + + '@isaacs/catcher@1.0.4': + resolution: {integrity: sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@types/node@20.14.10': + resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + esbuild@0.23.0: + resolution: {integrity: sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==} + engines: {node: '>=18'} + hasBin: true + + foreground-child@3.2.1: + resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} + engines: {node: '>=14'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + rimraf@5.0.9: + resolution: {integrity: sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==} + engines: {node: 14 >=14.20 || 16 >=16.20 || >=18} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sock-daemon@1.4.2: + resolution: {integrity: sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg==} + engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} + + socket-post-message@1.0.3: + resolution: {integrity: sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + tsimp@2.0.11: + resolution: {integrity: sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==} + engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.1.0 + + typescript@5.5.3: + resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + walk-up-path@3.0.1: + resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + +snapshots: + + '@esbuild/aix-ppc64@0.23.0': + optional: true + + '@esbuild/android-arm64@0.23.0': + optional: true + + '@esbuild/android-arm@0.23.0': + optional: true + + '@esbuild/android-x64@0.23.0': + optional: true + + '@esbuild/darwin-arm64@0.23.0': + optional: true + + '@esbuild/darwin-x64@0.23.0': + optional: true + + '@esbuild/freebsd-arm64@0.23.0': + optional: true + + '@esbuild/freebsd-x64@0.23.0': + optional: true + + '@esbuild/linux-arm64@0.23.0': + optional: true + + '@esbuild/linux-arm@0.23.0': + optional: true + + '@esbuild/linux-ia32@0.23.0': + optional: true + + '@esbuild/linux-loong64@0.23.0': + optional: true + + '@esbuild/linux-mips64el@0.23.0': + optional: true + + '@esbuild/linux-ppc64@0.23.0': + optional: true + + '@esbuild/linux-riscv64@0.23.0': + optional: true + + '@esbuild/linux-s390x@0.23.0': + optional: true + + '@esbuild/linux-x64@0.23.0': + optional: true + + '@esbuild/netbsd-x64@0.23.0': + optional: true + + '@esbuild/openbsd-arm64@0.23.0': + optional: true + + '@esbuild/openbsd-x64@0.23.0': + optional: true + + '@esbuild/sunos-x64@0.23.0': + optional: true + + '@esbuild/win32-arm64@0.23.0': + optional: true + + '@esbuild/win32-ia32@0.23.0': + optional: true + + '@esbuild/win32-x64@0.23.0': + optional: true + + '@isaacs/cached@1.0.1': + dependencies: + '@isaacs/catcher': 1.0.4 + + '@isaacs/catcher@1.0.4': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@types/node@20.14.10': + dependencies: + undici-types: 5.26.5 + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + balanced-match@1.0.2: {} + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + esbuild@0.23.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.23.0 + '@esbuild/android-arm': 0.23.0 + '@esbuild/android-arm64': 0.23.0 + '@esbuild/android-x64': 0.23.0 + '@esbuild/darwin-arm64': 0.23.0 + '@esbuild/darwin-x64': 0.23.0 + '@esbuild/freebsd-arm64': 0.23.0 + '@esbuild/freebsd-x64': 0.23.0 + '@esbuild/linux-arm': 0.23.0 + '@esbuild/linux-arm64': 0.23.0 + '@esbuild/linux-ia32': 0.23.0 + '@esbuild/linux-loong64': 0.23.0 + '@esbuild/linux-mips64el': 0.23.0 + '@esbuild/linux-ppc64': 0.23.0 + '@esbuild/linux-riscv64': 0.23.0 + '@esbuild/linux-s390x': 0.23.0 + '@esbuild/linux-x64': 0.23.0 + '@esbuild/netbsd-x64': 0.23.0 + '@esbuild/openbsd-arm64': 0.23.0 + '@esbuild/openbsd-x64': 0.23.0 + '@esbuild/sunos-x64': 0.23.0 + '@esbuild/win32-arm64': 0.23.0 + '@esbuild/win32-ia32': 0.23.0 + '@esbuild/win32-x64': 0.23.0 + + foreground-child@3.2.1: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + glob@10.4.5: + dependencies: + foreground-child: 3.2.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 1.11.1 + + is-fullwidth-code-point@3.0.0: {} + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + lru-cache@10.4.3: {} + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + + mkdirp@3.0.1: {} + + package-json-from-dist@1.0.0: {} + + path-key@3.1.1: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + pirates@4.0.6: {} + + rimraf@5.0.9: + dependencies: + glob: 10.4.5 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + sock-daemon@1.4.2: + dependencies: + rimraf: 5.0.9 + signal-exit: 4.1.0 + socket-post-message: 1.0.3 + + socket-post-message@1.0.3: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + tsimp@2.0.11(typescript@5.5.3): + dependencies: + '@isaacs/cached': 1.0.1 + '@isaacs/catcher': 1.0.4 + foreground-child: 3.2.1 + mkdirp: 3.0.1 + pirates: 4.0.6 + rimraf: 5.0.9 + signal-exit: 4.1.0 + sock-daemon: 1.4.2 + typescript: 5.5.3 + walk-up-path: 3.0.1 + + typescript@5.5.3: {} + + undici-types@5.26.5: {} + + walk-up-path@3.0.1: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 00000000000..91e2c5de65b --- /dev/null +++ b/src/index.ts @@ -0,0 +1,9 @@ +export { + SuperHeadersInit, + SuperHeaders, + SuperHeaders as default +} from "./lib/super-headers.js"; + +export { ContentDisposition } from "./lib/content-disposition.js"; +export { ContentType } from "./lib/content-type.js"; +export { Cookie } from "./lib/cookie.js"; diff --git a/src/lib/content-disposition.spec.ts b/src/lib/content-disposition.spec.ts new file mode 100644 index 00000000000..c3de4e5e97a --- /dev/null +++ b/src/lib/content-disposition.spec.ts @@ -0,0 +1,212 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { ContentDisposition } from './content-disposition.js'; + +describe('ContentDisposition', () => { + it('parses initial value correctly', () => { + let header = new ContentDisposition('attachment; filename="example.txt"'); + assert.equal(header.type, 'attachment'); + assert.equal(header.filename, 'example.txt'); + }); + + it('handles empty initial value', () => { + let header = new ContentDisposition(''); + assert.equal(header.type, ''); + assert.equal(header.filename, undefined); + }); + + it('handles whitespace in initial value', () => { + let header = new ContentDisposition(' inline ; filename = "document.pdf" '); + assert.equal(header.type, 'inline'); + assert.equal(header.filename, 'document.pdf'); + }); + + it('sets and gets type', () => { + let header = new ContentDisposition('attachment'); + header.type = 'inline'; + assert.equal(header.type, 'inline'); + }); + + it('sets and gets filename', () => { + let header = new ContentDisposition('attachment'); + header.filename = 'example.txt'; + assert.equal(header.filename, 'example.txt'); + }); + + it('sets and gets name', () => { + let header = new ContentDisposition('form-data'); + header.name = 'field1'; + assert.equal(header.name, 'field1'); + }); + + it('sets and gets filenameSplat', () => { + let header = new ContentDisposition('attachment'); + header.filenameSplat = "UTF-8''%E6%96%87%E4%BB%B6.txt"; + assert.equal(header.filenameSplat, "UTF-8''%E6%96%87%E4%BB%B6.txt"); + }); + + it('removes filename when set to null', () => { + let header = new ContentDisposition('attachment; filename="example.txt"'); + header.filename = null; + assert.equal(header.filename, undefined); + }); + + it('removes name when set to null', () => { + let header = new ContentDisposition('form-data; name="field1"'); + header.name = null; + assert.equal(header.name, undefined); + }); + + it('removes filenameSplat when set to null', () => { + let header = new ContentDisposition("attachment; filename*=UTF-8''%E6%96%87%E4%BB%B6.txt"); + header.filenameSplat = null; + assert.equal(header.filenameSplat, undefined); + }); + + it('handles quoted attribute values', () => { + let header = new ContentDisposition('attachment; filename="file with spaces.txt"'); + assert.equal(header.filename, 'file with spaces.txt'); + }); + + it('converts to string correctly', () => { + let header = new ContentDisposition('attachment; filename="example.txt"'); + assert.equal(header.toString(), 'attachment; filename=example.txt'); + }); + + it('handles multiple attributes', () => { + let header = new ContentDisposition('form-data; name="field1"; filename="example.txt"'); + assert.equal(header.type, 'form-data'); + assert.equal(header.name, 'field1'); + assert.equal(header.filename, 'example.txt'); + }); + + it('preserves case for type', () => { + let header = new ContentDisposition('Attachment'); + assert.equal(header.type, 'Attachment'); + }); + + it('converts attribute names to lowercase', () => { + let header = new ContentDisposition('attachment; FileName="example.txt"'); + assert.equal(header.filename, 'example.txt'); + }); + + it('handles attribute values with special characters', () => { + let header = new ContentDisposition( + 'attachment; filename="file with spaces and (parentheses).txt"' + ); + assert.equal(header.filename, 'file with spaces and (parentheses).txt'); + }); + + it('correctly quotes attribute values in toString()', () => { + let header = new ContentDisposition('attachment'); + header.filename = 'file "with" quotes.txt'; + assert.equal(header.toString(), 'attachment; filename="file \\"with\\" quotes.txt"'); + }); + + it('handles empty attribute values', () => { + let header = new ContentDisposition('form-data; name='); + assert.equal(header.name, ''); + }); + + it('ignores attributes without values', () => { + let header = new ContentDisposition('attachment; filename'); + assert.equal(header.filename, undefined); + }); + + it('preserves order of attributes in toString()', () => { + let header = new ContentDisposition('form-data; name="field1"; filename="example.txt"'); + assert.equal(header.toString(), 'form-data; name=field1; filename=example.txt'); + }); + + it('handles filename* (RFC 5987) correctly', () => { + let header = new ContentDisposition("attachment; filename*=UTF-8''%E6%96%87%E4%BB%B6.txt"); + assert.equal(header.filenameSplat, "UTF-8''%E6%96%87%E4%BB%B6.txt"); + }); + + it('prioritizes filename* over filename when both are present', () => { + let header = new ContentDisposition( + 'attachment; filename="fallback.txt"; filename*=UTF-8\'\'%E6%96%87%E4%BB%B6.txt' + ); + assert.equal(header.filename, 'fallback.txt'); + assert.equal(header.filenameSplat, "UTF-8''%E6%96%87%E4%BB%B6.txt"); + }); + + it('handles form-data disposition type correctly', () => { + let header = new ContentDisposition('form-data; name="uploadedfile"; filename="example.txt"'); + assert.equal(header.type, 'form-data'); + assert.equal(header.name, 'uploadedfile'); + assert.equal(header.filename, 'example.txt'); + }); + + describe('preferredFilename', () => { + it('returns filename* when both filename and filename* are present', () => { + let header = new ContentDisposition( + 'attachment; filename="old.txt"; filename*=UTF-8\'\'new.txt' + ); + assert.equal(header.preferredFilename, 'new.txt'); + }); + + it('returns filename when only filename is present', () => { + let header = new ContentDisposition('attachment; filename="document.pdf"'); + assert.equal(header.preferredFilename, 'document.pdf'); + }); + + it('returns filename* when only filename* is present', () => { + let header = new ContentDisposition("attachment; filename*=UTF-8''special%20file.txt"); + assert.equal(header.preferredFilename, 'special file.txt'); + }); + + it('handles UTF-8 encoded filename* with special characters', () => { + let header = new ContentDisposition("attachment; filename*=UTF-8''%E6%96%87%E4%BB%B6.txt"); + assert.equal(header.preferredFilename, '文件.txt'); + }); + + it('handles ISO-8859-1 encoded filename* with special characters', () => { + let header = new ContentDisposition("attachment; filename*=ISO-8859-1''f%F6o.txt"); + assert.equal(header.preferredFilename, 'föo.txt'); + }); + + it('handles filename* with spaces and other special characters', () => { + let header = new ContentDisposition( + "attachment; filename*=UTF-8''hello%20world%21%20%26%20goodbye.txt" + ); + assert.equal(header.preferredFilename, 'hello world! & goodbye.txt'); + }); + + it('returns undefined when no filename or filename* is present', () => { + let header = new ContentDisposition('attachment'); + assert.equal(header.preferredFilename, undefined); + }); + + it('falls back to filename when filename* is invalid', () => { + let header = new ContentDisposition('attachment; filename="fallback.txt"; filename*=invalid'); + assert.equal(header.preferredFilename, 'fallback.txt'); + }); + + it('correctly decodes ISO-8859-1 encoded filename', () => { + let header = new ContentDisposition("attachment; filename*=ISO-8859-1''f%F6o.txt"); + assert.equal(header.preferredFilename, 'föo.txt'); + }); + + it('correctly decodes ISO-8859-15 encoded filename', () => { + let header = new ContentDisposition("attachment; filename*=ISO-8859-15''file%A4.txt"); + assert.equal(header.preferredFilename, 'file€.txt'); + }); + + it('correctly decodes windows-1252 encoded filename', () => { + let header = new ContentDisposition("attachment; filename*=windows-1252''file%80.txt"); + assert.equal(header.preferredFilename, 'file€.txt'); + }); + + it('handles UTF-8 encoded filename correctly', () => { + let header = new ContentDisposition("attachment; filename*=UTF-8''%E6%96%87%E4%BB%B6.txt"); + assert.equal(header.preferredFilename, '文件.txt'); + }); + + it('falls back gracefully for unknown charsets', () => { + let header = new ContentDisposition("attachment; filename*=unknown-charset''file%FF.txt"); + assert.equal(header.preferredFilename, 'fileÿ.txt'); + }); + }); +}); diff --git a/src/lib/content-disposition.ts b/src/lib/content-disposition.ts new file mode 100644 index 00000000000..e812aace410 --- /dev/null +++ b/src/lib/content-disposition.ts @@ -0,0 +1,113 @@ +import { HeaderValue } from './header-value.js'; +import { quote, unquote } from './param-values.js'; + +/** + * Represents the value of a `Content-Disposition` HTTP header. + */ +export class ContentDisposition implements HeaderValue { + private attributes: Map; + private _type: string; + + constructor(initialValue: string) { + this.attributes = new Map(); + let parts = initialValue.split(';').map((part) => part.trim()); + this._type = parts[0]; + for (let i = 1; i < parts.length; i++) { + let match = parts[i].match(/([\w\*]+)\s*=\s*(.*)/); + if (match) { + this.attributes.set(match[1].toLowerCase(), unquote(match[2])); + } + } + } + + get preferredFilename(): string | undefined { + // From RFC 6266: + // Many user agent implementations predating this specification do not understand the "filename*" parameter. + // Therefore, when both "filename" and "filename*" are present in a single header field value, recipients SHOULD + // pick "filename*" and ignore "filename". This way, senders can avoid special-casing specific user agents by + // sending both the more expressive "filename*" parameter, and the "filename" parameter as fallback for legacy recipients. + let filenameSplat = this.filenameSplat; + if (filenameSplat) { + let decodedFilename = decodeFilenameSplat(filenameSplat); + if (decodedFilename) return decodedFilename; + } + + return this.filename; + } + + get filename(): string | undefined { + return this.attributes.get('filename'); + } + + set filename(value: string | null) { + if (value === null) { + this.attributes.delete('filename'); + } else { + this.attributes.set('filename', value); + } + } + + get filenameSplat(): string | undefined { + return this.attributes.get('filename*'); + } + + set filenameSplat(value: string | null) { + if (value === null) { + this.attributes.delete('filename*'); + } else { + this.attributes.set('filename*', value); + } + } + + get name(): string | undefined { + return this.attributes.get('name'); + } + + set name(value: string | null) { + if (value === null) { + this.attributes.delete('name'); + } else { + this.attributes.set('name', value); + } + } + + get type(): string { + return this._type; + } + + set type(value: string) { + this._type = value.trim(); + } + + toString(): string { + let parts = [this._type]; + for (let [key, value] of this.attributes) { + parts.push(`${key}=${quote(value)}`); + } + return parts.join('; '); + } +} + +function decodeFilenameSplat(value: string): string | null { + let match = value.match(/^([\w-]+)'([^']*)'(.+)$/); + if (!match) return null; + + let [, charset, , encodedFilename] = match; + + let decodedFilename = percentDecode(encodedFilename); + + try { + let decoder = new TextDecoder(charset); + let bytes = new Uint8Array(decodedFilename.split('').map((char) => char.charCodeAt(0))); + return decoder.decode(bytes); + } catch (error) { + console.warn(`Failed to decode filename from charset ${charset}:`, error); + return decodedFilename; + } +} + +function percentDecode(value: string): string { + return value.replace(/\+/g, ' ').replace(/%([0-9A-Fa-f]{2})/g, (_, hex) => { + return String.fromCharCode(parseInt(hex, 16)); + }); +} diff --git a/src/lib/content-type.spec.ts b/src/lib/content-type.spec.ts new file mode 100644 index 00000000000..d15a824216f --- /dev/null +++ b/src/lib/content-type.spec.ts @@ -0,0 +1,116 @@ +import * as assert from "node:assert/strict"; +import { describe, it } from "node:test"; + +import { ContentType } from "./content-type.js"; + +describe("ContentType", () => { + it("parses initial value correctly", () => { + let header = new ContentType("text/plain; charset=utf-8"); + assert.equal(header.mediaType, "text/plain"); + assert.equal(header.charset, "utf-8"); + }); + + it("handles empty initial value", () => { + let header = new ContentType(""); + assert.equal(header.mediaType, ""); + assert.equal(header.charset, undefined); + }); + + it("handles whitespace in initial value", () => { + let header = new ContentType(" text/html ; charset = iso-8859-1 "); + assert.equal(header.mediaType, "text/html"); + assert.equal(header.charset, "iso-8859-1"); + }); + + it("sets and gets media type", () => { + let header = new ContentType("text/plain"); + header.mediaType = "application/json"; + assert.equal(header.mediaType, "application/json"); + }); + + it("sets and gets charset", () => { + let header = new ContentType("text/plain"); + header.charset = "utf-8"; + assert.equal(header.charset, "utf-8"); + }); + + it("sets and gets boundary", () => { + let header = new ContentType("multipart/form-data"); + header.boundary = "abc123"; + assert.equal(header.boundary, "abc123"); + }); + + it("removes charset when set to null", () => { + let header = new ContentType("text/plain; charset=utf-8"); + header.charset = null; + assert.equal(header.charset, undefined); + }); + + it("removes boundary when set to null", () => { + let header = new ContentType("multipart/form-data; boundary=abc123"); + header.boundary = null; + assert.equal(header.boundary, undefined); + }); + + it("handles quoted attribute values", () => { + let header = new ContentType('text/plain; charset="us-ascii"'); + assert.equal(header.charset, "us-ascii"); + }); + + it("converts to string correctly", () => { + let header = new ContentType("text/plain; charset=utf-8"); + assert.equal(header.toString(), "text/plain; charset=utf-8"); + }); + + it("handles multiple attributes", () => { + let header = new ContentType( + 'multipart/form-data; boundary="abc123"; charset=utf-8' + ); + assert.equal(header.mediaType, "multipart/form-data"); + assert.equal(header.boundary, "abc123"); + assert.equal(header.charset, "utf-8"); + }); + + it("preserves case for media type", () => { + let header = new ContentType("Text/HTML"); + assert.equal(header.mediaType, "Text/HTML"); + }); + + it("converts attribute names to lowercase", () => { + let header = new ContentType("text/plain; CharSet=utf-8"); + assert.equal(header.charset, "utf-8"); + }); + + it("handles attribute values with special characters", () => { + let header = new ContentType( + 'multipart/form-data; boundary="---=_Part_0_1234567.89"' + ); + assert.equal(header.boundary, "---=_Part_0_1234567.89"); + }); + + it("correctly quotes attribute values in toString()", () => { + let header = new ContentType("multipart/form-data"); + header.boundary = "abc 123"; + assert.equal(header.toString(), 'multipart/form-data; boundary="abc 123"'); + }); + + it("handles empty attribute values", () => { + let header = new ContentType("text/plain; charset="); + assert.equal(header.charset, ""); + }); + + it("ignores attributes without values", () => { + let header = new ContentType("text/plain; charset"); + assert.equal(header.charset, undefined); + }); + + it("preserves order of attributes in toString()", () => { + let header = new ContentType( + "multipart/form-data; charset=utf-8; boundary=abc123" + ); + assert.equal( + header.toString(), + "multipart/form-data; charset=utf-8; boundary=abc123" + ); + }); +}); diff --git a/src/lib/content-type.ts b/src/lib/content-type.ts new file mode 100644 index 00000000000..44308d6aea8 --- /dev/null +++ b/src/lib/content-type.ts @@ -0,0 +1,62 @@ +import { HeaderValue } from "./header-value.js"; +import { quote, unquote } from "./param-values.js"; + +/** + * Represents the value of a `Content-Type` HTTP header. + */ +export class ContentType implements HeaderValue { + private attributes: Map; + private _mediaType: string; + + constructor(initialValue: string) { + this.attributes = new Map(); + let parts = initialValue.split(";").map(part => part.trim()); + this._mediaType = parts[0]; + for (let i = 1; i < parts.length; i++) { + let match = parts[i].match(/(\w+)\s*=\s*(.*)/); + if (match) { + this.attributes.set(match[1].toLowerCase(), unquote(match[2])); + } + } + } + + get boundary(): string | undefined { + return this.attributes.get("boundary"); + } + + set boundary(value: string | null) { + if (value === null) { + this.attributes.delete("boundary"); + } else { + this.attributes.set("boundary", value); + } + } + + get charset(): string | undefined { + return this.attributes.get("charset"); + } + + set charset(value: string | null) { + if (value === null) { + this.attributes.delete("charset"); + } else { + this.attributes.set("charset", value); + } + } + + get mediaType(): string { + return this._mediaType; + } + + set mediaType(value: string) { + this._mediaType = value.trim(); + } + + toString(): string { + let parts = [this._mediaType]; + for (let [key, value] of this.attributes) { + parts.push(`${key}=${quote(value)}`); + } + return parts.join("; "); + } +} diff --git a/src/lib/cookie.spec.ts b/src/lib/cookie.spec.ts new file mode 100644 index 00000000000..ac86e5a0cd8 --- /dev/null +++ b/src/lib/cookie.spec.ts @@ -0,0 +1,119 @@ +import * as assert from "node:assert/strict"; +import { describe, it } from "node:test"; + +import { Cookie } from "./cookie.js"; + +describe("Cookie", () => { + it("parses initial value correctly", () => { + let header = new Cookie("name1=value1; name2=value2"); + assert.equal(header.get("name1"), "value1"); + assert.equal(header.get("name2"), "value2"); + }); + + it("handles empty initial value", () => { + let header = new Cookie(""); + assert.equal(header.size, 0); + }); + + it("handles whitespace in initial value", () => { + let header = new Cookie(" name1 = value1 ; name2 = value2 "); + assert.equal(header.get("name1"), "value1"); + assert.equal(header.get("name2"), "value2"); + }); + + it("sets and gets values", () => { + let header = new Cookie(""); + header.set("name", "value"); + assert.equal(header.get("name"), "value"); + }); + + it("deletes values", () => { + let header = new Cookie("name=value"); + assert.equal(header.delete("name"), true); + assert.equal(header.delete("nonexistent"), false); + assert.equal(header.get("name"), undefined); + }); + + it("checks if value exists", () => { + let header = new Cookie("name=value"); + assert.equal(header.has("name"), true); + assert.equal(header.has("nonexistent"), false); + }); + + it("clears all values", () => { + let header = new Cookie("name1=value1; name2=value2"); + header.clear(); + assert.equal(header.size, 0); + }); + + it("iterates over entries", () => { + let header = new Cookie("name1=value1; name2=value2"); + let entries = Array.from(header.entries()); + assert.deepEqual(entries, [ + ["name1", "value1"], + ["name2", "value2"] + ]); + }); + + it("iterates over names", () => { + let header = new Cookie("name1=value1; name2=value2"); + let names = Array.from(header.names()); + assert.deepEqual(names, ["name1", "name2"]); + }); + + it("iterates over values", () => { + let header = new Cookie("name1=value1; name2=value2"); + let values = Array.from(header.values()); + assert.deepEqual(values, ["value1", "value2"]); + }); + + it("uses forEach correctly", () => { + let header = new Cookie("name1=value1; name2=value2"); + let result: [string, string][] = []; + header.forEach((value, name) => { + result.push([name, value]); + }); + assert.deepEqual(result, [ + ["name1", "value1"], + ["name2", "value2"] + ]); + }); + + it("returns correct size", () => { + let header = new Cookie("name1=value1; name2=value2"); + assert.equal(header.size, 2); + }); + + it("converts to string correctly", () => { + let header = new Cookie("name1=value1; name2=value2"); + assert.equal(header.toString(), "name1=value1; name2=value2"); + }); + + it("is directly iterable", () => { + let header = new Cookie("name1=value1; name2=value2"); + let entries = Array.from(header); + assert.deepEqual(entries, [ + ["name1", "value1"], + ["name2", "value2"] + ]); + }); + + it("handles cookies without values", () => { + let header = new Cookie("name1=value1; name2"); + assert.equal(header.get("name1"), "value1"); + assert.equal(header.get("name2"), ""); + }); + + it("handles setting empty values", () => { + let header = new Cookie(""); + header.set("name", ""); + assert.equal(header.get("name"), ""); + assert.equal(header.toString(), "name="); + }); + + it("overwrites existing values", () => { + let header = new Cookie("name=value1"); + header.set("name", "value2"); + assert.equal(header.get("name"), "value2"); + }); +}); diff --git a/src/lib/cookie.ts b/src/lib/cookie.ts new file mode 100644 index 00000000000..e44c8eea2d4 --- /dev/null +++ b/src/lib/cookie.ts @@ -0,0 +1,85 @@ +import { HeaderValue } from "./header-value.js"; + +/** + * Represents the value of a `Cookie` HTTP header. + */ +export class Cookie implements Iterable<[string, string]>, HeaderValue { + private cookies: Map; + + constructor(initialValue: string) { + this.cookies = new Map(); + let pairs = initialValue.split(";").map(pair => pair.trim()); + for (let pair of pairs) { + let [name, value] = splitNameValue(pair); + if (name) { + this.cookies.set(name, value); + } + } + } + + get(name: string): string | undefined { + return this.cookies.get(name); + } + + set(name: string, value: string): void { + this.cookies.set(name, value); + } + + delete(name: string): boolean { + return this.cookies.delete(name); + } + + has(name: string): boolean { + return this.cookies.has(name); + } + + clear(): void { + this.cookies.clear(); + } + + [Symbol.iterator](): IterableIterator<[string, string]> { + return this.cookies.entries(); + } + + entries(): IterableIterator<[string, string]> { + return this.cookies.entries(); + } + + names(): IterableIterator { + return this.cookies.keys(); + } + + values(): IterableIterator { + return this.cookies.values(); + } + + forEach( + callbackfn: (value: string, key: string, map: Map) => void, + thisArg?: any + ): void { + this.cookies.forEach(callbackfn, thisArg); + } + + get size(): number { + return this.cookies.size; + } + + toString(): string { + let pairs: string[] = []; + for (let [name, value] of this.cookies) { + pairs.push(`${name}=${value}`); + } + return pairs.join("; "); + } +} + +function splitNameValue(pair: string): [string, string] { + let equalsIndex = pair.indexOf("="); + if (equalsIndex === -1) { + return [pair, ""]; + } + return [ + pair.substring(0, equalsIndex).trim(), + pair.substring(equalsIndex + 1).trim() + ]; +} diff --git a/src/lib/header-names.spec.ts b/src/lib/header-names.spec.ts new file mode 100644 index 00000000000..0f54d203a5b --- /dev/null +++ b/src/lib/header-names.spec.ts @@ -0,0 +1,94 @@ +import * as assert from "node:assert/strict"; +import { describe, it } from "node:test"; + +import { normalizeHeaderName } from "./header-names.js"; + +describe("normalizeHeaderName", () => { + it("handles common headers correctly", () => { + assert.equal(normalizeHeaderName("content-type"), "Content-Type"); + assert.equal(normalizeHeaderName("content-length"), "Content-Length"); + assert.equal(normalizeHeaderName("user-agent"), "User-Agent"); + assert.equal(normalizeHeaderName("accept"), "Accept"); + }); + + it("handles special case headers correctly", () => { + assert.equal(normalizeHeaderName("etag"), "ETag"); + assert.equal(normalizeHeaderName("www-authenticate"), "WWW-Authenticate"); + assert.equal(normalizeHeaderName("x-forwarded-for"), "X-Forwarded-For"); + assert.equal(normalizeHeaderName("x-xss-protection"), "X-XSS-Protection"); + assert.equal(normalizeHeaderName("te"), "TE"); + assert.equal(normalizeHeaderName("expect-ct"), "Expect-CT"); + }); + + it("normalizes mixed-case input", () => { + assert.equal(normalizeHeaderName("CoNtEnT-TyPe"), "Content-Type"); + assert.equal(normalizeHeaderName("x-FoRwArDeD-fOr"), "X-Forwarded-For"); + }); + + it("handles single-word headers", () => { + assert.equal(normalizeHeaderName("authorization"), "Authorization"); + assert.equal(normalizeHeaderName("host"), "Host"); + }); + + it("normalizes other common HTTP headers", () => { + assert.equal(normalizeHeaderName("accept-charset"), "Accept-Charset"); + assert.equal(normalizeHeaderName("accept-encoding"), "Accept-Encoding"); + assert.equal(normalizeHeaderName("accept-language"), "Accept-Language"); + assert.equal(normalizeHeaderName("cache-control"), "Cache-Control"); + assert.equal(normalizeHeaderName("connection"), "Connection"); + assert.equal(normalizeHeaderName("cookie"), "Cookie"); + assert.equal(normalizeHeaderName("date"), "Date"); + assert.equal(normalizeHeaderName("expect"), "Expect"); + assert.equal(normalizeHeaderName("forwarded"), "Forwarded"); + assert.equal(normalizeHeaderName("from"), "From"); + assert.equal(normalizeHeaderName("if-match"), "If-Match"); + assert.equal(normalizeHeaderName("if-modified-since"), "If-Modified-Since"); + assert.equal(normalizeHeaderName("if-none-match"), "If-None-Match"); + assert.equal(normalizeHeaderName("if-range"), "If-Range"); + assert.equal( + normalizeHeaderName("if-unmodified-since"), + "If-Unmodified-Since" + ); + assert.equal(normalizeHeaderName("max-forwards"), "Max-Forwards"); + assert.equal(normalizeHeaderName("origin"), "Origin"); + assert.equal(normalizeHeaderName("pragma"), "Pragma"); + assert.equal( + normalizeHeaderName("proxy-authorization"), + "Proxy-Authorization" + ); + assert.equal(normalizeHeaderName("range"), "Range"); + assert.equal(normalizeHeaderName("referer"), "Referer"); + assert.equal(normalizeHeaderName("server"), "Server"); + assert.equal(normalizeHeaderName("transfer-encoding"), "Transfer-Encoding"); + assert.equal(normalizeHeaderName("upgrade"), "Upgrade"); + assert.equal(normalizeHeaderName("via"), "Via"); + assert.equal(normalizeHeaderName("warning"), "Warning"); + assert.equal(normalizeHeaderName("alt-svc"), "Alt-Svc"); + assert.equal( + normalizeHeaderName("content-disposition"), + "Content-Disposition" + ); + assert.equal(normalizeHeaderName("content-encoding"), "Content-Encoding"); + assert.equal(normalizeHeaderName("content-language"), "Content-Language"); + assert.equal(normalizeHeaderName("content-location"), "Content-Location"); + assert.equal(normalizeHeaderName("content-range"), "Content-Range"); + assert.equal(normalizeHeaderName("link"), "Link"); + assert.equal(normalizeHeaderName("location"), "Location"); + assert.equal(normalizeHeaderName("retry-after"), "Retry-After"); + assert.equal( + normalizeHeaderName("strict-transport-security"), + "Strict-Transport-Security" + ); + assert.equal(normalizeHeaderName("vary"), "Vary"); + }); + + it("handles custom X- headers", () => { + assert.equal(normalizeHeaderName("x-custom-header"), "X-Custom-Header"); + assert.equal(normalizeHeaderName("x-requested-with"), "X-Requested-With"); + }); + + it("preserves casing for unknown acronyms", () => { + assert.equal(normalizeHeaderName("x-csrf-token"), "X-Csrf-Token"); + assert.equal(normalizeHeaderName("x-api-key"), "X-Api-Key"); + }); +}); diff --git a/src/lib/header-names.ts b/src/lib/header-names.ts new file mode 100644 index 00000000000..8a864358fcf --- /dev/null +++ b/src/lib/header-names.ts @@ -0,0 +1,20 @@ +const HeaderWordCasingExceptions: Record = { + ct: "CT", + etag: "ETag", + te: "TE", + www: "WWW", + x: "X", + xss: "XSS" +}; + +export function normalizeHeaderName(name: string): string { + return name + .toLowerCase() + .split("-") + .map( + word => + HeaderWordCasingExceptions[word] || + word.charAt(0).toUpperCase() + word.slice(1) + ) + .join("-"); +} diff --git a/src/lib/header-value.ts b/src/lib/header-value.ts new file mode 100644 index 00000000000..832661b9368 --- /dev/null +++ b/src/lib/header-value.ts @@ -0,0 +1,3 @@ +export interface HeaderValue { + toString(): string; +} diff --git a/src/lib/param-values.ts b/src/lib/param-values.ts new file mode 100644 index 00000000000..fd488559b49 --- /dev/null +++ b/src/lib/param-values.ts @@ -0,0 +1,13 @@ +export function quote(value: string): string { + if (value.includes('"') || value.includes(";") || value.includes(" ")) { + return `"${value.replace(/"/g, '\\"')}"`; + } + return value; +} + +export function unquote(value: string): string { + if (value.startsWith('"') && value.endsWith('"')) { + return value.slice(1, -1).replace(/\\"/g, '"'); + } + return value; +} diff --git a/src/lib/super-headers.spec.ts b/src/lib/super-headers.spec.ts new file mode 100644 index 00000000000..263929851af --- /dev/null +++ b/src/lib/super-headers.spec.ts @@ -0,0 +1,184 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { ContentDisposition } from './content-disposition.js'; +import { ContentType } from './content-type.js'; +import { Cookie } from './cookie.js'; +import { SuperHeaders } from './super-headers.js'; + +describe('SuperHeaders', () => { + it('initializes with no arguments', () => { + let headers = new SuperHeaders(); + assert.equal(headers.get('content-type'), null); + }); + + it('initializes from an object', () => { + let headers = new SuperHeaders({ 'Content-Type': 'text/plain' }); + assert.equal(headers.get('content-type'), 'text/plain'); + }); + + it('initializes from an array of key-value pairs', () => { + let headers = new SuperHeaders([ + ['Content-Type', 'text/plain'], + ['X-Custom', 'value'], + ]); + assert.equal(headers.get('content-type'), 'text/plain'); + assert.equal(headers.get('x-custom'), 'value'); + }); + + it('initializes from another Headers instance', () => { + let original = new SuperHeaders({ 'Content-Type': 'text/plain' }); + let headers = new SuperHeaders(original); + assert.equal(headers.get('content-type'), 'text/plain'); + }); + + it('appends values', () => { + let headers = new SuperHeaders(); + headers.append('X-Custom', 'value1'); + headers.append('X-Custom', 'value2'); + assert.equal(headers.get('x-custom'), 'value1, value2'); + }); + + it('sets values', () => { + let headers = new SuperHeaders(); + headers.set('X-Custom', 'value1'); + headers.set('X-Custom', 'value2'); + assert.equal(headers.get('x-custom'), 'value2'); + }); + + it('deletes values', () => { + let headers = new SuperHeaders({ 'X-Custom': 'value' }); + headers.delete('X-Custom'); + assert.equal(headers.has('x-custom'), false); + }); + + it('checks if a header exists', () => { + let headers = new SuperHeaders({ 'X-Custom': 'value' }); + assert.equal(headers.has('x-custom'), true); + assert.equal(headers.has('nonexistent'), false); + }); + + it('iterates over entries', () => { + let headers = new SuperHeaders({ + 'X-Custom1': 'value1', + 'X-Custom2': 'value2', + }); + let entries = Array.from(headers.entries()); + assert.deepEqual(entries, [ + ['x-custom1', 'value1'], + ['x-custom2', 'value2'], + ]); + }); + + it('iterates over names', () => { + let headers = new SuperHeaders({ + 'X-Custom1': 'value1', + 'X-Custom2': 'value2', + }); + let keys = Array.from(headers.names()); + assert.deepEqual(keys, ['x-custom1', 'x-custom2']); + }); + + it('iterates over values', () => { + let headers = new SuperHeaders({ + 'X-Custom1': 'value1', + 'X-Custom2': 'value2', + }); + let values = Array.from(headers.values()); + assert.deepEqual(values, ['value1', 'value2']); + }); + + it('uses forEach correctly', () => { + let headers = new SuperHeaders({ + 'X-Custom1': 'value1', + 'X-Custom2': 'value2', + }); + let result: [string, string][] = []; + headers.forEach((value, key) => { + result.push([key, value]); + }); + assert.deepEqual(result, [ + ['x-custom1', 'value1'], + ['x-custom2', 'value2'], + ]); + }); + + it('is directly iterable', () => { + let headers = new SuperHeaders({ + 'X-Custom1': 'value1', + 'X-Custom2': 'value2', + }); + let entries = Array.from(headers); + assert.deepEqual(entries, [ + ['x-custom1', 'value1'], + ['x-custom2', 'value2'], + ]); + }); + + describe('header-specific getters and setters', () => { + it('handles Content-Disposition header', () => { + let headers = new SuperHeaders(); + headers.contentDisposition = 'attachment; filename="example.txt"'; + + assert.ok(headers.contentDisposition instanceof ContentDisposition); + assert.equal(headers.contentDisposition.type, 'attachment'); + assert.equal(headers.contentDisposition.filename, 'example.txt'); + + headers.contentDisposition.filename = 'new.txt'; + assert.equal(headers.get('Content-Disposition'), 'attachment; filename=new.txt'); + }); + + it('handles Content-Type header', () => { + let headers = new SuperHeaders(); + headers.contentType = 'text/plain; charset=utf-8'; + + assert.ok(headers.contentType instanceof ContentType); + assert.equal(headers.contentType.mediaType, 'text/plain'); + assert.equal(headers.contentType.charset, 'utf-8'); + + headers.contentType.charset = 'iso-8859-1'; + assert.equal(headers.get('Content-Type'), 'text/plain; charset=iso-8859-1'); + }); + + it('handles Cookie header', () => { + let headers = new SuperHeaders(); + headers.cookie = 'name1=value1; name2=value2'; + + assert.ok(headers.cookie instanceof Cookie); + assert.equal(headers.cookie.get('name1'), 'value1'); + assert.equal(headers.cookie.get('name2'), 'value2'); + + headers.cookie.set('name3', 'value3'); + assert.equal(headers.get('Cookie'), 'name1=value1; name2=value2; name3=value3'); + }); + + it('creates empty header objects when accessed', () => { + let headers = new SuperHeaders(); + + assert.ok(headers.contentDisposition instanceof ContentDisposition); + assert.equal(headers.contentDisposition.toString(), ''); + + assert.ok(headers.contentType instanceof ContentType); + assert.equal(headers.contentType.toString(), ''); + + assert.ok(headers.cookie instanceof Cookie); + assert.equal(headers.cookie.toString(), ''); + }); + }); + + describe('toString', () => { + it('omits empty values when stringified', () => { + let headers = new SuperHeaders(); + headers.set('X-Test', 'value'); + headers.contentDisposition = ''; + headers.contentType = ''; + headers.cookie = ''; + + let result = headers.toString(); + assert.equal(result, 'X-Test: value'); + assert.ok(!result.includes('Content-Disposition')); + assert.ok(!result.includes('Content-Type')); + assert.ok(!result.includes('Cookie')); + }); + }); +}); diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts new file mode 100644 index 00000000000..eaa6be3b667 --- /dev/null +++ b/src/lib/super-headers.ts @@ -0,0 +1,150 @@ +import { ContentDisposition } from './content-disposition.js'; +import { ContentType } from './content-type.js'; +import { Cookie } from './cookie.js'; +import { normalizeHeaderName } from './header-names.js'; +import { HeaderValue } from './header-value.js'; + +export type SuperHeadersInit = + | SuperHeaders + | Headers + | [string, string | HeaderValue][] + | Record; + +/** + * HTTP Headers object, with superpowers. + */ +export class SuperHeaders implements Iterable<[string, string]> { + private map: Map; + + constructor(init?: SuperHeadersInit) { + this.map = new Map(); + if (init) { + if (init instanceof SuperHeaders || Array.isArray(init)) { + for (let [name, value] of init) { + this.append(name, value); + } + } else if (init instanceof Headers) { + init.forEach((value, name) => { + this.append(name, value); + }); + } else if (typeof init === 'object') { + for (let name in init) { + if (Object.prototype.hasOwnProperty.call(init, name)) { + this.append(name, init[name]); + } + } + } + } + } + + append(name: string, value: string | HeaderValue): void { + let lowerName = name.toLowerCase(); + let existingValue = this.map.get(lowerName); + this.map.set(lowerName, existingValue ? `${existingValue}, ${value}` : value); + } + + delete(name: string): void { + this.map.delete(name.toLowerCase()); + } + + get(name: string): string | null { + let value = this.map.get(name.toLowerCase()); + return value === undefined ? null : value.toString(); + } + + has(name: string): boolean { + return this.map.has(name.toLowerCase()); + } + + set(name: string, value: string | HeaderValue): void { + this.map.set(name.toLowerCase(), value); + } + + *entries(): IterableIterator<[string, string]> { + for (let [name, value] of this.map) { + let stringValue = value.toString(); + if (stringValue !== '') { + yield [name, stringValue]; + } + } + } + + *names(): IterableIterator { + for (let [name] of this) { + yield name; + } + } + + *values(): IterableIterator { + for (let [, value] of this) { + yield value; + } + } + + [Symbol.iterator](): IterableIterator<[string, string]> { + return this.entries(); + } + + forEach( + callback: (value: string, name: string, parent: SuperHeaders) => void, + thisArg?: any + ): void { + for (let [name, value] of this) { + callback.call(thisArg, value, name, this); + } + } + + toString(): string { + let lines: string[] = []; + for (let [name, value] of this) { + lines.push(`${normalizeHeaderName(name)}: ${value}`); + } + return lines.join('\r\n'); + } + + // Header-specific getters and setters + + get contentDisposition(): ContentDisposition { + return this.getHeaderValue('content-disposition', ContentDisposition) as ContentDisposition; + } + + set contentDisposition(value: string | ContentDisposition) { + this.map.set('content-disposition', value); + } + + get contentType(): ContentType { + return this.getHeaderValue('content-type', ContentType) as ContentType; + } + + set contentType(value: string | ContentType) { + this.map.set('content-type', value); + } + + get cookie(): Cookie { + return this.getHeaderValue('cookie', Cookie) as Cookie; + } + + set cookie(value: string | Cookie) { + this.map.set('cookie', value); + } + + private getHeaderValue( + key: string, + constructor: new (initialValue: string) => HeaderValue + ): HeaderValue { + let value = this.map.get(key); + if (value) { + if (typeof value === 'string') { + let headerValue = new constructor(value); + this.map.set(key, headerValue); + return headerValue; + } else { + return value; + } + } else { + let headerValue = new constructor(''); + this.map.set(key, headerValue); + return headerValue; + } + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000000..ba16aeed449 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "lib": ["DOM", "ES2020"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true + }, + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/tsconfig.lib.json b/tsconfig.lib.json new file mode 100644 index 00000000000..8e712f7d6c8 --- /dev/null +++ b/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.spec.ts"], + "compilerOptions": { + "composite": true, + "rootDir": "src" + } +} diff --git a/tsconfig.spec.json b/tsconfig.spec.json new file mode 100644 index 00000000000..79d1e4a027a --- /dev/null +++ b/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": { + "composite": true, + "types": ["node"] + } +} From 2ea6d856742f9ee3d35d6b92dbe4fcfc693545b1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 11 Jul 2024 23:40:01 -0700 Subject: [PATCH 007/730] Tweak description --- README.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c9000d1e83f..d626ad379b2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # fetch-super-headers -This package is a suite of tools that make it a little more fun to work with fetch `Headers`. +This package is a suite of tools that make it a little more fun to work with `Headers`. ## Key Features diff --git a/package.json b/package.json index 2495d65bf98..8b372c5d622 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "fetch-super-headers", "version": "0.1.0", - "description": "A suite of tools that make it a little more fun to work with fetch Headers", + "description": "A suite of tools that make it a little more fun to work with Headers", "main": "dist/index.js", "scripts": { "build": "pnpm run build:cjs && pnpm run build:esm", From 05e2b70ade0f6a537ab9c68eb4eb37179d3811e4 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 11 Jul 2024 23:44:29 -0700 Subject: [PATCH 008/730] Add package exports and files array --- package.json | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 8b372c5d622..75420492bfc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fetch-super-headers", - "version": "0.1.0", + "version": "0.2.0", "description": "A suite of tools that make it a little more fun to work with Headers", "main": "dist/index.js", "scripts": { @@ -9,6 +9,15 @@ "build:esm": "esbuild src/index.ts --bundle --format=esm --target=node16 --outfile=dist/index.mjs", "test": "node --import tsimp/import --test ./src/**/*.spec.ts" }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js", + "default": "./dist/index.js" + }, + "./package.json": "./package.json" + }, "author": "Michael Jackson ", "license": "MIT", "devDependencies": { @@ -16,5 +25,9 @@ "esbuild": "^0.23.0", "tsimp": "^2.0.11", "typescript": "^5.5.3" - } + }, + "files": [ + "dist", + "README.md" + ] } From b90459e6143fc65849a903ca674660ea48102184 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 11 Jul 2024 23:45:59 -0700 Subject: [PATCH 009/730] Re-arrange package.json --- package.json | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 75420492bfc..6f6bb9c4181 100644 --- a/package.json +++ b/package.json @@ -2,13 +2,12 @@ "name": "fetch-super-headers", "version": "0.2.0", "description": "A suite of tools that make it a little more fun to work with Headers", - "main": "dist/index.js", - "scripts": { - "build": "pnpm run build:cjs && pnpm run build:esm", - "build:cjs": "tsc --outDir dist --project tsconfig.lib.json", - "build:esm": "esbuild src/index.ts --bundle --format=esm --target=node16 --outfile=dist/index.mjs", - "test": "node --import tsimp/import --test ./src/**/*.spec.ts" - }, + "author": "Michael Jackson ", + "license": "MIT", + "files": [ + "dist", + "README.md" + ], "exports": { ".": { "types": "./dist/index.d.ts", @@ -18,16 +17,16 @@ }, "./package.json": "./package.json" }, - "author": "Michael Jackson ", - "license": "MIT", + "scripts": { + "build": "pnpm run build:cjs && pnpm run build:esm", + "build:cjs": "tsc --outDir dist --project tsconfig.lib.json", + "build:esm": "esbuild src/index.ts --bundle --format=esm --target=node16 --outfile=dist/index.mjs", + "test": "node --import tsimp/import --test ./src/**/*.spec.ts" + }, "devDependencies": { "@types/node": "^20.14.10", "esbuild": "^0.23.0", "tsimp": "^2.0.11", "typescript": "^5.5.3" - }, - "files": [ - "dist", - "README.md" - ] + } } From 18fd1a63de2fe36bdeabd608f3f6615831199222 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 11 Jul 2024 23:58:14 -0700 Subject: [PATCH 010/730] Tweak README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d626ad379b2..2c8a3ec2703 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ headers feel a lot more like working with JavaScript objects. ```ts import Headers from 'fetch-super-headers'; +// or, if you don't want to clobber the global `Headers` reference: +// import SuperHeaders from 'fetch-super-headers'; let headers = new Headers(); From b1def03e3e13d105b00d8ff736005634e6d0e9f8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 12 Jul 2024 08:15:55 -0700 Subject: [PATCH 011/730] Use canonical header names in iteration --- src/lib/content-disposition.spec.ts | 12 +++++- src/lib/super-headers.spec.ts | 60 ++++++++++++++++------------- src/lib/super-headers.ts | 32 +++++++++------ 3 files changed, 65 insertions(+), 39 deletions(-) diff --git a/src/lib/content-disposition.spec.ts b/src/lib/content-disposition.spec.ts index c3de4e5e97a..42ca8cd8d5b 100644 --- a/src/lib/content-disposition.spec.ts +++ b/src/lib/content-disposition.spec.ts @@ -204,9 +204,19 @@ describe('ContentDisposition', () => { assert.equal(header.preferredFilename, '文件.txt'); }); - it('falls back gracefully for unknown charsets', () => { + it('falls back gracefully with a warning for unknown charsets', () => { + let warn = console.warn; + let warnWasCalled = false; + console.warn = () => { + warnWasCalled = true; + }; + let header = new ContentDisposition("attachment; filename*=unknown-charset''file%FF.txt"); + assert.equal(header.preferredFilename, 'fileÿ.txt'); + assert.ok(warnWasCalled, 'console.warn should have been called'); + + console.warn = warn; }); }); }); diff --git a/src/lib/super-headers.spec.ts b/src/lib/super-headers.spec.ts index 263929851af..ef9fce70480 100644 --- a/src/lib/super-headers.spec.ts +++ b/src/lib/super-headers.spec.ts @@ -12,9 +12,15 @@ describe('SuperHeaders', () => { assert.equal(headers.get('content-type'), null); }); + it('initializes from a string', () => { + let headers = new SuperHeaders('Content-Type: text/plain\r\nContent-Length: 42'); + assert.equal(headers.get('Content-Type'), 'text/plain'); + assert.equal(headers.get('Content-Length'), '42'); + }); + it('initializes from an object', () => { let headers = new SuperHeaders({ 'Content-Type': 'text/plain' }); - assert.equal(headers.get('content-type'), 'text/plain'); + assert.equal(headers.get('Content-Type'), 'text/plain'); }); it('initializes from an array of key-value pairs', () => { @@ -22,96 +28,96 @@ describe('SuperHeaders', () => { ['Content-Type', 'text/plain'], ['X-Custom', 'value'], ]); - assert.equal(headers.get('content-type'), 'text/plain'); - assert.equal(headers.get('x-custom'), 'value'); + assert.equal(headers.get('Content-Type'), 'text/plain'); + assert.equal(headers.get('X-Custom'), 'value'); }); it('initializes from another Headers instance', () => { let original = new SuperHeaders({ 'Content-Type': 'text/plain' }); let headers = new SuperHeaders(original); - assert.equal(headers.get('content-type'), 'text/plain'); + assert.equal(headers.get('Content-Type'), 'text/plain'); }); it('appends values', () => { let headers = new SuperHeaders(); headers.append('X-Custom', 'value1'); headers.append('X-Custom', 'value2'); - assert.equal(headers.get('x-custom'), 'value1, value2'); + assert.equal(headers.get('X-Custom'), 'value1, value2'); }); it('sets values', () => { let headers = new SuperHeaders(); headers.set('X-Custom', 'value1'); headers.set('X-Custom', 'value2'); - assert.equal(headers.get('x-custom'), 'value2'); + assert.equal(headers.get('X-Custom'), 'value2'); }); it('deletes values', () => { let headers = new SuperHeaders({ 'X-Custom': 'value' }); headers.delete('X-Custom'); - assert.equal(headers.has('x-custom'), false); + assert.equal(headers.has('X-Custom'), false); }); it('checks if a header exists', () => { let headers = new SuperHeaders({ 'X-Custom': 'value' }); - assert.equal(headers.has('x-custom'), true); - assert.equal(headers.has('nonexistent'), false); + assert.equal(headers.has('X-Custom'), true); + assert.equal(headers.has('Nonexistent'), false); }); it('iterates over entries', () => { let headers = new SuperHeaders({ - 'X-Custom1': 'value1', - 'X-Custom2': 'value2', + 'Content-Type': 'text/plain', + 'Content-Length': '42', }); let entries = Array.from(headers.entries()); assert.deepEqual(entries, [ - ['x-custom1', 'value1'], - ['x-custom2', 'value2'], + ['Content-Type', 'text/plain'], + ['Content-Length', '42'], ]); }); it('iterates over names', () => { let headers = new SuperHeaders({ - 'X-Custom1': 'value1', - 'X-Custom2': 'value2', + 'Content-Type': 'text/plain', + 'Content-Length': '42', }); let keys = Array.from(headers.names()); - assert.deepEqual(keys, ['x-custom1', 'x-custom2']); + assert.deepEqual(keys, ['Content-Type', 'Content-Length']); }); it('iterates over values', () => { let headers = new SuperHeaders({ - 'X-Custom1': 'value1', - 'X-Custom2': 'value2', + 'Content-Type': 'text/plain', + 'Content-Length': '42', }); let values = Array.from(headers.values()); - assert.deepEqual(values, ['value1', 'value2']); + assert.deepEqual(values, ['text/plain', '42']); }); it('uses forEach correctly', () => { let headers = new SuperHeaders({ - 'X-Custom1': 'value1', - 'X-Custom2': 'value2', + 'Content-Type': 'text/plain', + 'Content-Length': '42', }); let result: [string, string][] = []; headers.forEach((value, key) => { result.push([key, value]); }); assert.deepEqual(result, [ - ['x-custom1', 'value1'], - ['x-custom2', 'value2'], + ['Content-Type', 'text/plain'], + ['Content-Length', '42'], ]); }); it('is directly iterable', () => { let headers = new SuperHeaders({ - 'X-Custom1': 'value1', - 'X-Custom2': 'value2', + 'Content-Type': 'text/plain', + 'Content-Length': '42', }); let entries = Array.from(headers); assert.deepEqual(entries, [ - ['x-custom1', 'value1'], - ['x-custom2', 'value2'], + ['Content-Type', 'text/plain'], + ['Content-Length', '42'], ]); }); diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index eaa6be3b667..7f1ec08b71c 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -4,6 +4,8 @@ import { Cookie } from './cookie.js'; import { normalizeHeaderName } from './header-names.js'; import { HeaderValue } from './header-value.js'; +const CRLF = '\r\n'; + export type SuperHeadersInit = | SuperHeaders | Headers @@ -16,10 +18,18 @@ export type SuperHeadersInit = export class SuperHeaders implements Iterable<[string, string]> { private map: Map; - constructor(init?: SuperHeadersInit) { + constructor(init?: string | SuperHeadersInit) { this.map = new Map(); if (init) { - if (init instanceof SuperHeaders || Array.isArray(init)) { + if (typeof init === 'string') { + let lines = init.split(CRLF); + for (let line of lines) { + let match = line.match(/^([^:]+):(.*)/); + if (match) { + this.append(match[1].trim(), match[2].trim()); + } + } + } else if (init instanceof SuperHeaders || Array.isArray(init)) { for (let [name, value] of init) { this.append(name, value); } @@ -38,9 +48,9 @@ export class SuperHeaders implements Iterable<[string, string]> { } append(name: string, value: string | HeaderValue): void { - let lowerName = name.toLowerCase(); - let existingValue = this.map.get(lowerName); - this.map.set(lowerName, existingValue ? `${existingValue}, ${value}` : value); + let key = name.toLowerCase(); + let existingValue = this.map.get(key); + this.map.set(key, existingValue ? `${existingValue}, ${value}` : value); } delete(name: string): void { @@ -64,7 +74,7 @@ export class SuperHeaders implements Iterable<[string, string]> { for (let [name, value] of this.map) { let stringValue = value.toString(); if (stringValue !== '') { - yield [name, stringValue]; + yield [normalizeHeaderName(name), stringValue]; } } } @@ -97,9 +107,9 @@ export class SuperHeaders implements Iterable<[string, string]> { toString(): string { let lines: string[] = []; for (let [name, value] of this) { - lines.push(`${normalizeHeaderName(name)}: ${value}`); + lines.push(`${name}: ${value}`); } - return lines.join('\r\n'); + return lines.join(CRLF); } // Header-specific getters and setters @@ -130,19 +140,19 @@ export class SuperHeaders implements Iterable<[string, string]> { private getHeaderValue( key: string, - constructor: new (initialValue: string) => HeaderValue + ctor: new (initialValue: string) => HeaderValue ): HeaderValue { let value = this.map.get(key); if (value) { if (typeof value === 'string') { - let headerValue = new constructor(value); + let headerValue = new ctor(value); this.map.set(key, headerValue); return headerValue; } else { return value; } } else { - let headerValue = new constructor(''); + let headerValue = new ctor(''); this.map.set(key, headerValue); return headerValue; } From 70bb31432a0bdedf2a38dc83af953a6adcb031e9 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 12 Jul 2024 09:39:59 -0700 Subject: [PATCH 012/730] Add contentLength getter/setter --- src/lib/super-headers.spec.ts | 8 ++++++++ src/lib/super-headers.ts | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/src/lib/super-headers.spec.ts b/src/lib/super-headers.spec.ts index ef9fce70480..54f4d8f1b6d 100644 --- a/src/lib/super-headers.spec.ts +++ b/src/lib/super-headers.spec.ts @@ -134,6 +134,14 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Content-Disposition'), 'attachment; filename=new.txt'); }); + it('handles Content-Length header', () => { + let headers = new SuperHeaders(); + headers.contentLength = 42; + + assert.equal(headers.contentLength, 42); + assert.equal(headers.get('Content-Length'), '42'); + }); + it('handles Content-Type header', () => { let headers = new SuperHeaders(); headers.contentType = 'text/plain; charset=utf-8'; diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index 7f1ec08b71c..6731566f651 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -122,6 +122,15 @@ export class SuperHeaders implements Iterable<[string, string]> { this.map.set('content-disposition', value); } + get contentLength(): number { + let value = this.map.get('content-length'); + return value ? parseInt(value.toString(), 10) : NaN; + } + + set contentLength(value: number) { + this.map.set('content-length', value.toString()); + } + get contentType(): ContentType { return this.getHeaderValue('content-type', ContentType) as ContentType; } From 9d0e5a58801e518f25c8779b08f9711c0c099635 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 12 Jul 2024 12:10:29 -0700 Subject: [PATCH 013/730] Small formatting tweaks --- src/lib/cookie.ts | 17 ++--- src/lib/header-names.spec.ts | 144 ++++++++++++++++------------------- src/lib/header-names.ts | 24 +++--- src/lib/super-headers.ts | 7 +- 4 files changed, 87 insertions(+), 105 deletions(-) diff --git a/src/lib/cookie.ts b/src/lib/cookie.ts index e44c8eea2d4..9145c838052 100644 --- a/src/lib/cookie.ts +++ b/src/lib/cookie.ts @@ -1,14 +1,14 @@ -import { HeaderValue } from "./header-value.js"; +import { HeaderValue } from './header-value.js'; /** * Represents the value of a `Cookie` HTTP header. */ -export class Cookie implements Iterable<[string, string]>, HeaderValue { +export class Cookie implements HeaderValue, Iterable<[string, string]> { private cookies: Map; constructor(initialValue: string) { this.cookies = new Map(); - let pairs = initialValue.split(";").map(pair => pair.trim()); + let pairs = initialValue.split(';').map((pair) => pair.trim()); for (let pair of pairs) { let [name, value] = splitNameValue(pair); if (name) { @@ -69,17 +69,14 @@ export class Cookie implements Iterable<[string, string]>, HeaderValue { for (let [name, value] of this.cookies) { pairs.push(`${name}=${value}`); } - return pairs.join("; "); + return pairs.join('; '); } } function splitNameValue(pair: string): [string, string] { - let equalsIndex = pair.indexOf("="); + let equalsIndex = pair.indexOf('='); if (equalsIndex === -1) { - return [pair, ""]; + return [pair, '']; } - return [ - pair.substring(0, equalsIndex).trim(), - pair.substring(equalsIndex + 1).trim() - ]; + return [pair.substring(0, equalsIndex).trim(), pair.substring(equalsIndex + 1).trim()]; } diff --git a/src/lib/header-names.spec.ts b/src/lib/header-names.spec.ts index 0f54d203a5b..403ee6f98fa 100644 --- a/src/lib/header-names.spec.ts +++ b/src/lib/header-names.spec.ts @@ -1,94 +1,82 @@ -import * as assert from "node:assert/strict"; -import { describe, it } from "node:test"; +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; -import { normalizeHeaderName } from "./header-names.js"; +import { canonicalHeaderName } from './header-names.js'; -describe("normalizeHeaderName", () => { - it("handles common headers correctly", () => { - assert.equal(normalizeHeaderName("content-type"), "Content-Type"); - assert.equal(normalizeHeaderName("content-length"), "Content-Length"); - assert.equal(normalizeHeaderName("user-agent"), "User-Agent"); - assert.equal(normalizeHeaderName("accept"), "Accept"); +describe('normalizeHeaderName', () => { + it('handles common headers correctly', () => { + assert.equal(canonicalHeaderName('content-type'), 'Content-Type'); + assert.equal(canonicalHeaderName('content-length'), 'Content-Length'); + assert.equal(canonicalHeaderName('user-agent'), 'User-Agent'); + assert.equal(canonicalHeaderName('accept'), 'Accept'); }); - it("handles special case headers correctly", () => { - assert.equal(normalizeHeaderName("etag"), "ETag"); - assert.equal(normalizeHeaderName("www-authenticate"), "WWW-Authenticate"); - assert.equal(normalizeHeaderName("x-forwarded-for"), "X-Forwarded-For"); - assert.equal(normalizeHeaderName("x-xss-protection"), "X-XSS-Protection"); - assert.equal(normalizeHeaderName("te"), "TE"); - assert.equal(normalizeHeaderName("expect-ct"), "Expect-CT"); + it('handles special case headers correctly', () => { + assert.equal(canonicalHeaderName('etag'), 'ETag'); + assert.equal(canonicalHeaderName('www-authenticate'), 'WWW-Authenticate'); + assert.equal(canonicalHeaderName('x-forwarded-for'), 'X-Forwarded-For'); + assert.equal(canonicalHeaderName('x-xss-protection'), 'X-XSS-Protection'); + assert.equal(canonicalHeaderName('te'), 'TE'); + assert.equal(canonicalHeaderName('expect-ct'), 'Expect-CT'); }); - it("normalizes mixed-case input", () => { - assert.equal(normalizeHeaderName("CoNtEnT-TyPe"), "Content-Type"); - assert.equal(normalizeHeaderName("x-FoRwArDeD-fOr"), "X-Forwarded-For"); + it('normalizes mixed-case input', () => { + assert.equal(canonicalHeaderName('CoNtEnT-TyPe'), 'Content-Type'); + assert.equal(canonicalHeaderName('x-FoRwArDeD-fOr'), 'X-Forwarded-For'); }); - it("handles single-word headers", () => { - assert.equal(normalizeHeaderName("authorization"), "Authorization"); - assert.equal(normalizeHeaderName("host"), "Host"); + it('handles single-word headers', () => { + assert.equal(canonicalHeaderName('authorization'), 'Authorization'); + assert.equal(canonicalHeaderName('host'), 'Host'); }); - it("normalizes other common HTTP headers", () => { - assert.equal(normalizeHeaderName("accept-charset"), "Accept-Charset"); - assert.equal(normalizeHeaderName("accept-encoding"), "Accept-Encoding"); - assert.equal(normalizeHeaderName("accept-language"), "Accept-Language"); - assert.equal(normalizeHeaderName("cache-control"), "Cache-Control"); - assert.equal(normalizeHeaderName("connection"), "Connection"); - assert.equal(normalizeHeaderName("cookie"), "Cookie"); - assert.equal(normalizeHeaderName("date"), "Date"); - assert.equal(normalizeHeaderName("expect"), "Expect"); - assert.equal(normalizeHeaderName("forwarded"), "Forwarded"); - assert.equal(normalizeHeaderName("from"), "From"); - assert.equal(normalizeHeaderName("if-match"), "If-Match"); - assert.equal(normalizeHeaderName("if-modified-since"), "If-Modified-Since"); - assert.equal(normalizeHeaderName("if-none-match"), "If-None-Match"); - assert.equal(normalizeHeaderName("if-range"), "If-Range"); - assert.equal( - normalizeHeaderName("if-unmodified-since"), - "If-Unmodified-Since" - ); - assert.equal(normalizeHeaderName("max-forwards"), "Max-Forwards"); - assert.equal(normalizeHeaderName("origin"), "Origin"); - assert.equal(normalizeHeaderName("pragma"), "Pragma"); - assert.equal( - normalizeHeaderName("proxy-authorization"), - "Proxy-Authorization" - ); - assert.equal(normalizeHeaderName("range"), "Range"); - assert.equal(normalizeHeaderName("referer"), "Referer"); - assert.equal(normalizeHeaderName("server"), "Server"); - assert.equal(normalizeHeaderName("transfer-encoding"), "Transfer-Encoding"); - assert.equal(normalizeHeaderName("upgrade"), "Upgrade"); - assert.equal(normalizeHeaderName("via"), "Via"); - assert.equal(normalizeHeaderName("warning"), "Warning"); - assert.equal(normalizeHeaderName("alt-svc"), "Alt-Svc"); - assert.equal( - normalizeHeaderName("content-disposition"), - "Content-Disposition" - ); - assert.equal(normalizeHeaderName("content-encoding"), "Content-Encoding"); - assert.equal(normalizeHeaderName("content-language"), "Content-Language"); - assert.equal(normalizeHeaderName("content-location"), "Content-Location"); - assert.equal(normalizeHeaderName("content-range"), "Content-Range"); - assert.equal(normalizeHeaderName("link"), "Link"); - assert.equal(normalizeHeaderName("location"), "Location"); - assert.equal(normalizeHeaderName("retry-after"), "Retry-After"); - assert.equal( - normalizeHeaderName("strict-transport-security"), - "Strict-Transport-Security" - ); - assert.equal(normalizeHeaderName("vary"), "Vary"); + it('normalizes other common HTTP headers', () => { + assert.equal(canonicalHeaderName('accept-charset'), 'Accept-Charset'); + assert.equal(canonicalHeaderName('accept-encoding'), 'Accept-Encoding'); + assert.equal(canonicalHeaderName('accept-language'), 'Accept-Language'); + assert.equal(canonicalHeaderName('cache-control'), 'Cache-Control'); + assert.equal(canonicalHeaderName('connection'), 'Connection'); + assert.equal(canonicalHeaderName('cookie'), 'Cookie'); + assert.equal(canonicalHeaderName('date'), 'Date'); + assert.equal(canonicalHeaderName('expect'), 'Expect'); + assert.equal(canonicalHeaderName('forwarded'), 'Forwarded'); + assert.equal(canonicalHeaderName('from'), 'From'); + assert.equal(canonicalHeaderName('if-match'), 'If-Match'); + assert.equal(canonicalHeaderName('if-modified-since'), 'If-Modified-Since'); + assert.equal(canonicalHeaderName('if-none-match'), 'If-None-Match'); + assert.equal(canonicalHeaderName('if-range'), 'If-Range'); + assert.equal(canonicalHeaderName('if-unmodified-since'), 'If-Unmodified-Since'); + assert.equal(canonicalHeaderName('max-forwards'), 'Max-Forwards'); + assert.equal(canonicalHeaderName('origin'), 'Origin'); + assert.equal(canonicalHeaderName('pragma'), 'Pragma'); + assert.equal(canonicalHeaderName('proxy-authorization'), 'Proxy-Authorization'); + assert.equal(canonicalHeaderName('range'), 'Range'); + assert.equal(canonicalHeaderName('referer'), 'Referer'); + assert.equal(canonicalHeaderName('server'), 'Server'); + assert.equal(canonicalHeaderName('transfer-encoding'), 'Transfer-Encoding'); + assert.equal(canonicalHeaderName('upgrade'), 'Upgrade'); + assert.equal(canonicalHeaderName('via'), 'Via'); + assert.equal(canonicalHeaderName('warning'), 'Warning'); + assert.equal(canonicalHeaderName('alt-svc'), 'Alt-Svc'); + assert.equal(canonicalHeaderName('content-disposition'), 'Content-Disposition'); + assert.equal(canonicalHeaderName('content-encoding'), 'Content-Encoding'); + assert.equal(canonicalHeaderName('content-language'), 'Content-Language'); + assert.equal(canonicalHeaderName('content-location'), 'Content-Location'); + assert.equal(canonicalHeaderName('content-range'), 'Content-Range'); + assert.equal(canonicalHeaderName('link'), 'Link'); + assert.equal(canonicalHeaderName('location'), 'Location'); + assert.equal(canonicalHeaderName('retry-after'), 'Retry-After'); + assert.equal(canonicalHeaderName('strict-transport-security'), 'Strict-Transport-Security'); + assert.equal(canonicalHeaderName('vary'), 'Vary'); }); - it("handles custom X- headers", () => { - assert.equal(normalizeHeaderName("x-custom-header"), "X-Custom-Header"); - assert.equal(normalizeHeaderName("x-requested-with"), "X-Requested-With"); + it('handles custom X- headers', () => { + assert.equal(canonicalHeaderName('x-custom-header'), 'X-Custom-Header'); + assert.equal(canonicalHeaderName('x-requested-with'), 'X-Requested-With'); }); - it("preserves casing for unknown acronyms", () => { - assert.equal(normalizeHeaderName("x-csrf-token"), "X-Csrf-Token"); - assert.equal(normalizeHeaderName("x-api-key"), "X-Api-Key"); + it('preserves casing for unknown acronyms', () => { + assert.equal(canonicalHeaderName('x-csrf-token'), 'X-Csrf-Token'); + assert.equal(canonicalHeaderName('x-api-key'), 'X-Api-Key'); }); }); diff --git a/src/lib/header-names.ts b/src/lib/header-names.ts index 8a864358fcf..2f36bb94445 100644 --- a/src/lib/header-names.ts +++ b/src/lib/header-names.ts @@ -1,20 +1,16 @@ const HeaderWordCasingExceptions: Record = { - ct: "CT", - etag: "ETag", - te: "TE", - www: "WWW", - x: "X", - xss: "XSS" + ct: 'CT', + etag: 'ETag', + te: 'TE', + www: 'WWW', + x: 'X', + xss: 'XSS', }; -export function normalizeHeaderName(name: string): string { +export function canonicalHeaderName(name: string): string { return name .toLowerCase() - .split("-") - .map( - word => - HeaderWordCasingExceptions[word] || - word.charAt(0).toUpperCase() + word.slice(1) - ) - .join("-"); + .split('-') + .map((word) => HeaderWordCasingExceptions[word] || word.charAt(0).toUpperCase() + word.slice(1)) + .join('-'); } diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index 6731566f651..98c973d8e3a 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -1,7 +1,7 @@ import { ContentDisposition } from './content-disposition.js'; import { ContentType } from './content-type.js'; import { Cookie } from './cookie.js'; -import { normalizeHeaderName } from './header-names.js'; +import { canonicalHeaderName } from './header-names.js'; import { HeaderValue } from './header-value.js'; const CRLF = '\r\n'; @@ -74,7 +74,7 @@ export class SuperHeaders implements Iterable<[string, string]> { for (let [name, value] of this.map) { let stringValue = value.toString(); if (stringValue !== '') { - yield [normalizeHeaderName(name), stringValue]; + yield [canonicalHeaderName(name), stringValue]; } } } @@ -124,11 +124,12 @@ export class SuperHeaders implements Iterable<[string, string]> { get contentLength(): number { let value = this.map.get('content-length'); + if (typeof value === 'number') return value; return value ? parseInt(value.toString(), 10) : NaN; } set contentLength(value: number) { - this.map.set('content-length', value.toString()); + this.map.set('content-length', value); } get contentType(): ContentType { From 5e69ad44815d6caca31e55029641554a57d721dd Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 12 Jul 2024 13:24:21 -0700 Subject: [PATCH 014/730] Make SuperHeaders an instanceof Headers --- README.md | 54 ++++++++++++++++++++++++----------- package.json | 2 +- src/lib/super-headers.spec.ts | 6 ++++ src/lib/super-headers.ts | 7 +++-- 4 files changed, 49 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 2c8a3ec2703..3f07acdae23 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,16 @@ # fetch-super-headers -This package is a suite of tools that make it a little more fun to work with `Headers`. +fetch-super-headers is JavaScript `Headers`, with superpowers. ## Key Features -- Drop-in replacement for the standard `Headers` object +This package is a suite of tools that make it a little more fun to work with `Headers`. + +- Drop-in replacement for [the standard `Headers` object](https://developer.mozilla.org/en-US/docs/Web/API/Headers) - Strongly typed header-specific getters and setters (e.g., `contentType`, `cookie`) - Easy parsing and manipulation of complex headers like Content-Type and Content-Disposition - Iterable interface for easy header enumeration -- Convenient string conversion for HTTP message assembly +- Convenient string conversion for HTTP message parsing and assembly ## Installation @@ -22,11 +24,11 @@ fetch-super-headers is designed to be a drop-in replacement for `Headers`, with headers feel a lot more like working with JavaScript objects. ```ts -import Headers from 'fetch-super-headers'; -// or, if you don't want to clobber the global `Headers` reference: -// import SuperHeaders from 'fetch-super-headers'; +import SuperHeaders from 'fetch-super-headers'; +// or, if you don't mind clobbering the global `Headers` reference: +// import Headers from `fetch-super-headers'; -let headers = new Headers(); +let headers = new SuperHeaders(); // Content-Type headers.contentType = 'application/json; charset=utf-8'; @@ -43,6 +45,7 @@ headers.contentDisposition = console.log(headers.contentDisposition.type); // 'attachment' console.log(headers.contentDisposition.filename); // 'example.pdf' +console.log(headers.contentDisposition.filenameSplat); // 'UTF-8\'\'%E4%BE%8B%E5%AD%90.pdf' console.log(headers.contentDisposition.preferredFilename); // '例子.pdf' // Cookie @@ -55,10 +58,31 @@ headers.cookie.set('theme', 'dark'); console.log(headers.get('Cookie')); // 'session_id=abc123; user_id=12345; theme=dark' ``` -Headers are iterable: +You can easily build `SuperHeaders` from an exising `Headers` object, like the one you get in a `fetch` response: ```ts -let headers = new Headers({ +let response = await fetch('https://example.com'); +let headers = new SuperHeaders(response.headers); +``` + +Or use them to construct a new `fetch` request, or even convert back to a normal `Headers` object: + +```ts +// this works +fetch('https://example.com', { + headers: new SuperHeaders(), +}); + +// this works too +let headers = new Headers(new SuperHeaders()); + +assert.ok(new SuperHeaders() instanceof Headers); +``` + +`SuperHeaders` are iterable: + +```ts +let headers = new SuperHeaders({ 'Content-Type': 'application/json', 'X-API-Key': 'secret-key', 'Accept-Language': 'en-US,en;q=0.9', @@ -72,24 +96,20 @@ for (let [name, value] of headers) { // Accept-Language: en-US,en;q=0.9 ``` -And you can easily build them from an exising `Headers` object, like the one you get in a `fetch` response: - -```ts -let response = await fetch('https://example.com'); -let headers = new Headers(response.headers); -``` - If you're assembling HTTP messages, you can easily convert to a multiline string suitable for using as a Request/Response header block: ```ts -let headers = new Headers(); +let headers = new SuperHeaders(); headers.set('content-type', 'text/html'); // or headers.contentType = 'text/html' headers.set('X-Custom-Header', 'value'); console.log(headers.toString()); // Content-Type: text/html // X-Custom-Header: value + +// Note: This varies from the built-in Headers class where you would normally +// get [object Headers] from toString(). ``` In addition to the high-level API, fetch-super-headers also exposes all of the low-level parsers it uses for each individual HTTP diff --git a/package.json b/package.json index 6f6bb9c4181..c7d770a515c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "fetch-super-headers", "version": "0.2.0", - "description": "A suite of tools that make it a little more fun to work with Headers", + "description": "JavaScript Headers, with superpowers", "author": "Michael Jackson ", "license": "MIT", "files": [ diff --git a/src/lib/super-headers.spec.ts b/src/lib/super-headers.spec.ts index 54f4d8f1b6d..c757b4508cc 100644 --- a/src/lib/super-headers.spec.ts +++ b/src/lib/super-headers.spec.ts @@ -7,6 +7,12 @@ import { Cookie } from './cookie.js'; import { SuperHeaders } from './super-headers.js'; describe('SuperHeaders', () => { + it('is an instance of Headers', () => { + let headers = new SuperHeaders(); + assert.ok(headers instanceof SuperHeaders); + assert.ok(headers instanceof Headers); + }); + it('initializes with no arguments', () => { let headers = new SuperHeaders(); assert.equal(headers.get('content-type'), null); diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index 98c973d8e3a..24aac3a4aa3 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -13,13 +13,16 @@ export type SuperHeadersInit = | Record; /** - * HTTP Headers object, with superpowers. + * A Headers object, with superpowers. */ -export class SuperHeaders implements Iterable<[string, string]> { +export class SuperHeaders extends Headers implements Iterable<[string, string]> { private map: Map; constructor(init?: string | SuperHeadersInit) { + super(); + this.map = new Map(); + if (init) { if (typeof init === 'string') { let lines = init.split(CRLF); From 73cbe32d258a374ef8190ae7112f710ada15d5bc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 14 Jul 2024 20:20:53 -0700 Subject: [PATCH 015/730] Add parseMultipartStream function --- src/index.ts | 1 + src/lib/multipart.spec.ts | 2 +- src/lib/multipart.ts | 34 +++++++++++++++++++++++++++------- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index 56b4fa96093..473869b5f9c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,4 +4,5 @@ export { isMultipartFormData, MultipartParseOptions, parseMultipartFormData, + parseMultipartStream, } from './lib/multipart.js'; diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index f1646e573cd..81223b2cd91 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -42,7 +42,7 @@ function createMockRequest( } as unknown as Request; } -describe('Multipart Form Data Parser', async () => { +describe('parseMultipartFormData', async () => { let boundary = 'boundary123'; it('Successfully parses a simple multipart form', async () => { diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 01ddebadac1..05b1aab6660 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -115,10 +115,9 @@ const textDecoder = new TextDecoder(); const findDoubleCRLF = createSeqFinder(textEncoder.encode(CRLF + CRLF)); /** - * Parses a multipart/form-data request body and yields each part as a MultipartPart object. - * - * Throws MultipartParseError if the parse fails for some reason. + * Parses a `multipart/form-data` request body and yields each part as a `MultipartPart` object. * + * Throws `MultipartParseError` if the parse fails for some reason. * * Example: * @@ -150,9 +149,6 @@ export async function* parseMultipartFormData( request: Request, options: MultipartParseOptions = {} ): AsyncGenerator { - let maxHeaderSize = options.maxHeaderSize || DefaultMaxHeaderSize; - let maxPartSize = options.maxPartSize || DefaultMaxPartSize; - if (!isMultipartFormData(request)) { throw new MultipartParseError('Request is not multipart/form-data'); } @@ -166,12 +162,36 @@ export async function* parseMultipartFormData( } let boundary = boundaryMatch[1] || boundaryMatch[2]; // handle quoted and unquoted boundaries + + yield* parseMultipartStream(boundary, request.body, options); +} + +/** + * Parses a multipart stream and yields each part as a `MultipartPart` object. + * + * Throws `MultipartParseError` if the parse fails for some reason. + * + * Note: This is a low-level function that requires manually handling the stream and boundary. For most common use cases, + * consider using `parseMultipartFormData(request)` instead. + * + * @param boundary + * @param stream + * @param options + */ +export async function* parseMultipartStream( + boundary: string, + stream: ReadableStream, + options: MultipartParseOptions = {} +) { + let maxHeaderSize = options.maxHeaderSize || DefaultMaxHeaderSize; + let maxPartSize = options.maxPartSize || DefaultMaxPartSize; + let boundarySeq = textEncoder.encode(`--${boundary}`); let findBoundary = createSeqFinder(boundarySeq); let initialBoundaryFound = false; let isFinished = false; - let reader = request.body.getReader(); + let reader = stream.getReader(); let buffer = new Uint8Array(0); let boundarySearchStartIndex = 0; From 8183c92f7feb911283d7f40aeb0e85dfeb5c2ca5 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 00:25:57 -0700 Subject: [PATCH 016/730] Add Set-Cookie support --- README.md | 2 - src/lib/content-disposition.spec.ts | 25 +---- src/lib/content-disposition.ts | 87 ++++++--------- src/lib/content-type.spec.ts | 134 ++++++++++------------- src/lib/content-type.ts | 75 +++++-------- src/lib/cookie.ts | 25 ++--- src/lib/param-values.spec.ts | 90 ++++++++++++++++ src/lib/param-values.ts | 26 +++-- src/lib/set-cookie.spec.ts | 160 ++++++++++++++++++++++++++++ src/lib/set-cookie.ts | 104 ++++++++++++++++++ src/lib/super-headers.spec.ts | 53 +++++++-- src/lib/super-headers.ts | 105 +++++++++++++----- 12 files changed, 621 insertions(+), 265 deletions(-) create mode 100644 src/lib/param-values.spec.ts create mode 100644 src/lib/set-cookie.spec.ts create mode 100644 src/lib/set-cookie.ts diff --git a/README.md b/README.md index 3f07acdae23..fe80f93bea2 100644 --- a/README.md +++ b/README.md @@ -68,12 +68,10 @@ let headers = new SuperHeaders(response.headers); Or use them to construct a new `fetch` request, or even convert back to a normal `Headers` object: ```ts -// this works fetch('https://example.com', { headers: new SuperHeaders(), }); -// this works too let headers = new Headers(new SuperHeaders()); assert.ok(new SuperHeaders() instanceof Headers); diff --git a/src/lib/content-disposition.spec.ts b/src/lib/content-disposition.spec.ts index 42ca8cd8d5b..9032e961bfe 100644 --- a/src/lib/content-disposition.spec.ts +++ b/src/lib/content-disposition.spec.ts @@ -12,7 +12,7 @@ describe('ContentDisposition', () => { it('handles empty initial value', () => { let header = new ContentDisposition(''); - assert.equal(header.type, ''); + assert.equal(header.type, undefined); assert.equal(header.filename, undefined); }); @@ -46,24 +46,6 @@ describe('ContentDisposition', () => { assert.equal(header.filenameSplat, "UTF-8''%E6%96%87%E4%BB%B6.txt"); }); - it('removes filename when set to null', () => { - let header = new ContentDisposition('attachment; filename="example.txt"'); - header.filename = null; - assert.equal(header.filename, undefined); - }); - - it('removes name when set to null', () => { - let header = new ContentDisposition('form-data; name="field1"'); - header.name = null; - assert.equal(header.name, undefined); - }); - - it('removes filenameSplat when set to null', () => { - let header = new ContentDisposition("attachment; filename*=UTF-8''%E6%96%87%E4%BB%B6.txt"); - header.filenameSplat = null; - assert.equal(header.filenameSplat, undefined); - }); - it('handles quoted attribute values', () => { let header = new ContentDisposition('attachment; filename="file with spaces.txt"'); assert.equal(header.filename, 'file with spaces.txt'); @@ -86,11 +68,6 @@ describe('ContentDisposition', () => { assert.equal(header.type, 'Attachment'); }); - it('converts attribute names to lowercase', () => { - let header = new ContentDisposition('attachment; FileName="example.txt"'); - assert.equal(header.filename, 'example.txt'); - }); - it('handles attribute values with special characters', () => { let header = new ContentDisposition( 'attachment; filename="file with spaces and (parentheses).txt"' diff --git a/src/lib/content-disposition.ts b/src/lib/content-disposition.ts index e812aace410..27fef55b7d0 100644 --- a/src/lib/content-disposition.ts +++ b/src/lib/content-disposition.ts @@ -1,21 +1,29 @@ import { HeaderValue } from './header-value.js'; -import { quote, unquote } from './param-values.js'; +import { quote, parseParams } from './param-values.js'; /** * Represents the value of a `Content-Disposition` HTTP header. */ export class ContentDisposition implements HeaderValue { - private attributes: Map; - private _type: string; - - constructor(initialValue: string) { - this.attributes = new Map(); - let parts = initialValue.split(';').map((part) => part.trim()); - this._type = parts[0]; - for (let i = 1; i < parts.length; i++) { - let match = parts[i].match(/([\w\*]+)\s*=\s*(.*)/); - if (match) { - this.attributes.set(match[1].toLowerCase(), unquote(match[2])); + public type?: string; + public filename?: string; + public filenameSplat?: string; + public name?: string; + + constructor(initialValue?: string) { + if (initialValue) { + let params = parseParams(initialValue); + if (params.length > 0) { + this.type = params[0][0]; + for (let [name, value] of params.slice(1)) { + if (name === 'filename') { + this.filename = value; + } else if (name === 'filename*') { + this.filenameSplat = value; + } else if (name === 'name') { + this.name = value; + } + } } } } @@ -35,55 +43,22 @@ export class ContentDisposition implements HeaderValue { return this.filename; } - get filename(): string | undefined { - return this.attributes.get('filename'); - } + toString(): string { + let parts = []; - set filename(value: string | null) { - if (value === null) { - this.attributes.delete('filename'); - } else { - this.attributes.set('filename', value); + if (this.type) { + parts.push(this.type); } - } - - get filenameSplat(): string | undefined { - return this.attributes.get('filename*'); - } - - set filenameSplat(value: string | null) { - if (value === null) { - this.attributes.delete('filename*'); - } else { - this.attributes.set('filename*', value); + if (this.name) { + parts.push(`name=${quote(this.name)}`); } - } - - get name(): string | undefined { - return this.attributes.get('name'); - } - - set name(value: string | null) { - if (value === null) { - this.attributes.delete('name'); - } else { - this.attributes.set('name', value); + if (this.filename) { + parts.push(`filename=${quote(this.filename)}`); } - } - - get type(): string { - return this._type; - } - - set type(value: string) { - this._type = value.trim(); - } - - toString(): string { - let parts = [this._type]; - for (let [key, value] of this.attributes) { - parts.push(`${key}=${quote(value)}`); + if (this.filenameSplat) { + parts.push(`filename*=${quote(this.filenameSplat)}`); } + return parts.join('; '); } } diff --git a/src/lib/content-type.spec.ts b/src/lib/content-type.spec.ts index d15a824216f..187243b550c 100644 --- a/src/lib/content-type.spec.ts +++ b/src/lib/content-type.spec.ts @@ -1,116 +1,90 @@ -import * as assert from "node:assert/strict"; -import { describe, it } from "node:test"; +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; -import { ContentType } from "./content-type.js"; +import { ContentType } from './content-type.js'; -describe("ContentType", () => { - it("parses initial value correctly", () => { - let header = new ContentType("text/plain; charset=utf-8"); - assert.equal(header.mediaType, "text/plain"); - assert.equal(header.charset, "utf-8"); +describe('ContentType', () => { + it('parses initial value correctly', () => { + let header = new ContentType('text/plain; charset=utf-8'); + assert.equal(header.mediaType, 'text/plain'); + assert.equal(header.charset, 'utf-8'); }); - it("handles empty initial value", () => { - let header = new ContentType(""); - assert.equal(header.mediaType, ""); + it('handles empty initial value', () => { + let header = new ContentType(''); + assert.equal(header.mediaType, undefined); assert.equal(header.charset, undefined); }); - it("handles whitespace in initial value", () => { - let header = new ContentType(" text/html ; charset = iso-8859-1 "); - assert.equal(header.mediaType, "text/html"); - assert.equal(header.charset, "iso-8859-1"); + it('handles whitespace in initial value', () => { + let header = new ContentType(' text/html ; charset = iso-8859-1 '); + assert.equal(header.mediaType, 'text/html'); + assert.equal(header.charset, 'iso-8859-1'); }); - it("sets and gets media type", () => { - let header = new ContentType("text/plain"); - header.mediaType = "application/json"; - assert.equal(header.mediaType, "application/json"); + it('sets and gets media type', () => { + let header = new ContentType('text/plain'); + header.mediaType = 'application/json'; + assert.equal(header.mediaType, 'application/json'); }); - it("sets and gets charset", () => { - let header = new ContentType("text/plain"); - header.charset = "utf-8"; - assert.equal(header.charset, "utf-8"); + it('sets and gets charset', () => { + let header = new ContentType('text/plain'); + header.charset = 'utf-8'; + assert.equal(header.charset, 'utf-8'); }); - it("sets and gets boundary", () => { - let header = new ContentType("multipart/form-data"); - header.boundary = "abc123"; - assert.equal(header.boundary, "abc123"); + it('sets and gets boundary', () => { + let header = new ContentType('multipart/form-data'); + header.boundary = 'abc123'; + assert.equal(header.boundary, 'abc123'); }); - it("removes charset when set to null", () => { - let header = new ContentType("text/plain; charset=utf-8"); - header.charset = null; - assert.equal(header.charset, undefined); - }); - - it("removes boundary when set to null", () => { - let header = new ContentType("multipart/form-data; boundary=abc123"); - header.boundary = null; - assert.equal(header.boundary, undefined); - }); - - it("handles quoted attribute values", () => { + it('handles quoted attribute values', () => { let header = new ContentType('text/plain; charset="us-ascii"'); - assert.equal(header.charset, "us-ascii"); - }); - - it("converts to string correctly", () => { - let header = new ContentType("text/plain; charset=utf-8"); - assert.equal(header.toString(), "text/plain; charset=utf-8"); + assert.equal(header.charset, 'us-ascii'); }); - it("handles multiple attributes", () => { - let header = new ContentType( - 'multipart/form-data; boundary="abc123"; charset=utf-8' - ); - assert.equal(header.mediaType, "multipart/form-data"); - assert.equal(header.boundary, "abc123"); - assert.equal(header.charset, "utf-8"); + it('converts to string correctly', () => { + let header = new ContentType('text/plain; charset=utf-8'); + assert.equal(header.toString(), 'text/plain; charset=utf-8'); }); - it("preserves case for media type", () => { - let header = new ContentType("Text/HTML"); - assert.equal(header.mediaType, "Text/HTML"); + it('handles multiple attributes', () => { + let header = new ContentType('multipart/form-data; boundary="abc123"; charset=utf-8'); + assert.equal(header.mediaType, 'multipart/form-data'); + assert.equal(header.boundary, 'abc123'); + assert.equal(header.charset, 'utf-8'); }); - it("converts attribute names to lowercase", () => { - let header = new ContentType("text/plain; CharSet=utf-8"); - assert.equal(header.charset, "utf-8"); + it('preserves case for media type', () => { + let header = new ContentType('Text/HTML'); + assert.equal(header.mediaType, 'Text/HTML'); }); - it("handles attribute values with special characters", () => { - let header = new ContentType( - 'multipart/form-data; boundary="---=_Part_0_1234567.89"' - ); - assert.equal(header.boundary, "---=_Part_0_1234567.89"); + it('handles attribute values with special characters', () => { + let header = new ContentType('multipart/form-data; boundary="---=_Part_0_1234567.89"'); + assert.equal(header.boundary, '---=_Part_0_1234567.89'); }); - it("correctly quotes attribute values in toString()", () => { - let header = new ContentType("multipart/form-data"); - header.boundary = "abc 123"; + it('correctly quotes attribute values in toString()', () => { + let header = new ContentType('multipart/form-data'); + header.boundary = 'abc 123'; assert.equal(header.toString(), 'multipart/form-data; boundary="abc 123"'); }); - it("handles empty attribute values", () => { - let header = new ContentType("text/plain; charset="); - assert.equal(header.charset, ""); + it('handles empty attribute values', () => { + let header = new ContentType('text/plain; charset='); + assert.equal(header.charset, ''); }); - it("ignores attributes without values", () => { - let header = new ContentType("text/plain; charset"); + it('ignores attributes without values', () => { + let header = new ContentType('text/plain; charset'); assert.equal(header.charset, undefined); }); - it("preserves order of attributes in toString()", () => { - let header = new ContentType( - "multipart/form-data; charset=utf-8; boundary=abc123" - ); - assert.equal( - header.toString(), - "multipart/form-data; charset=utf-8; boundary=abc123" - ); + it('preserves order of attributes in toString()', () => { + let header = new ContentType('multipart/form-data; charset=utf-8; boundary=abc123'); + assert.equal(header.toString(), 'multipart/form-data; charset=utf-8; boundary=abc123'); }); }); diff --git a/src/lib/content-type.ts b/src/lib/content-type.ts index 44308d6aea8..56533aa6c5f 100644 --- a/src/lib/content-type.ts +++ b/src/lib/content-type.ts @@ -1,62 +1,43 @@ -import { HeaderValue } from "./header-value.js"; -import { quote, unquote } from "./param-values.js"; +import { HeaderValue } from './header-value.js'; +import { quote, parseParams } from './param-values.js'; /** * Represents the value of a `Content-Type` HTTP header. */ export class ContentType implements HeaderValue { - private attributes: Map; - private _mediaType: string; - - constructor(initialValue: string) { - this.attributes = new Map(); - let parts = initialValue.split(";").map(part => part.trim()); - this._mediaType = parts[0]; - for (let i = 1; i < parts.length; i++) { - let match = parts[i].match(/(\w+)\s*=\s*(.*)/); - if (match) { - this.attributes.set(match[1].toLowerCase(), unquote(match[2])); + public mediaType?: string; + public boundary?: string; + public charset?: string; + + constructor(initialValue?: string) { + if (initialValue) { + let params = parseParams(initialValue); + if (params.length > 0) { + this.mediaType = params[0][0]; + for (let [name, value] of params.slice(1)) { + if (name === 'boundary') { + this.boundary = value; + } else if (name === 'charset') { + this.charset = value; + } + } } } } - get boundary(): string | undefined { - return this.attributes.get("boundary"); - } + toString(): string { + let parts = []; - set boundary(value: string | null) { - if (value === null) { - this.attributes.delete("boundary"); - } else { - this.attributes.set("boundary", value); + if (this.mediaType) { + parts.push(this.mediaType); } - } - - get charset(): string | undefined { - return this.attributes.get("charset"); - } - - set charset(value: string | null) { - if (value === null) { - this.attributes.delete("charset"); - } else { - this.attributes.set("charset", value); + if (this.charset) { + parts.push(`charset=${quote(this.charset)}`); } - } - - get mediaType(): string { - return this._mediaType; - } - - set mediaType(value: string) { - this._mediaType = value.trim(); - } - - toString(): string { - let parts = [this._mediaType]; - for (let [key, value] of this.attributes) { - parts.push(`${key}=${quote(value)}`); + if (this.boundary) { + parts.push(`boundary=${quote(this.boundary)}`); } - return parts.join("; "); + + return parts.join('; '); } } diff --git a/src/lib/cookie.ts b/src/lib/cookie.ts index 9145c838052..a1b1e842a42 100644 --- a/src/lib/cookie.ts +++ b/src/lib/cookie.ts @@ -1,18 +1,19 @@ import { HeaderValue } from './header-value.js'; +import { quote, parseParams } from './param-values.js'; + /** * Represents the value of a `Cookie` HTTP header. */ export class Cookie implements HeaderValue, Iterable<[string, string]> { private cookies: Map; - constructor(initialValue: string) { + constructor(initialValue?: string) { this.cookies = new Map(); - let pairs = initialValue.split(';').map((pair) => pair.trim()); - for (let pair of pairs) { - let [name, value] = splitNameValue(pair); - if (name) { - this.cookies.set(name, value); + if (initialValue) { + let params = parseParams(initialValue); + for (let [name, value] of params) { + this.cookies.set(name, value || ''); } } } @@ -66,17 +67,11 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> { toString(): string { let pairs: string[] = []; + for (let [name, value] of this.cookies) { - pairs.push(`${name}=${value}`); + pairs.push(`${name}=${quote(value)}`); } - return pairs.join('; '); - } -} -function splitNameValue(pair: string): [string, string] { - let equalsIndex = pair.indexOf('='); - if (equalsIndex === -1) { - return [pair, '']; + return pairs.join('; '); } - return [pair.substring(0, equalsIndex).trim(), pair.substring(equalsIndex + 1).trim()]; } diff --git a/src/lib/param-values.spec.ts b/src/lib/param-values.spec.ts new file mode 100644 index 00000000000..569d33c1e35 --- /dev/null +++ b/src/lib/param-values.spec.ts @@ -0,0 +1,90 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { parseParams } from './param-values.js'; + +describe('parseParams', () => { + it('correctly parses a string of parameters for a Content-Type header', () => { + assert.deepEqual(parseParams('text/html; charset=utf-8'), [ + ['text/html', undefined], + ['charset', 'utf-8'], + ]); + assert.deepEqual(parseParams('application/json'), [['application/json', undefined]]); + assert.deepEqual(parseParams('multipart/form-data; boundary=----WebKitFormBoundaryABC123'), [ + ['multipart/form-data', undefined], + ['boundary', '----WebKitFormBoundaryABC123'], + ]); + }); + + it('correctly parses a string of parameters for a Content-Disposition header', () => { + assert.deepEqual(parseParams('form-data; name=fieldName'), [ + ['form-data', undefined], + ['name', 'fieldName'], + ]); + assert.deepEqual(parseParams('form-data; name="fieldName"; filename="filename.jpg"'), [ + ['form-data', undefined], + ['name', 'fieldName'], + ['filename', 'filename.jpg'], + ]); + assert.deepEqual( + parseParams("attachment; filename=photo.jpg; filename*=UTF-8''%E7%85%A7%E7%89%87.jpg"), + [ + ['attachment', undefined], + ['filename', 'photo.jpg'], + ['filename*', "UTF-8''%E7%85%A7%E7%89%87.jpg"], + ] + ); + assert.deepEqual( + parseParams('attachment; filename="photo.jpg"; filename*="UTF-8\'\'%E7%85%A7%E7%89%87.jpg"'), + [ + ['attachment', undefined], + ['filename', 'photo.jpg'], + ['filename*', "UTF-8''%E7%85%A7%E7%89%87.jpg"], + ] + ); + }); + + it('correctly parses a string of parameters for a Set-Cookie header', () => { + assert.deepEqual(parseParams('session_id=abc123; Path=/; HttpOnly; Secure'), [ + ['session_id', 'abc123'], + ['Path', '/'], + ['HttpOnly', undefined], + ['Secure', undefined], + ]); + assert.deepEqual(parseParams('user_pref="dark_mode"; Max-Age=31536000; SameSite=Lax'), [ + ['user_pref', 'dark_mode'], + ['Max-Age', '31536000'], + ['SameSite', 'Lax'], + ]); + assert.deepEqual( + parseParams( + 'preferences={"font":"Arial","size":"12pt"}; Expires=Fri, 31 Dec 2023 23:59:59 GMT' + ), + [ + ['preferences', '{"font":"Arial","size":"12pt"}'], + ['Expires', 'Fri, 31 Dec 2023 23:59:59 GMT'], + ] + ); + assert.deepEqual(parseParams('cart_items="[\\"item1\\",\\"item2\\"]"; Path=/cart; HttpOnly'), [ + ['cart_items', '["item1","item2"]'], + ['Path', '/cart'], + ['HttpOnly', undefined], + ]); + assert.deepEqual(parseParams('account_type="premium,\\"gold\\""; Domain=example.com; Secure'), [ + ['account_type', 'premium,"gold"'], + ['Domain', 'example.com'], + ['Secure', undefined], + ]); + assert.deepEqual( + parseParams('a2f_token=987654; Path=/2fa; Secure; HttpOnly; SameSite=Strict; Max-Age=300'), + [ + ['a2f_token', '987654'], + ['Path', '/2fa'], + ['Secure', undefined], + ['HttpOnly', undefined], + ['SameSite', 'Strict'], + ['Max-Age', '300'], + ] + ); + }); +}); diff --git a/src/lib/param-values.ts b/src/lib/param-values.ts index fd488559b49..4fff2f32ee7 100644 --- a/src/lib/param-values.ts +++ b/src/lib/param-values.ts @@ -1,13 +1,25 @@ -export function quote(value: string): string { - if (value.includes('"') || value.includes(";") || value.includes(" ")) { - return `"${value.replace(/"/g, '\\"')}"`; +export function parseParams(input: string): [string, string | undefined][] { + let regex = /(?:^|;)\s*([^=;\s]+)(\s*=\s*(?:"((?:[^"\\]|\\.)*)"|((?:[^;]|\\\;)+))?)?/g; + let params: [string, string | undefined][] = []; + + let match; + while ((match = regex.exec(input)) !== null) { + let key = match[1].trim(); + + let value: string | undefined; + if (match[2]) { + value = (match[3] || match[4] || '').replace(/\\(.)/g, '$1').trim(); + } + + params.push([key, value]); } - return value; + + return params; } -export function unquote(value: string): string { - if (value.startsWith('"') && value.endsWith('"')) { - return value.slice(1, -1).replace(/\\"/g, '"'); +export function quote(value: string): string { + if (value.includes('"') || value.includes(';') || value.includes(' ')) { + return `"${value.replace(/"/g, '\\"')}"`; } return value; } diff --git a/src/lib/set-cookie.spec.ts b/src/lib/set-cookie.spec.ts new file mode 100644 index 00000000000..cf2ca1e1509 --- /dev/null +++ b/src/lib/set-cookie.spec.ts @@ -0,0 +1,160 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { SetCookie } from './set-cookie.js'; + +describe('SetCookie', () => { + it('parses initial value correctly', () => { + let setCookie = new SetCookie( + 'session=abc123; Domain=example.com; Path=/; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly' + ); + assert.equal(setCookie.name, 'session'); + assert.equal(setCookie.value, 'abc123'); + assert.equal(setCookie.domain, 'example.com'); + assert.equal(setCookie.path, '/'); + assert.equal(setCookie.expires?.toUTCString(), 'Wed, 21 Oct 2015 07:28:00 GMT'); + assert.equal(setCookie.secure, true); + assert.equal(setCookie.httpOnly, true); + }); + + it('handles cookies without attributes', () => { + let setCookie = new SetCookie('user=john'); + assert.equal(setCookie.name, 'user'); + assert.equal(setCookie.value, 'john'); + }); + + it('initializes with an empty string', () => { + let setCookie = new SetCookie(''); + assert.equal(setCookie.name, undefined); + assert.equal(setCookie.value, undefined); + }); + + it('handles cookie values with commas', () => { + let setCookie = new SetCookie('list=apple,banana,cherry; Domain=example.com'); + assert.equal(setCookie.name, 'list'); + assert.equal(setCookie.value, 'apple,banana,cherry'); + assert.equal(setCookie.domain, 'example.com'); + }); + + it('handles cookie values with semicolons', () => { + let setCookie = new SetCookie('complex="value; with; semicolons"; Path=/'); + assert.equal(setCookie.name, 'complex'); + assert.equal(setCookie.value, 'value; with; semicolons'); + assert.equal(setCookie.path, '/'); + }); + + it('handles cookie values with equals signs', () => { + let setCookie = new SetCookie('equation="1+1=2"; Secure'); + assert.equal(setCookie.name, 'equation'); + assert.equal(setCookie.value, '1+1=2'); + assert.equal(setCookie.secure, true); + }); + + it('sets and gets attributes', () => { + let setCookie = new SetCookie('test=value'); + setCookie.domain = 'example.org'; + setCookie.path = '/api'; + setCookie.maxAge = 3600; + setCookie.secure = true; + setCookie.httpOnly = true; + setCookie.sameSite = 'Strict'; + + assert.equal(setCookie.domain, 'example.org'); + assert.equal(setCookie.path, '/api'); + assert.equal(setCookie.maxAge, 3600); + assert.equal(setCookie.secure, true); + assert.equal(setCookie.httpOnly, true); + assert.equal(setCookie.sameSite, 'Strict'); + }); + + it('converts to string correctly', () => { + let setCookie = new SetCookie('session=abc123'); + setCookie.domain = 'example.com'; + setCookie.path = '/'; + setCookie.secure = true; + setCookie.httpOnly = true; + setCookie.sameSite = 'Lax'; + + assert.equal( + setCookie.toString(), + 'session=abc123; Domain=example.com; Path=/; Secure; HttpOnly; SameSite=Lax' + ); + }); + + it('handles quoted values', () => { + let setCookie = new SetCookie('complex="quoted value; with semicolon"'); + assert.equal(setCookie.name, 'complex'); + assert.equal(setCookie.value, 'quoted value; with semicolon'); + }); + + it('parses and formats expires attribute correctly', () => { + let expiresDate = new Date('Wed, 21 Oct 2015 07:28:00 GMT'); + let setCookie = new SetCookie(`test=value; Expires=${expiresDate.toUTCString()}`); + assert.equal(setCookie.expires?.toUTCString(), expiresDate.toUTCString()); + + setCookie.expires = new Date('Thu, 22 Oct 2015 07:28:00 GMT'); + assert.equal(setCookie.toString(), 'test=value; Expires=Thu, 22 Oct 2015 07:28:00 GMT'); + }); + + it('handles SameSite attribute case-insensitively', () => { + let setCookie = new SetCookie('test=value; SameSite=lax'); + assert.equal(setCookie.sameSite, 'Lax'); + + setCookie = new SetCookie('test=value; SameSite=STRICT'); + assert.equal(setCookie.sameSite, 'Strict'); + + setCookie = new SetCookie('test=value; SameSite=NoNe'); + assert.equal(setCookie.sameSite, 'None'); + }); + + it('handles cookies with empty value', () => { + let setCookie = new SetCookie('name='); + assert.equal(setCookie.name, 'name'); + assert.equal(setCookie.value, ''); + }); + + it('handles multiple identical attributes', () => { + let setCookie = new SetCookie('test=value; Path=/; Path=/api'); + assert.equal(setCookie.path, '/api'); + }); + + it('ignores unknown attributes', () => { + let setCookie = new SetCookie('test=value; Unknown=something'); + assert.equal(setCookie.toString(), 'test=value'); + }); + + it('handles Max-Age as a number', () => { + let setCookie = new SetCookie('test=value; Max-Age=3600'); + assert.equal(setCookie.maxAge, 3600); + }); + + it('ignores invalid Max-Age', () => { + let setCookie = new SetCookie('test=value; Max-Age=invalid'); + assert.equal(setCookie.maxAge, undefined); + }); + + it('handles missing value in attributes', () => { + let setCookie = new SetCookie('test=value; Domain=; Path'); + assert.equal(setCookie.domain, ''); + assert.equal(setCookie.path, undefined); + }); + + it('preserves the case of the cookie name and value', () => { + let setCookie = new SetCookie('TestName=TestValue'); + assert.equal(setCookie.name, 'TestName'); + assert.equal(setCookie.value, 'TestValue'); + }); + + it('handles setting new name and value', () => { + let setCookie = new SetCookie('old=value'); + setCookie.name = 'new'; + setCookie.value = 'newvalue'; + assert.equal(setCookie.toString(), 'new=newvalue'); + }); + + it('correctly quotes values when necessary', () => { + let setCookie = new SetCookie('test=value'); + setCookie.value = 'need; quotes'; + assert.equal(setCookie.toString(), 'test="need; quotes"'); + }); +}); diff --git a/src/lib/set-cookie.ts b/src/lib/set-cookie.ts new file mode 100644 index 00000000000..90aa154cd66 --- /dev/null +++ b/src/lib/set-cookie.ts @@ -0,0 +1,104 @@ +import { HeaderValue } from './header-value.js'; +import { quote, parseParams } from './param-values.js'; + +type SameSiteValue = 'Strict' | 'Lax' | 'None'; + +/** + * Represents the value of a `Set-Cookie` HTTP header. + */ +export class SetCookie implements HeaderValue { + public domain?: string; + public expires?: Date; + public httpOnly?: true; + public maxAge?: number; + public name?: string; + public path?: string; + public sameSite?: SameSiteValue; + public secure?: true; + public value?: string; + + constructor(initialValue?: string) { + if (initialValue) { + let params = parseParams(initialValue); + if (params.length > 0) { + this.name = params[0][0]; + this.value = params[0][1]; + + for (let [key, value] of params.slice(1)) { + switch (key.toLowerCase()) { + case 'domain': + this.domain = value; + break; + case 'expires': { + if (typeof value === 'string') { + let v = new Date(value); + if (isValidDate(v)) this.expires = v; + } + break; + } + case 'httponly': + this.httpOnly = true; + break; + case 'max-age': { + if (typeof value === 'string') { + let v = parseInt(value, 10); + if (!isNaN(v)) this.maxAge = v; + } + break; + } + case 'path': + this.path = value; + break; + case 'samesite': + if (typeof value === 'string' && /strict|lax|none/i.test(value)) { + this.sameSite = capitalize(value) as SameSiteValue; + } + break; + case 'secure': + this.secure = true; + break; + } + } + } + } + } + + toString(): string { + let parts = []; + + if (this.name) { + parts.push(`${this.name}=${quote(this.value || '')}`); + } + if (this.domain) { + parts.push(`Domain=${this.domain}`); + } + if (this.path) { + parts.push(`Path=${this.path}`); + } + if (this.expires) { + parts.push(`Expires=${this.expires.toUTCString()}`); + } + if (this.maxAge) { + parts.push(`Max-Age=${this.maxAge}`); + } + if (this.secure) { + parts.push('Secure'); + } + if (this.httpOnly) { + parts.push('HttpOnly'); + } + if (this.sameSite) { + parts.push(`SameSite=${this.sameSite}`); + } + + return parts.join('; '); + } +} + +function capitalize(str: string): string { + return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); +} + +function isValidDate(date: unknown): boolean { + return date instanceof Date && !isNaN(date.getTime()); +} diff --git a/src/lib/super-headers.spec.ts b/src/lib/super-headers.spec.ts index c757b4508cc..d3984e03bc5 100644 --- a/src/lib/super-headers.spec.ts +++ b/src/lib/super-headers.spec.ts @@ -38,12 +38,18 @@ describe('SuperHeaders', () => { assert.equal(headers.get('X-Custom'), 'value'); }); - it('initializes from another Headers instance', () => { + it('initializes from another SuperHeaders instance', () => { let original = new SuperHeaders({ 'Content-Type': 'text/plain' }); let headers = new SuperHeaders(original); assert.equal(headers.get('Content-Type'), 'text/plain'); }); + it('initializes from a Headers instance', () => { + let original = new Headers({ 'Content-Type': 'text/plain' }); + let headers = new SuperHeaders(original); + assert.equal(headers.get('Content-Type'), 'text/plain'); + }); + it('appends values', () => { let headers = new SuperHeaders(); headers.append('X-Custom', 'value1'); @@ -77,18 +83,26 @@ describe('SuperHeaders', () => { }); let entries = Array.from(headers.entries()); assert.deepEqual(entries, [ - ['Content-Type', 'text/plain'], - ['Content-Length', '42'], + ['content-type', 'text/plain'], + ['content-length', '42'], ]); }); - it('iterates over names', () => { + it('iterates over keys', () => { let headers = new SuperHeaders({ 'Content-Type': 'text/plain', 'Content-Length': '42', }); - let keys = Array.from(headers.names()); - assert.deepEqual(keys, ['Content-Type', 'Content-Length']); + let keys = Array.from(headers.keys()); + assert.deepEqual(keys, ['content-type', 'content-length']); + }); + + it('iterates over set-cookie keys correctly', () => { + let headers = new SuperHeaders(); + headers.append('Set-Cookie', 'session=abc'); + headers.append('Set-Cookie', 'theme=dark'); + let keys = Array.from(headers.keys()); + assert.deepEqual(keys, ['set-cookie', 'set-cookie']); }); it('iterates over values', () => { @@ -110,8 +124,8 @@ describe('SuperHeaders', () => { result.push([key, value]); }); assert.deepEqual(result, [ - ['Content-Type', 'text/plain'], - ['Content-Length', '42'], + ['content-type', 'text/plain'], + ['content-length', '42'], ]); }); @@ -122,8 +136,8 @@ describe('SuperHeaders', () => { }); let entries = Array.from(headers); assert.deepEqual(entries, [ - ['Content-Type', 'text/plain'], - ['Content-Length', '42'], + ['content-type', 'text/plain'], + ['content-length', '42'], ]); }); @@ -172,6 +186,22 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Cookie'), 'name1=value1; name2=value2; name3=value3'); }); + it('handles Set-Cookie header', () => { + let headers = new SuperHeaders(); + headers.setCookie = ['session=abc', 'theme=dark']; + + assert.ok(Array.isArray(headers.setCookie)); + assert.equal(headers.setCookie.length, 2); + assert.equal(headers.setCookie[0].name, 'session'); + assert.equal(headers.setCookie[0].value, 'abc'); + assert.equal(headers.setCookie[1].name, 'theme'); + assert.equal(headers.setCookie[1].value, 'dark'); + + headers.setCookie = [...headers.setCookie, 'lang=en']; + + assert.equal(headers.get('Set-Cookie'), 'session=abc, theme=dark, lang=en'); + }); + it('creates empty header objects when accessed', () => { let headers = new SuperHeaders(); @@ -183,6 +213,9 @@ describe('SuperHeaders', () => { assert.ok(headers.cookie instanceof Cookie); assert.equal(headers.cookie.toString(), ''); + + assert.ok(Array.isArray(headers.setCookie)); + assert.equal(headers.setCookie.length, 0); }); }); diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index 24aac3a4aa3..af7c6fbc435 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -3,8 +3,10 @@ import { ContentType } from './content-type.js'; import { Cookie } from './cookie.js'; import { canonicalHeaderName } from './header-names.js'; import { HeaderValue } from './header-value.js'; +import { SetCookie } from './set-cookie.js'; const CRLF = '\r\n'; +const SetCookieKey = 'set-cookie'; export type SuperHeadersInit = | SuperHeaders @@ -17,6 +19,7 @@ export type SuperHeadersInit = */ export class SuperHeaders extends Headers implements Iterable<[string, string]> { private map: Map; + private setCookieValues: (string | SetCookie)[] = []; constructor(init?: string | SuperHeadersInit) { super(); @@ -52,39 +55,74 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> append(name: string, value: string | HeaderValue): void { let key = name.toLowerCase(); - let existingValue = this.map.get(key); - this.map.set(key, existingValue ? `${existingValue}, ${value}` : value); + if (key === SetCookieKey) { + this.setCookieValues.push(value as string | SetCookie); + } else { + let existingValue = this.map.get(key); + this.map.set(key, existingValue ? `${existingValue}, ${value}` : value); + } } delete(name: string): void { - this.map.delete(name.toLowerCase()); + let key = name.toLowerCase(); + if (key === SetCookieKey) { + this.setCookieValues = []; + } else { + this.map.delete(key); + } } get(name: string): string | null { - let value = this.map.get(name.toLowerCase()); - return value === undefined ? null : value.toString(); + let key = name.toLowerCase(); + if (key === SetCookieKey) { + return this.setCookieValues.map((value) => value.toString()).join(', '); + } else { + let value = this.map.get(key); + return value === undefined ? null : value.toString(); + } + } + + getSetCookie(): string[] { + return this.setCookieValues.map((value) => value.toString()); } has(name: string): boolean { - return this.map.has(name.toLowerCase()); + let key = name.toLowerCase(); + if (key === SetCookieKey) { + return this.setCookieValues.length > 0; + } else { + return this.map.has(key); + } } set(name: string, value: string | HeaderValue): void { - this.map.set(name.toLowerCase(), value); + let key = name.toLowerCase(); + if (key === SetCookieKey) { + this.setCookieValues = [value as string | SetCookie]; + } else { + this.map.set(key, value); + } } *entries(): IterableIterator<[string, string]> { - for (let [name, value] of this.map) { + for (let [key, value] of this.map) { let stringValue = value.toString(); if (stringValue !== '') { - yield [canonicalHeaderName(name), stringValue]; + yield [key, stringValue]; + } + } + + for (let value of this.setCookieValues) { + let stringValue = value.toString(); + if (stringValue !== '') { + yield [SetCookieKey, stringValue]; } } } - *names(): IterableIterator { - for (let [name] of this) { - yield name; + *keys(): IterableIterator { + for (let [key] of this) { + yield key; } } @@ -99,18 +137,18 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } forEach( - callback: (value: string, name: string, parent: SuperHeaders) => void, + callback: (value: string, key: string, parent: SuperHeaders) => void, thisArg?: any ): void { - for (let [name, value] of this) { - callback.call(thisArg, value, name, this); + for (let [key, value] of this) { + callback.call(thisArg, value, key, this); } } toString(): string { let lines: string[] = []; - for (let [name, value] of this) { - lines.push(`${name}: ${value}`); + for (let [key, value] of this) { + lines.push(`${canonicalHeaderName(key)}: ${value}`); } return lines.join(CRLF); } @@ -118,7 +156,7 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> // Header-specific getters and setters get contentDisposition(): ContentDisposition { - return this.getHeaderValue('content-disposition', ContentDisposition) as ContentDisposition; + return this.getHeaderValue('content-disposition', ContentDisposition); } set contentDisposition(value: string | ContentDisposition) { @@ -136,7 +174,7 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } get contentType(): ContentType { - return this.getHeaderValue('content-type', ContentType) as ContentType; + return this.getHeaderValue('content-type', ContentType); } set contentType(value: string | ContentType) { @@ -144,17 +182,36 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } get cookie(): Cookie { - return this.getHeaderValue('cookie', Cookie) as Cookie; + return this.getHeaderValue('cookie', Cookie); } set cookie(value: string | Cookie) { this.map.set('cookie', value); } - private getHeaderValue( + get setCookie(): SetCookie[] { + for (let i = 0; i < this.setCookieValues.length; i++) { + let value = this.setCookieValues[i]; + if (typeof value === 'string') { + this.setCookieValues[i] = new SetCookie(value); + } + } + + return this.setCookieValues as SetCookie[]; + } + + set setCookie(values: string | (string | SetCookie)[]) { + if (typeof values === 'string') { + this.setCookieValues = [values]; + } else { + this.setCookieValues = values.slice(0); + } + } + + private getHeaderValue( key: string, - ctor: new (initialValue: string) => HeaderValue - ): HeaderValue { + ctor: new (initialValue: string) => T + ): T { let value = this.map.get(key); if (value) { if (typeof value === 'string') { @@ -162,7 +219,7 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.map.set(key, headerValue); return headerValue; } else { - return value; + return value as T; } } else { let headerValue = new ctor(''); From f7f6a8887b636b0fd7a0c82b87afdd082cad581c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 00:30:31 -0700 Subject: [PATCH 017/730] Add some scripts --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index c7d770a515c..bfb52cb8821 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,9 @@ "build": "pnpm run build:cjs && pnpm run build:esm", "build:cjs": "tsc --outDir dist --project tsconfig.lib.json", "build:esm": "esbuild src/index.ts --bundle --format=esm --target=node16 --outfile=dist/index.mjs", - "test": "node --import tsimp/import --test ./src/**/*.spec.ts" + "test": "node --import tsimp/import --test ./src/**/*.spec.ts", + "prepare": "pnpm run build", + "prepublishOnly": "pnpm run test" }, "devDependencies": { "@types/node": "^20.14.10", From 598eb871d63e2b7680f4cc6efe6434cac4ae06f2 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 00:31:05 -0700 Subject: [PATCH 018/730] Version 0.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bfb52cb8821..9bb031b81a6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fetch-super-headers", - "version": "0.2.0", + "version": "0.3.0", "description": "JavaScript Headers, with superpowers", "author": "Michael Jackson ", "license": "MIT", From 0ebdf93d54be0495ae8f741888ae1b1c88232f07 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 00:49:35 -0700 Subject: [PATCH 019/730] Export SetCookie --- src/index.ts | 13 +++++-------- src/lib/content-disposition.ts | 2 +- src/lib/content-type.ts | 2 +- src/lib/cookie.ts | 3 +-- src/lib/set-cookie.ts | 2 +- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/index.ts b/src/index.ts index 91e2c5de65b..65209a0b491 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,6 @@ -export { - SuperHeadersInit, - SuperHeaders, - SuperHeaders as default -} from "./lib/super-headers.js"; +export { SuperHeadersInit, SuperHeaders, SuperHeaders as default } from './lib/super-headers.js'; -export { ContentDisposition } from "./lib/content-disposition.js"; -export { ContentType } from "./lib/content-type.js"; -export { Cookie } from "./lib/cookie.js"; +export { ContentDisposition } from './lib/content-disposition.js'; +export { ContentType } from './lib/content-type.js'; +export { Cookie } from './lib/cookie.js'; +export { SetCookie } from './lib/set-cookie.js'; diff --git a/src/lib/content-disposition.ts b/src/lib/content-disposition.ts index 27fef55b7d0..c7c309f6cf0 100644 --- a/src/lib/content-disposition.ts +++ b/src/lib/content-disposition.ts @@ -1,5 +1,5 @@ import { HeaderValue } from './header-value.js'; -import { quote, parseParams } from './param-values.js'; +import { parseParams, quote } from './param-values.js'; /** * Represents the value of a `Content-Disposition` HTTP header. diff --git a/src/lib/content-type.ts b/src/lib/content-type.ts index 56533aa6c5f..9a7882366d5 100644 --- a/src/lib/content-type.ts +++ b/src/lib/content-type.ts @@ -1,5 +1,5 @@ import { HeaderValue } from './header-value.js'; -import { quote, parseParams } from './param-values.js'; +import { parseParams, quote } from './param-values.js'; /** * Represents the value of a `Content-Type` HTTP header. diff --git a/src/lib/cookie.ts b/src/lib/cookie.ts index a1b1e842a42..c030a0ac26a 100644 --- a/src/lib/cookie.ts +++ b/src/lib/cookie.ts @@ -1,6 +1,5 @@ import { HeaderValue } from './header-value.js'; - -import { quote, parseParams } from './param-values.js'; +import { parseParams, quote } from './param-values.js'; /** * Represents the value of a `Cookie` HTTP header. diff --git a/src/lib/set-cookie.ts b/src/lib/set-cookie.ts index 90aa154cd66..4619cea01e9 100644 --- a/src/lib/set-cookie.ts +++ b/src/lib/set-cookie.ts @@ -1,5 +1,5 @@ import { HeaderValue } from './header-value.js'; -import { quote, parseParams } from './param-values.js'; +import { parseParams, quote } from './param-values.js'; type SameSiteValue = 'Strict' | 'Lax' | 'None'; From feeeb0344ea10129bf1c5c2d8d6ed70aebe39faa Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 00:50:05 -0700 Subject: [PATCH 020/730] Version 0.3.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9bb031b81a6..56141f996fe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fetch-super-headers", - "version": "0.3.0", + "version": "0.3.1", "description": "JavaScript Headers, with superpowers", "author": "Michael Jackson ", "license": "MIT", From 93e4987f7d750d91fe4c12921e164e65fa2ad8eb Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 00:53:01 -0700 Subject: [PATCH 021/730] Tweak whitespace --- src/lib/super-headers.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index af7c6fbc435..bd5fa568ac6 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -147,9 +147,11 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> toString(): string { let lines: string[] = []; + for (let [key, value] of this) { lines.push(`${canonicalHeaderName(key)}: ${value}`); } + return lines.join(CRLF); } From 38e49b44b8732e04371bed300e1c216e0760fcfc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 01:46:15 -0700 Subject: [PATCH 022/730] Add support for more numeric and date headers --- src/lib/set-cookie.ts | 9 +-- src/lib/super-headers.spec.ts | 26 ++++++++ src/lib/super-headers.ts | 119 ++++++++++++++++++++++++++++++---- src/lib/utils.ts | 7 ++ 4 files changed, 141 insertions(+), 20 deletions(-) create mode 100644 src/lib/utils.ts diff --git a/src/lib/set-cookie.ts b/src/lib/set-cookie.ts index 4619cea01e9..000d99be5a5 100644 --- a/src/lib/set-cookie.ts +++ b/src/lib/set-cookie.ts @@ -1,5 +1,6 @@ import { HeaderValue } from './header-value.js'; import { parseParams, quote } from './param-values.js'; +import { capitalize, isValidDate } from './utils.js'; type SameSiteValue = 'Strict' | 'Lax' | 'None'; @@ -94,11 +95,3 @@ export class SetCookie implements HeaderValue { return parts.join('; '); } } - -function capitalize(str: string): string { - return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); -} - -function isValidDate(date: unknown): boolean { - return date instanceof Date && !isNaN(date.getTime()); -} diff --git a/src/lib/super-headers.spec.ts b/src/lib/super-headers.spec.ts index d3984e03bc5..d948b18ec84 100644 --- a/src/lib/super-headers.spec.ts +++ b/src/lib/super-headers.spec.ts @@ -142,6 +142,14 @@ describe('SuperHeaders', () => { }); describe('header-specific getters and setters', () => { + it('handles Age header', () => { + let headers = new SuperHeaders(); + headers.age = 42; + + assert.equal(headers.age, 42); + assert.equal(headers.get('Age'), '42'); + }); + it('handles Content-Disposition header', () => { let headers = new SuperHeaders(); headers.contentDisposition = 'attachment; filename="example.txt"'; @@ -186,6 +194,24 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Cookie'), 'name1=value1; name2=value2; name3=value3'); }); + it('handles Expires header', () => { + let headers = new SuperHeaders(); + headers.expires = new Date('2021-01-01T00:00:00Z'); + + assert.ok(headers.expires instanceof Date); + assert.equal(headers.expires.toUTCString(), 'Fri, 01 Jan 2021 00:00:00 GMT'); + assert.equal(headers.get('Expires'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + }); + + it('handles Last-Modified header', () => { + let headers = new SuperHeaders(); + headers.lastModified = new Date('2021-01-01T00:00:00Z'); + + assert.ok(headers.lastModified instanceof Date); + assert.equal(headers.lastModified.toUTCString(), 'Fri, 01 Jan 2021 00:00:00 GMT'); + assert.equal(headers.get('Last-Modified'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + }); + it('handles Set-Cookie header', () => { let headers = new SuperHeaders(); headers.setCookie = ['session=abc', 'theme=dark']; diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index bd5fa568ac6..b7a646eb3ed 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -4,6 +4,7 @@ import { Cookie } from './cookie.js'; import { canonicalHeaderName } from './header-names.js'; import { HeaderValue } from './header-value.js'; import { SetCookie } from './set-cookie.js'; +import { isValidDate } from './utils.js'; const CRLF = '\r\n'; const SetCookieKey = 'set-cookie'; @@ -78,7 +79,15 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> return this.setCookieValues.map((value) => value.toString()).join(', '); } else { let value = this.map.get(key); - return value === undefined ? null : value.toString(); + if (typeof value === 'string') { + return value; + } else if (value instanceof Date) { + return value.toUTCString(); + } else if (value != null) { + return value.toString(); + } else { + return null; + } } } @@ -105,16 +114,16 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } *entries(): IterableIterator<[string, string]> { - for (let [key, value] of this.map) { - let stringValue = value.toString(); - if (stringValue !== '') { + for (let [key] of this.map) { + let stringValue = this.get(key); + if (stringValue) { yield [key, stringValue]; } } for (let value of this.setCookieValues) { let stringValue = value.toString(); - if (stringValue !== '') { + if (stringValue) { yield [SetCookieKey, stringValue]; } } @@ -157,6 +166,14 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> // Header-specific getters and setters + get age(): number | undefined { + return this.getNumberValue('age'); + } + + set age(value: string | number) { + this.map.set('age', value); + } + get contentDisposition(): ContentDisposition { return this.getHeaderValue('content-disposition', ContentDisposition); } @@ -165,13 +182,11 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.map.set('content-disposition', value); } - get contentLength(): number { - let value = this.map.get('content-length'); - if (typeof value === 'number') return value; - return value ? parseInt(value.toString(), 10) : NaN; + get contentLength(): number | undefined { + return this.getNumberValue('content-length'); } - set contentLength(value: number) { + set contentLength(value: string | number) { this.map.set('content-length', value); } @@ -191,6 +206,46 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.map.set('cookie', value); } + get date(): Date | undefined { + return this.getDateValue('date'); + } + + set date(value: string | Date) { + this.map.set('date', value); + } + + get expires(): Date | undefined { + return this.getDateValue('expires'); + } + + set expires(value: string | Date) { + this.map.set('expires', value); + } + + get ifModifiedSince(): Date | undefined { + return this.getDateValue('if-modified-since'); + } + + set ifModifiedSince(value: string | Date) { + this.map.set('if-modified-since', value); + } + + get ifUnmodifiedSince(): Date | undefined { + return this.getDateValue('if-unmodified-since'); + } + + set ifUnmodifiedSince(value: string | Date) { + this.map.set('if-unmodified-since', value); + } + + get lastModified(): Date | undefined { + return this.getDateValue('last-modified'); + } + + set lastModified(value: string | Date) { + this.map.set('last-modified', value); + } + get setCookie(): SetCookie[] { for (let i = 0; i < this.setCookieValues.length; i++) { let value = this.setCookieValues[i]; @@ -210,9 +265,49 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } } + // helpers + + private getDateValue(key: string): Date | undefined { + let value = this.map.get(key); + if (value) { + if (typeof value === 'string') { + let date = new Date(value); + if (isValidDate(date)) { + this.map.set(key, date); // cache the parsed date + return date; + } else { + this.map.delete(key); // bad value, remove it + } + } else if (value instanceof Date) { + return value; + } else { + this.map.delete(key); // bad value, remove it + } + } + } + + private getNumberValue(key: string): number | undefined { + let value = this.map.get(key); + if (value) { + if (typeof value === 'string') { + let v = parseInt(value, 10); + if (!isNaN(v)) { + this.map.set(key, v); // cache the parsed number + return v; + } else { + this.map.delete(key); // bad value, remove it + } + } else if (typeof value === 'number') { + return value; + } else { + this.map.delete(key); // bad value, remove it + } + } + } + private getHeaderValue( key: string, - ctor: new (initialValue: string) => T + ctor: new (initialValue?: string) => T ): T { let value = this.map.get(key); if (value) { @@ -224,7 +319,7 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> return value as T; } } else { - let headerValue = new ctor(''); + let headerValue = new ctor(); this.map.set(key, headerValue); return headerValue; } diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 00000000000..4fd9eb73620 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,7 @@ +export function capitalize(str: string): string { + return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); +} + +export function isValidDate(date: unknown): boolean { + return date instanceof Date && !isNaN(date.getTime()); +} From cb0191ebc0b189871c8a7c4f635f09a892d63b88 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 08:38:31 -0700 Subject: [PATCH 023/730] Convert to empty strings when critical attributes are not set --- src/lib/content-disposition.spec.ts | 6 + src/lib/content-disposition.ts | 9 +- src/lib/content-type.spec.ts | 6 + src/lib/content-type.ts | 9 +- src/lib/set-cookie.spec.ts | 174 ++++++++++++++-------------- src/lib/set-cookie.ts | 9 +- 6 files changed, 117 insertions(+), 96 deletions(-) diff --git a/src/lib/content-disposition.spec.ts b/src/lib/content-disposition.spec.ts index 9032e961bfe..0bebd483ec8 100644 --- a/src/lib/content-disposition.spec.ts +++ b/src/lib/content-disposition.spec.ts @@ -56,6 +56,12 @@ describe('ContentDisposition', () => { assert.equal(header.toString(), 'attachment; filename=example.txt'); }); + it('converts to an empty string when type is not set', () => { + let header = new ContentDisposition(); + header.filename = 'example.txt'; + assert.equal(header.toString(), ''); + }); + it('handles multiple attributes', () => { let header = new ContentDisposition('form-data; name="field1"; filename="example.txt"'); assert.equal(header.type, 'form-data'); diff --git a/src/lib/content-disposition.ts b/src/lib/content-disposition.ts index c7c309f6cf0..c70c70007b4 100644 --- a/src/lib/content-disposition.ts +++ b/src/lib/content-disposition.ts @@ -44,11 +44,12 @@ export class ContentDisposition implements HeaderValue { } toString(): string { - let parts = []; - - if (this.type) { - parts.push(this.type); + if (!this.type) { + return ''; } + + let parts = [this.type]; + if (this.name) { parts.push(`name=${quote(this.name)}`); } diff --git a/src/lib/content-type.spec.ts b/src/lib/content-type.spec.ts index 187243b550c..1e6ce1aa17d 100644 --- a/src/lib/content-type.spec.ts +++ b/src/lib/content-type.spec.ts @@ -50,6 +50,12 @@ describe('ContentType', () => { assert.equal(header.toString(), 'text/plain; charset=utf-8'); }); + it('converts to an empty string when media type is not set', () => { + let header = new ContentType(); + header.charset = 'utf-8'; + assert.equal(header.toString(), ''); + }); + it('handles multiple attributes', () => { let header = new ContentType('multipart/form-data; boundary="abc123"; charset=utf-8'); assert.equal(header.mediaType, 'multipart/form-data'); diff --git a/src/lib/content-type.ts b/src/lib/content-type.ts index 9a7882366d5..4148ee069db 100644 --- a/src/lib/content-type.ts +++ b/src/lib/content-type.ts @@ -26,11 +26,12 @@ export class ContentType implements HeaderValue { } toString(): string { - let parts = []; - - if (this.mediaType) { - parts.push(this.mediaType); + if (!this.mediaType) { + return ''; } + + let parts = [this.mediaType]; + if (this.charset) { parts.push(`charset=${quote(this.charset)}`); } diff --git a/src/lib/set-cookie.spec.ts b/src/lib/set-cookie.spec.ts index cf2ca1e1509..0980e5e40d1 100644 --- a/src/lib/set-cookie.spec.ts +++ b/src/lib/set-cookie.spec.ts @@ -5,156 +5,162 @@ import { SetCookie } from './set-cookie.js'; describe('SetCookie', () => { it('parses initial value correctly', () => { - let setCookie = new SetCookie( + let header = new SetCookie( 'session=abc123; Domain=example.com; Path=/; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly' ); - assert.equal(setCookie.name, 'session'); - assert.equal(setCookie.value, 'abc123'); - assert.equal(setCookie.domain, 'example.com'); - assert.equal(setCookie.path, '/'); - assert.equal(setCookie.expires?.toUTCString(), 'Wed, 21 Oct 2015 07:28:00 GMT'); - assert.equal(setCookie.secure, true); - assert.equal(setCookie.httpOnly, true); + assert.equal(header.name, 'session'); + assert.equal(header.value, 'abc123'); + assert.equal(header.domain, 'example.com'); + assert.equal(header.path, '/'); + assert.equal(header.expires?.toUTCString(), 'Wed, 21 Oct 2015 07:28:00 GMT'); + assert.equal(header.secure, true); + assert.equal(header.httpOnly, true); }); it('handles cookies without attributes', () => { - let setCookie = new SetCookie('user=john'); - assert.equal(setCookie.name, 'user'); - assert.equal(setCookie.value, 'john'); + let header = new SetCookie('user=john'); + assert.equal(header.name, 'user'); + assert.equal(header.value, 'john'); }); it('initializes with an empty string', () => { - let setCookie = new SetCookie(''); - assert.equal(setCookie.name, undefined); - assert.equal(setCookie.value, undefined); + let header = new SetCookie(''); + assert.equal(header.name, undefined); + assert.equal(header.value, undefined); }); it('handles cookie values with commas', () => { - let setCookie = new SetCookie('list=apple,banana,cherry; Domain=example.com'); - assert.equal(setCookie.name, 'list'); - assert.equal(setCookie.value, 'apple,banana,cherry'); - assert.equal(setCookie.domain, 'example.com'); + let header = new SetCookie('list=apple,banana,cherry; Domain=example.com'); + assert.equal(header.name, 'list'); + assert.equal(header.value, 'apple,banana,cherry'); + assert.equal(header.domain, 'example.com'); }); it('handles cookie values with semicolons', () => { - let setCookie = new SetCookie('complex="value; with; semicolons"; Path=/'); - assert.equal(setCookie.name, 'complex'); - assert.equal(setCookie.value, 'value; with; semicolons'); - assert.equal(setCookie.path, '/'); + let header = new SetCookie('complex="value; with; semicolons"; Path=/'); + assert.equal(header.name, 'complex'); + assert.equal(header.value, 'value; with; semicolons'); + assert.equal(header.path, '/'); }); it('handles cookie values with equals signs', () => { - let setCookie = new SetCookie('equation="1+1=2"; Secure'); - assert.equal(setCookie.name, 'equation'); - assert.equal(setCookie.value, '1+1=2'); - assert.equal(setCookie.secure, true); + let header = new SetCookie('equation="1+1=2"; Secure'); + assert.equal(header.name, 'equation'); + assert.equal(header.value, '1+1=2'); + assert.equal(header.secure, true); }); it('sets and gets attributes', () => { - let setCookie = new SetCookie('test=value'); - setCookie.domain = 'example.org'; - setCookie.path = '/api'; - setCookie.maxAge = 3600; - setCookie.secure = true; - setCookie.httpOnly = true; - setCookie.sameSite = 'Strict'; - - assert.equal(setCookie.domain, 'example.org'); - assert.equal(setCookie.path, '/api'); - assert.equal(setCookie.maxAge, 3600); - assert.equal(setCookie.secure, true); - assert.equal(setCookie.httpOnly, true); - assert.equal(setCookie.sameSite, 'Strict'); + let header = new SetCookie('test=value'); + header.domain = 'example.org'; + header.path = '/api'; + header.maxAge = 3600; + header.secure = true; + header.httpOnly = true; + header.sameSite = 'Strict'; + + assert.equal(header.domain, 'example.org'); + assert.equal(header.path, '/api'); + assert.equal(header.maxAge, 3600); + assert.equal(header.secure, true); + assert.equal(header.httpOnly, true); + assert.equal(header.sameSite, 'Strict'); }); it('converts to string correctly', () => { - let setCookie = new SetCookie('session=abc123'); - setCookie.domain = 'example.com'; - setCookie.path = '/'; - setCookie.secure = true; - setCookie.httpOnly = true; - setCookie.sameSite = 'Lax'; + let header = new SetCookie('session=abc123'); + header.domain = 'example.com'; + header.path = '/'; + header.secure = true; + header.httpOnly = true; + header.sameSite = 'Lax'; assert.equal( - setCookie.toString(), + header.toString(), 'session=abc123; Domain=example.com; Path=/; Secure; HttpOnly; SameSite=Lax' ); }); + it('converts to an empty string when name is not set', () => { + let header = new SetCookie(); + header.value = 'test'; + assert.equal(header.toString(), ''); + }); + it('handles quoted values', () => { - let setCookie = new SetCookie('complex="quoted value; with semicolon"'); - assert.equal(setCookie.name, 'complex'); - assert.equal(setCookie.value, 'quoted value; with semicolon'); + let header = new SetCookie('complex="quoted value; with semicolon"'); + assert.equal(header.name, 'complex'); + assert.equal(header.value, 'quoted value; with semicolon'); }); it('parses and formats expires attribute correctly', () => { let expiresDate = new Date('Wed, 21 Oct 2015 07:28:00 GMT'); - let setCookie = new SetCookie(`test=value; Expires=${expiresDate.toUTCString()}`); - assert.equal(setCookie.expires?.toUTCString(), expiresDate.toUTCString()); + let header = new SetCookie(`test=value; Expires=${expiresDate.toUTCString()}`); + assert.equal(header.expires?.toUTCString(), expiresDate.toUTCString()); - setCookie.expires = new Date('Thu, 22 Oct 2015 07:28:00 GMT'); - assert.equal(setCookie.toString(), 'test=value; Expires=Thu, 22 Oct 2015 07:28:00 GMT'); + header.expires = new Date('Thu, 22 Oct 2015 07:28:00 GMT'); + assert.equal(header.toString(), 'test=value; Expires=Thu, 22 Oct 2015 07:28:00 GMT'); }); it('handles SameSite attribute case-insensitively', () => { - let setCookie = new SetCookie('test=value; SameSite=lax'); - assert.equal(setCookie.sameSite, 'Lax'); + let header = new SetCookie('test=value; SameSite=lax'); + assert.equal(header.sameSite, 'Lax'); - setCookie = new SetCookie('test=value; SameSite=STRICT'); - assert.equal(setCookie.sameSite, 'Strict'); + header = new SetCookie('test=value; SameSite=STRICT'); + assert.equal(header.sameSite, 'Strict'); - setCookie = new SetCookie('test=value; SameSite=NoNe'); - assert.equal(setCookie.sameSite, 'None'); + header = new SetCookie('test=value; SameSite=NoNe'); + assert.equal(header.sameSite, 'None'); }); it('handles cookies with empty value', () => { - let setCookie = new SetCookie('name='); - assert.equal(setCookie.name, 'name'); - assert.equal(setCookie.value, ''); + let header = new SetCookie('name='); + assert.equal(header.name, 'name'); + assert.equal(header.value, ''); }); it('handles multiple identical attributes', () => { - let setCookie = new SetCookie('test=value; Path=/; Path=/api'); - assert.equal(setCookie.path, '/api'); + let header = new SetCookie('test=value; Path=/; Path=/api'); + assert.equal(header.path, '/api'); }); it('ignores unknown attributes', () => { - let setCookie = new SetCookie('test=value; Unknown=something'); - assert.equal(setCookie.toString(), 'test=value'); + let header = new SetCookie('test=value; Unknown=something'); + assert.equal(header.toString(), 'test=value'); }); it('handles Max-Age as a number', () => { - let setCookie = new SetCookie('test=value; Max-Age=3600'); - assert.equal(setCookie.maxAge, 3600); + let header = new SetCookie('test=value; Max-Age=3600'); + assert.equal(header.maxAge, 3600); }); it('ignores invalid Max-Age', () => { - let setCookie = new SetCookie('test=value; Max-Age=invalid'); - assert.equal(setCookie.maxAge, undefined); + let header = new SetCookie('test=value; Max-Age=invalid'); + assert.equal(header.maxAge, undefined); }); it('handles missing value in attributes', () => { - let setCookie = new SetCookie('test=value; Domain=; Path'); - assert.equal(setCookie.domain, ''); - assert.equal(setCookie.path, undefined); + let header = new SetCookie('test=value; Domain=; Path'); + assert.equal(header.domain, ''); + assert.equal(header.path, undefined); }); it('preserves the case of the cookie name and value', () => { - let setCookie = new SetCookie('TestName=TestValue'); - assert.equal(setCookie.name, 'TestName'); - assert.equal(setCookie.value, 'TestValue'); + let header = new SetCookie('TestName=TestValue'); + assert.equal(header.name, 'TestName'); + assert.equal(header.value, 'TestValue'); }); it('handles setting new name and value', () => { - let setCookie = new SetCookie('old=value'); - setCookie.name = 'new'; - setCookie.value = 'newvalue'; - assert.equal(setCookie.toString(), 'new=newvalue'); + let header = new SetCookie('old=value'); + header.name = 'new'; + header.value = 'newvalue'; + assert.equal(header.toString(), 'new=newvalue'); }); it('correctly quotes values when necessary', () => { - let setCookie = new SetCookie('test=value'); - setCookie.value = 'need; quotes'; - assert.equal(setCookie.toString(), 'test="need; quotes"'); + let header = new SetCookie('test=value'); + header.value = 'need; quotes'; + assert.equal(header.toString(), 'test="need; quotes"'); }); }); diff --git a/src/lib/set-cookie.ts b/src/lib/set-cookie.ts index 000d99be5a5..0758c860eb9 100644 --- a/src/lib/set-cookie.ts +++ b/src/lib/set-cookie.ts @@ -65,11 +65,12 @@ export class SetCookie implements HeaderValue { } toString(): string { - let parts = []; - - if (this.name) { - parts.push(`${this.name}=${quote(this.value || '')}`); + if (!this.name) { + return ''; } + + let parts = [`${this.name}=${quote(this.value || '')}`]; + if (this.domain) { parts.push(`Domain=${this.domain}`); } From b4bb6f519d6a590fde87b8d08be25a401ed3c043 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 08:43:00 -0700 Subject: [PATCH 024/730] Improve test --- src/lib/super-headers.spec.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/lib/super-headers.spec.ts b/src/lib/super-headers.spec.ts index d948b18ec84..254823e2b4a 100644 --- a/src/lib/super-headers.spec.ts +++ b/src/lib/super-headers.spec.ts @@ -248,16 +248,14 @@ describe('SuperHeaders', () => { describe('toString', () => { it('omits empty values when stringified', () => { let headers = new SuperHeaders(); - headers.set('X-Test', 'value'); - headers.contentDisposition = ''; - headers.contentType = ''; - headers.cookie = ''; - - let result = headers.toString(); - assert.equal(result, 'X-Test: value'); - assert.ok(!result.includes('Content-Disposition')); - assert.ok(!result.includes('Content-Type')); - assert.ok(!result.includes('Cookie')); + + // This should appear in the string since it has a media type, it's complete + headers.contentType = 'text/plain'; + + // This should not appear in the string since it's incomplete, missing the type + headers.contentDisposition.filename = 'example.txt'; + + assert.equal(headers.toString(), 'Content-Type: text/plain'); }); }); }); From 9f3c063e0a41173c09f201c87552b7200dc2818d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 08:47:11 -0700 Subject: [PATCH 025/730] Small tweak in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fe80f93bea2..c43bad8423d 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ header block: ```ts let headers = new SuperHeaders(); -headers.set('content-type', 'text/html'); // or headers.contentType = 'text/html' +headers.set('Content-Type', 'text/html'); // or headers.contentType = 'text/html' headers.set('X-Custom-Header', 'value'); console.log(headers.toString()); From 1acbea11bcdd98ff4c544d108b0966a5d24898d7 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 08:56:09 -0700 Subject: [PATCH 026/730] Update README --- README.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c43bad8423d..7d0219709d2 100644 --- a/README.md +++ b/README.md @@ -110,14 +110,24 @@ console.log(headers.toString()); // get [object Headers] from toString(). ``` -In addition to the high-level API, fetch-super-headers also exposes all of the low-level parsers it uses for each individual HTTP -header as public API, so you can use them in your own projects easily. +In addition to the high-level API, fetch-super-headers also provides a rich set of primitives you can use +to work with just about any complex HTTP header value. Each header class includes a spec-compliant parser +(the constructor), stringifier (`toString`), and getters/setters for all relevant attributes. Classes for +headers that contain a list of fields, like `Cookie`, are iterable. ```ts -import { ContentType } from 'fetch-super-headers'; +import { ContentType, Cookie } from 'fetch-super-headers'; let contentType = new ContentType('text/html; charset=utf-8'); console.log(contentType.charset); + +let cookie = new Cookie(); +cookie.set('theme', 'dark'); +cookie.set('session_id', '123'); + +for (let [key, value] of cookie) { + // ... +} ``` ## Contributing From 726211da24d0c2658a742cbf7430b842d0f8bb0d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 08:56:42 -0700 Subject: [PATCH 027/730] Version 0.3.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 56141f996fe..bd9141c1cf3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fetch-super-headers", - "version": "0.3.1", + "version": "0.3.2", "description": "JavaScript Headers, with superpowers", "author": "Michael Jackson ", "license": "MIT", From fabd3c02d77db0eb7be44891f4a31ffcd31f8975 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 09:21:55 -0700 Subject: [PATCH 028/730] Update README with Set-Cookie example --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index 7d0219709d2..51cfffb0ceb 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,31 @@ console.log(headers.cookie.get('user_id')); // '12345' headers.cookie.set('theme', 'dark'); console.log(headers.get('Cookie')); // 'session_id=abc123; user_id=12345; theme=dark' + +// Set-Cookie +headers.setCookie = 'session_id=abc123; Path=/; HttpOnly'; + +console.log(headers.setCookie.name); // 'session_id' +console.log(headers.setCookie.value); // 'abc123' +console.log(headers.setCookie.path); // '/' +console.log(headers.setCookie.httpOnly); // true + +// Modifying Set-Cookie attributes +headers.setCookie.maxAge = 3600; +headers.setCookie.secure = true; + +console.log(headers.get('Set-Cookie')); +// session_id=abc123; Path=/; HttpOnly; Max-Age=3600; Secure + +// Setting multiple cookies +headers.append('Set-Cookie', 'user_id=12345; Path=/api; Secure'); + +// Accessing multiple Set-Cookie headers +for (let cookie of headers.getSetCookie()) { + console.log(cookie); +} +// session_id=abc123; Path=/; HttpOnly; Max-Age=3600; Secure +// user_id=12345; Path=/api; Secure ``` You can easily build `SuperHeaders` from an exising `Headers` object, like the one you get in a `fetch` response: From 447e5d647e18b2710fa0826787279f1b429b89e6 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 09:36:07 -0700 Subject: [PATCH 029/730] Rename to fetch-multipart-parser --- README.md | 15 ++++++++++----- package.json | 6 ++++-- src/lib/multipart.ts | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f6ce321252f..4369c3d0dcb 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,17 @@ -# multipart-web-stream +# fetch-multipart-parser -This is a streaming multipart parser for JavaScript with no dependencies. +`fetch-multipart-parser` is a streaming multipart parser for JavaScript's fetch API. ## Installation ```sh -$ npm install multipart-web-stream +$ npm install fetch-multipart-parser ``` ## Usage ```typescript -import { parseMultipartFormData, MultipartParseError } from 'multipart-web-stream'; +import { parseMultipartFormData, MultipartParseError } from 'fetch-multipart-parser'; function handleMultipartRequest(request: Request): void { try { @@ -20,7 +20,12 @@ function handleMultipartRequest(request: Request): void { console.log(part.name); console.log(part.filename); console.log(part.contentType); - console.log(new TextDecoder().decode(part.content)); + + if (/^text\//.test(part.contentType)) { + console.log(new TextDecoder().decode(part.content)); + } else { + // part.content is binary data, save it to a file + } } } catch (error) { if (error instanceof MultipartParseError) { diff --git a/package.json b/package.json index 8eca9fe5bc6..e4dbb892a10 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,14 @@ { - "name": "multipart-web-stream", + "name": "fetch-multipart-parser", "version": "0.1.0", "description": "A multipart parser for fetch streams", "scripts": { "build": "pnpm run build:cjs && pnpm run build:esm", "build:cjs": "tsc --outDir dist --project tsconfig.lib.json", "build:esm": "esbuild src/index.ts --bundle --format=esm --target=node16 --outfile=dist/index.mjs", - "test": "node --import tsimp/import --test ./src/**/*.spec.ts" + "test": "node --import tsimp/import --test ./src/**/*.spec.ts", + "prepare": "pnpm run build", + "prepublishOnly": "pnpm run test" }, "exports": { ".": { diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 05b1aab6660..b29aa1175f1 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -122,7 +122,7 @@ const findDoubleCRLF = createSeqFinder(textEncoder.encode(CRLF + CRLF)); * Example: * * ```typescript - * import { parseMultipartFormData, MultipartParseError } from 'multipart-web-stream'; + * import { parseMultipartFormData, MultipartParseError } from 'fetch-multipart-parser'; * * function handleMultipartRequest(request: Request): void { * try { From c9f6eaaaebbb9870ab1d43ee86b8aa89cc0ddb52 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 09:38:23 -0700 Subject: [PATCH 030/730] Small README tweak --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4369c3d0dcb..c53263361ee 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ $ npm install fetch-multipart-parser ## Usage ```typescript -import { parseMultipartFormData, MultipartParseError } from 'fetch-multipart-parser'; +import { MultipartParseError, parseMultipartFormData } from 'fetch-multipart-parser'; function handleMultipartRequest(request: Request): void { try { From 0459a13ed098e016466c655783b2008ea331d7a5 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 10:01:30 -0700 Subject: [PATCH 031/730] Use SuperHeaders internally --- package.json | 3 + pnpm-lock.yaml | 9 +++ src/lib/multipart.spec.ts | 6 +- src/lib/multipart.ts | 125 +++++++------------------------------- 4 files changed, 36 insertions(+), 107 deletions(-) diff --git a/package.json b/package.json index e4dbb892a10..83141501cc9 100644 --- a/package.json +++ b/package.json @@ -26,5 +26,8 @@ "esbuild": "^0.23.0", "tsimp": "^2.0.11", "typescript": "^5.5.3" + }, + "dependencies": { + "fetch-super-headers": "^0.3.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c08d4393129..c7c352e7175 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,10 @@ settings: importers: .: + dependencies: + fetch-super-headers: + specifier: ^0.3.2 + version: 0.3.2 devDependencies: '@types/node': specifier: ^20.14.10 @@ -231,6 +235,9 @@ packages: engines: {node: '>=18'} hasBin: true + fetch-super-headers@0.3.2: + resolution: {integrity: sha512-bq+upFu2iaEMjJs7zS9k8cABlLU3TBQgbWxA1rZUNDzzYdDGi6q9KdHcYADzCi7OJ7eIKowxjBVUTOcYQEO7bQ==} + foreground-child@3.2.1: resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} engines: {node: '>=14'} @@ -509,6 +516,8 @@ snapshots: '@esbuild/win32-ia32': 0.23.0 '@esbuild/win32-x64': 0.23.0 + fetch-super-headers@0.3.2: {} + foreground-child@3.2.1: dependencies: cross-spawn: 7.0.3 diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 81223b2cd91..565869caf4e 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -116,7 +116,7 @@ describe('parseMultipartFormData', async () => { assert.equal(parts.length, 1); assert.equal(parts[0].name, 'file1'); assert.equal(parts[0].filename, 'test.txt'); - assert.equal(parts[0].contentType, 'text/plain'); + assert.equal(parts[0].mediaType, 'text/plain'); assert.equal(new TextDecoder().decode(parts[0].content), 'File content here'); }); @@ -153,7 +153,7 @@ describe('parseMultipartFormData', async () => { assert.equal(new TextDecoder().decode(parts[1].content), 'value2'); assert.equal(parts[2].name, 'file1'); assert.equal(parts[2].filename, 'test.txt'); - assert.equal(parts[2].contentType, 'text/plain'); + assert.equal(parts[2].mediaType, 'text/plain'); assert.equal(new TextDecoder().decode(parts[2].content), 'File content here'); }); @@ -299,7 +299,5 @@ describe('parseMultipartFormData', async () => { assert.equal(parts.length, 1); assert.equal(parts[0].name, 'file'); assert.equal(parts[0].filename, 'encoded filename.txt'); - assert.equal(parts[0].contentDisposition.filename, 'name with spaces.txt'); - assert.equal(parts[0].contentDisposition.filenameSplat, "utf-8''encoded%20filename.txt"); }); }); diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index b29aa1175f1..16c29765348 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -1,3 +1,5 @@ +import { SuperHeaders } from 'fetch-super-headers'; + const CRLF = '\r\n'; const DefaultMaxHeaderSize = 1024 * 1024; // 1 MB @@ -10,93 +12,19 @@ export class MultipartParseError extends Error { } } -export interface ContentDisposition { - type: string | null; - name: string | null; - filename: string | null; - filenameSplat: string | null; - creationDate: Date | null; - modificationDate: Date | null; - readDate: Date | null; - size: number | null; -} - export class MultipartPart { - private _parsedContentDisposition: ContentDisposition | null = null; - - constructor(public headers: Headers, public content: Uint8Array) {} - - get contentDisposition(): ContentDisposition { - if (this._parsedContentDisposition) { - return this._parsedContentDisposition; - } - - let header = this.headers.get('Content-Disposition'); - if (!header) { - return (this._parsedContentDisposition = { - type: null, - name: null, - filename: null, - filenameSplat: null, - creationDate: null, - modificationDate: null, - readDate: null, - size: null, - }); - } - - let parts = header.split(';').map((part) => part.trim()); - let type = parts.shift() || null; - let params: { [key: string]: string } = {}; - - for (let part of parts) { - let [key, value] = part.split('='); - if (key && value) { - params[key.toLowerCase()] = value.replace(/^["']|["']$/g, ''); - } - } - - return (this._parsedContentDisposition = { - type, - name: params['name'] || null, - filename: params['filename'] || null, - filenameSplat: params['filename*'] || null, - creationDate: params['creation-date'] ? new Date(params['creation-date']) : null, - modificationDate: params['modification-date'] ? new Date(params['modification-date']) : null, - readDate: params['read-date'] ? new Date(params['read-date']) : null, - size: params['size'] ? parseInt(params['size'], 10) : null, - }); - } - - get contentType(): string | null { - return this.headers.get('Content-Type') || null; - } + constructor(public headers: SuperHeaders, public content: Uint8Array) {} get filename(): string | null { - if (this.contentDisposition.filenameSplat) { - try { - let [encodingPart, _languagePart, ...filenameParts] = - this.contentDisposition.filenameSplat.split("'"); - let encoding = encodingPart.toLowerCase(); - let encodedFilename = filenameParts.join("'"); - - let filename = decodeURIComponent(encodedFilename.replace(/%([0-9A-Fa-f]{2})/g, '%$1')); - - if (encoding !== 'utf-8') { - console.warn(`Unsupported encoding: ${encoding}. Treating as UTF-8.`); - } - - return filename; - } catch (error) { - throw new Error(`Failed to decode internationalized filename*: ${error}`); - } - } + return this.headers.contentDisposition.preferredFilename || null; + } - return this.contentDisposition.filename; + get mediaType(): string | null { + return this.headers.contentType.mediaType || null; } get name(): string | null { - return this.contentDisposition.name; + return this.headers.contentDisposition.name || null; } } @@ -115,14 +43,14 @@ const textDecoder = new TextDecoder(); const findDoubleCRLF = createSeqFinder(textEncoder.encode(CRLF + CRLF)); /** - * Parses a `multipart/form-data` request body and yields each part as a `MultipartPart` object. + * Parse a `multipart/form-data` request body and yield each part as a `MultipartPart` object. * - * Throws `MultipartParseError` if the parse fails for some reason. + * Throw `MultipartParseError` if the parse fails for some reason. * * Example: * * ```typescript - * import { parseMultipartFormData, MultipartParseError } from 'fetch-multipart-parser'; + * import { MultipartParseError, parseMultipartFormData } from 'fetch-multipart-parser'; * * function handleMultipartRequest(request: Request): void { * try { @@ -130,7 +58,12 @@ const findDoubleCRLF = createSeqFinder(textEncoder.encode(CRLF + CRLF)); * console.log(part.name); * console.log(part.filename); * console.log(part.contentType); - * console.log(new TextDecoder().decode(part.content)); + * + * if (/^text\//.test(part.contentType)) { + * console.log(new TextDecoder().decode(part.content)); + * } else { + * // part.content is binary data, save it to a file + * } * } * } catch (error) { * if (error instanceof MultipartParseError) { @@ -167,9 +100,9 @@ export async function* parseMultipartFormData( } /** - * Parses a multipart stream and yields each part as a `MultipartPart` object. + * Parse a multipart stream and yield each part as a `MultipartPart` object. * - * Throws `MultipartParseError` if the parse fails for some reason. + * Throw `MultipartParseError` if the parse fails for some reason. * * Note: This is a low-level function that requires manually handling the stream and boundary. For most common use cases, * consider using `parseMultipartFormData(request)` instead. @@ -219,7 +152,7 @@ export async function* parseMultipartStream( let partData = buffer.subarray(0, boundaryIndex - 2); // -2 to remove \r\n before boundary let headerEndIndex = findDoubleCRLF(partData); - let headers: Headers; + let headers: SuperHeaders; let content: Uint8Array; if (headerEndIndex !== -1) { if (headerEndIndex > maxHeaderSize) { @@ -228,11 +161,11 @@ export async function* parseMultipartStream( ); } - headers = parseHeaders(partData.subarray(0, headerEndIndex)); + headers = new SuperHeaders(textDecoder.decode(partData.subarray(0, headerEndIndex))); content = partData.subarray(headerEndIndex + 4); // +4 to remove \r\n\r\n after headers } else { // No headers found, treat entire part as content - headers = new Headers(); + headers = new SuperHeaders(); content = partData; } @@ -266,20 +199,6 @@ export async function* parseMultipartStream( } } -function parseHeaders(headerData: Uint8Array): Headers { - let headers = new Headers(); - - let lines = textDecoder.decode(headerData).split(CRLF); - for (let line of lines) { - let [key, value] = line.split(':').map((s) => s.trim()); - if (key && value) { - headers.append(key, value); - } - } - - return headers; -} - function createSeqFinder(needle: Uint8Array): (haystack: Uint8Array, offset?: number) => number { let skipTable = new Map(); for (let i = 0; i < needle.length - 1; i++) { From 29fb9d3747061459a6bf1bd19414a218c305e2fc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 10:52:07 -0700 Subject: [PATCH 032/730] Fix example --- README.md | 4 ++-- src/lib/multipart.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c53263361ee..c94370e7dd4 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,9 @@ function handleMultipartRequest(request: Request): void { for await (let part of parseMultipartFormData(request)) { console.log(part.name); console.log(part.filename); - console.log(part.contentType); + console.log(part.mediaType); - if (/^text\//.test(part.contentType)) { + if (/^text\//.test(part.mediaType)) { console.log(new TextDecoder().decode(part.content)); } else { // part.content is binary data, save it to a file diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 16c29765348..f8364922dfc 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -57,9 +57,9 @@ const findDoubleCRLF = createSeqFinder(textEncoder.encode(CRLF + CRLF)); * for await (let part of parseMultipartFormData(request)) { * console.log(part.name); * console.log(part.filename); - * console.log(part.contentType); + * console.log(part.mediaType); * - * if (/^text\//.test(part.contentType)) { + * if (/^text\//.test(part.mediaType)) { * console.log(new TextDecoder().decode(part.content)); * } else { * // part.content is binary data, save it to a file From fb3301551a101585e538ca34e2e9bec81293ec2f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 12:15:53 -0700 Subject: [PATCH 033/730] Update description/docs --- README.md | 23 +++++++---------------- src/lib/super-headers.ts | 14 +++++++++++++- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 51cfffb0ceb..27507a4dcd3 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ # fetch-super-headers -fetch-super-headers is JavaScript `Headers`, with superpowers. +`SuperHeaders` is a drop-in replacement for JavaScript's `Headers` with type-safe access to common headers. ## Key Features This package is a suite of tools that make it a little more fun to work with `Headers`. -- Drop-in replacement for [the standard `Headers` object](https://developer.mozilla.org/en-US/docs/Web/API/Headers) -- Strongly typed header-specific getters and setters (e.g., `contentType`, `cookie`) -- Easy parsing and manipulation of complex headers like Content-Type and Content-Disposition +- Drop-in replacement for [the standard `Headers` class](https://developer.mozilla.org/en-US/docs/Web/API/Headers) +- Strongly typed header-specific getters and setters (e.g., `headers.contentType`, `headers.setCookie`, etc.) +- Easy parsing and manipulation of complex headers like `Content-Disposition`, `Content-Type`, `Set-Cookie`, and more - Iterable interface for easy header enumeration - Convenient string conversion for HTTP message parsing and assembly @@ -20,8 +20,7 @@ $ npm install fetch-super-headers ## Usage -fetch-super-headers is designed to be a drop-in replacement for `Headers`, with some additions that make working with HTTP -headers feel a lot more like working with JavaScript objects. +fetch-super-headers is designed to be a drop-in replacement for `Headers`, with some additions that make working with HTTP headers feel a lot more like working with JavaScript objects. ```ts import SuperHeaders from 'fetch-super-headers'; @@ -119,8 +118,7 @@ for (let [name, value] of headers) { // Accept-Language: en-US,en;q=0.9 ``` -If you're assembling HTTP messages, you can easily convert to a multiline string suitable for using as a Request/Response -header block: +If you're assembling HTTP messages, you can easily convert to a multiline string suitable for using as a Request/Response header block: ```ts let headers = new SuperHeaders(); @@ -135,10 +133,7 @@ console.log(headers.toString()); // get [object Headers] from toString(). ``` -In addition to the high-level API, fetch-super-headers also provides a rich set of primitives you can use -to work with just about any complex HTTP header value. Each header class includes a spec-compliant parser -(the constructor), stringifier (`toString`), and getters/setters for all relevant attributes. Classes for -headers that contain a list of fields, like `Cookie`, are iterable. +In addition to the high-level API, fetch-super-headers also provides a rich set of primitives you can use to work with just about any complex HTTP header value. Each header class includes a spec-compliant parser (the constructor), stringifier (`toString`), and getters/setters for all relevant attributes. Classes for headers that contain a list of fields, like `Cookie`, are iterable. ```ts import { ContentType, Cookie } from 'fetch-super-headers'; @@ -155,10 +150,6 @@ for (let [key, value] of cookie) { } ``` -## Contributing - -Contributions are welcome! Please feel free to submit a Pull Request. Make sure to follow the existing coding style and add tests for any new functionality. - ## License MIT License diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index b7a646eb3ed..6bd872dac6c 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -16,7 +16,19 @@ export type SuperHeadersInit = | Record; /** - * A Headers object, with superpowers. + * A drop-in replacement for JavaScript's `Headers` with type-safe access to common headers. + * + * @example + * + * ```ts + * let headers = new SuperHeaders(); + * headers.contentType = 'text/plain; charset=utf-8'; + * headers.contentType.mediaType; // 'text/plain' + * headers.contentType.charset; // 'utf-8' + * + * headers.contentType.mediaType = 'text/html'; + * headers.get('Content-Type'); // 'text/html; charset=utf-8' + * ``` */ export class SuperHeaders extends Headers implements Iterable<[string, string]> { private map: Map; From fd8804f001c85073117b79bd22664fe7ca2786d1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 12:20:41 -0700 Subject: [PATCH 034/730] Update description --- README.md | 4 +++- package.json | 2 +- src/lib/super-headers.ts | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 27507a4dcd3..09dbaa20972 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # fetch-super-headers -`SuperHeaders` is a drop-in replacement for JavaScript's `Headers` with type-safe access to common headers. +`SuperHeaders` is a drop-in replacement for JavaScript `Headers` with type-safe access. + +Another way to think about it is a spec-compliant, type-safe way to parse, modify, and stringify various HTTP headers and collections of them. ## Key Features diff --git a/package.json b/package.json index bd9141c1cf3..d69d7251b61 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "fetch-super-headers", "version": "0.3.2", - "description": "JavaScript Headers, with superpowers", + "description": "A drop-in replacement for JavaScript Headers with type-safe access", "author": "Michael Jackson ", "license": "MIT", "files": [ diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index 6bd872dac6c..8512bb7a086 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -16,7 +16,7 @@ export type SuperHeadersInit = | Record; /** - * A drop-in replacement for JavaScript's `Headers` with type-safe access to common headers. + * A drop-in replacement for JavaScript `Headers` with type-safe access. * * @example * From 4627ba100edd17991c97ab1f81f07ebcb232af07 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 12:23:24 -0700 Subject: [PATCH 035/730] Restrict package files --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 83141501cc9..6a192bf2069 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,10 @@ "prepare": "pnpm run build", "prepublishOnly": "pnpm run test" }, + "files": [ + "dist", + "README.md" + ], "exports": { ".": { "types": "./dist/index.d.ts", From 0af518939bd7277cebfa3fe96ac9c3761b773e5c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 12:24:04 -0700 Subject: [PATCH 036/730] Version 0.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6a192bf2069..65d6bf7c8d8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fetch-multipart-parser", - "version": "0.1.0", + "version": "0.2.0", "description": "A multipart parser for fetch streams", "scripts": { "build": "pnpm run build:cjs && pnpm run build:esm", From 4e608b5dd95059105cf3cbdbd8e00b76c162163e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 14:10:38 -0700 Subject: [PATCH 037/730] Slightly better JSDoc --- src/lib/multipart.ts | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index f8364922dfc..6d3eafcdeac 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -12,22 +12,37 @@ export class MultipartParseError extends Error { } } +/** + * Represents a part of a `multipart/form-data` request. + */ export class MultipartPart { constructor(public headers: SuperHeaders, public content: Uint8Array) {} + /** + * The filename of the part, if it is a file upload. + */ get filename(): string | null { return this.headers.contentDisposition.preferredFilename || null; } + /** + * The media type of the part. + */ get mediaType(): string | null { return this.headers.contentType.mediaType || null; } + /** + * The name of the part, usually the `name` of the field in the `
` that submitted the request. + */ get name(): string | null { return this.headers.contentDisposition.name || null; } } +/** + * Returns true if the request is `multipart/form-data`. + */ export function isMultipartFormData(request: Request): boolean { let contentType = request.headers.get('Content-Type'); return contentType != null && contentType.startsWith('multipart/form-data'); @@ -74,9 +89,6 @@ const findDoubleCRLF = createSeqFinder(textEncoder.encode(CRLF + CRLF)); * } * } * ``` - * - * @param request - * @param options */ export async function* parseMultipartFormData( request: Request, @@ -106,10 +118,6 @@ export async function* parseMultipartFormData( * * Note: This is a low-level function that requires manually handling the stream and boundary. For most common use cases, * consider using `parseMultipartFormData(request)` instead. - * - * @param boundary - * @param stream - * @param options */ export async function* parseMultipartStream( boundary: string, From f11e68f48647011140edc667651fd3f8b1b6c96d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 14:11:22 -0700 Subject: [PATCH 038/730] 0.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 65d6bf7c8d8..0f45fe3b3be 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fetch-multipart-parser", - "version": "0.2.0", + "version": "0.2.1", "description": "A multipart parser for fetch streams", "scripts": { "build": "pnpm run build:cjs && pnpm run build:esm", From a92568522b15a9fb94a833013250a58884de10e9 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 16:01:37 -0700 Subject: [PATCH 039/730] Provide only ESM --- package.json | 20 ++-- pnpm-lock.yaml | 251 --------------------------------------------- tsconfig.json | 10 +- tsconfig.spec.json | 3 +- 4 files changed, 9 insertions(+), 275 deletions(-) diff --git a/package.json b/package.json index d69d7251b61..3b6674787b2 100644 --- a/package.json +++ b/package.json @@ -8,27 +8,21 @@ "dist", "README.md" ], + "type": "module", "exports": { - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.mjs", - "require": "./dist/index.js", - "default": "./dist/index.js" - }, + ".": "./dist/index.js", "./package.json": "./package.json" }, "scripts": { - "build": "pnpm run build:cjs && pnpm run build:esm", - "build:cjs": "tsc --outDir dist --project tsconfig.lib.json", - "build:esm": "esbuild src/index.ts --bundle --format=esm --target=node16 --outfile=dist/index.mjs", + "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "prepublishOnly": "pnpm run test" + "prepare": "npm run build", + "prepublishOnly": "npm run test" }, "devDependencies": { "@types/node": "^20.14.10", - "esbuild": "^0.23.0", "tsimp": "^2.0.11", "typescript": "^5.5.3" - } + }, + "packageManager": "pnpm@9.4.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f78a2e8d200..a9d23a6c359 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,9 +11,6 @@ importers: '@types/node': specifier: ^20.14.10 version: 20.14.10 - esbuild: - specifier: ^0.23.0 - version: 0.23.0 tsimp: specifier: ^2.0.11 version: 2.0.11(typescript@5.5.3) @@ -23,150 +20,6 @@ importers: packages: - '@esbuild/aix-ppc64@0.23.0': - resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.23.0': - resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.23.0': - resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.23.0': - resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.23.0': - resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.23.0': - resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.23.0': - resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.23.0': - resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.23.0': - resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.23.0': - resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.23.0': - resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.23.0': - resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.23.0': - resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.23.0': - resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.23.0': - resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.23.0': - resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.23.0': - resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-x64@0.23.0': - resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.23.0': - resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.23.0': - resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/sunos-x64@0.23.0': - resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.23.0': - resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.23.0': - resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.23.0': - resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - '@isaacs/cached@1.0.1': resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} @@ -226,11 +79,6 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - esbuild@0.23.0: - resolution: {integrity: sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==} - engines: {node: '>=18'} - hasBin: true - foreground-child@3.2.1: resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} engines: {node: '>=14'} @@ -353,78 +201,6 @@ packages: snapshots: - '@esbuild/aix-ppc64@0.23.0': - optional: true - - '@esbuild/android-arm64@0.23.0': - optional: true - - '@esbuild/android-arm@0.23.0': - optional: true - - '@esbuild/android-x64@0.23.0': - optional: true - - '@esbuild/darwin-arm64@0.23.0': - optional: true - - '@esbuild/darwin-x64@0.23.0': - optional: true - - '@esbuild/freebsd-arm64@0.23.0': - optional: true - - '@esbuild/freebsd-x64@0.23.0': - optional: true - - '@esbuild/linux-arm64@0.23.0': - optional: true - - '@esbuild/linux-arm@0.23.0': - optional: true - - '@esbuild/linux-ia32@0.23.0': - optional: true - - '@esbuild/linux-loong64@0.23.0': - optional: true - - '@esbuild/linux-mips64el@0.23.0': - optional: true - - '@esbuild/linux-ppc64@0.23.0': - optional: true - - '@esbuild/linux-riscv64@0.23.0': - optional: true - - '@esbuild/linux-s390x@0.23.0': - optional: true - - '@esbuild/linux-x64@0.23.0': - optional: true - - '@esbuild/netbsd-x64@0.23.0': - optional: true - - '@esbuild/openbsd-arm64@0.23.0': - optional: true - - '@esbuild/openbsd-x64@0.23.0': - optional: true - - '@esbuild/sunos-x64@0.23.0': - optional: true - - '@esbuild/win32-arm64@0.23.0': - optional: true - - '@esbuild/win32-ia32@0.23.0': - optional: true - - '@esbuild/win32-x64@0.23.0': - optional: true - '@isaacs/cached@1.0.1': dependencies: '@isaacs/catcher': 1.0.4 @@ -481,33 +257,6 @@ snapshots: emoji-regex@9.2.2: {} - esbuild@0.23.0: - optionalDependencies: - '@esbuild/aix-ppc64': 0.23.0 - '@esbuild/android-arm': 0.23.0 - '@esbuild/android-arm64': 0.23.0 - '@esbuild/android-x64': 0.23.0 - '@esbuild/darwin-arm64': 0.23.0 - '@esbuild/darwin-x64': 0.23.0 - '@esbuild/freebsd-arm64': 0.23.0 - '@esbuild/freebsd-x64': 0.23.0 - '@esbuild/linux-arm': 0.23.0 - '@esbuild/linux-arm64': 0.23.0 - '@esbuild/linux-ia32': 0.23.0 - '@esbuild/linux-loong64': 0.23.0 - '@esbuild/linux-mips64el': 0.23.0 - '@esbuild/linux-ppc64': 0.23.0 - '@esbuild/linux-riscv64': 0.23.0 - '@esbuild/linux-s390x': 0.23.0 - '@esbuild/linux-x64': 0.23.0 - '@esbuild/netbsd-x64': 0.23.0 - '@esbuild/openbsd-arm64': 0.23.0 - '@esbuild/openbsd-x64': 0.23.0 - '@esbuild/sunos-x64': 0.23.0 - '@esbuild/win32-arm64': 0.23.0 - '@esbuild/win32-ia32': 0.23.0 - '@esbuild/win32-x64': 0.23.0 - foreground-child@3.2.1: dependencies: cross-spawn: 7.0.3 diff --git a/tsconfig.json b/tsconfig.json index ba16aeed449..d8aaef54f9d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,13 +4,5 @@ "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true - }, - "references": [ - { - "path": "./tsconfig.lib.json" - }, - { - "path": "./tsconfig.spec.json" - } - ] + } } diff --git a/tsconfig.spec.json b/tsconfig.spec.json index 79d1e4a027a..456f4c46cca 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -1,8 +1,7 @@ { "extends": "./tsconfig.json", - "include": ["src/**/*.ts"], + "include": ["src/**/*.spec.ts"], "compilerOptions": { - "composite": true, "types": ["node"] } } From aed5bfe08ec8ad8f6d29574472cb4951e4065992 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 16:02:09 -0700 Subject: [PATCH 040/730] 0.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3b6674787b2..a79fadec082 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fetch-super-headers", - "version": "0.3.2", + "version": "0.4.0", "description": "A drop-in replacement for JavaScript Headers with type-safe access", "author": "Michael Jackson ", "license": "MIT", From a70d66393159ece07fa2feb5913eaa2d6ff79e2c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 16:23:02 -0700 Subject: [PATCH 041/730] Use main field instead of package exports --- package.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/package.json b/package.json index a79fadec082..a1b625bb4b8 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,7 @@ "README.md" ], "type": "module", - "exports": { - ".": "./dist/index.js", - "./package.json": "./package.json" - }, + "main": "./dist/index.js", "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", From 19690cbd9045febcf2a9a5b60f55c56fea84f30b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 16:26:32 -0700 Subject: [PATCH 042/730] Add LICENSE Closes #2 --- LICENSE | 21 +++++++++++++++++++++ package.json | 1 + 2 files changed, 22 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..717984c0442 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Michael Jackson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package.json b/package.json index a1b625bb4b8..a71f0f8ab51 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "license": "MIT", "files": [ "dist", + "LICENSE", "README.md" ], "type": "module", From b1e762142d69105d622a9e8c43c55faec21cb7a9 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 16:27:33 -0700 Subject: [PATCH 043/730] Update README --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 09dbaa20972..9ad26997839 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,3 @@ for (let [key, value] of cookie) { // ... } ``` - -## License - -MIT License From c5b1111ecaab9d40a44e7f3fb18389c8614d5ca0 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 16:35:42 -0700 Subject: [PATCH 044/730] Simplify build, provide ESM only --- LICENSE | 21 +++++ package.json | 33 +++---- pnpm-lock.yaml | 251 ------------------------------------------------- tsconfig.json | 10 +- 4 files changed, 34 insertions(+), 281 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..717984c0442 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Michael Jackson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package.json b/package.json index 0f45fe3b3be..33e394a7830 100644 --- a/package.json +++ b/package.json @@ -2,36 +2,27 @@ "name": "fetch-multipart-parser", "version": "0.2.1", "description": "A multipart parser for fetch streams", - "scripts": { - "build": "pnpm run build:cjs && pnpm run build:esm", - "build:cjs": "tsc --outDir dist --project tsconfig.lib.json", - "build:esm": "esbuild src/index.ts --bundle --format=esm --target=node16 --outfile=dist/index.mjs", - "test": "node --import tsimp/import --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "prepublishOnly": "pnpm run test" - }, + "author": "Michael Jackson ", + "license": "MIT", + "type": "module", + "main": "./dist/index.js", "files": [ "dist", + "LICENSE", "README.md" ], - "exports": { - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.mjs", - "require": "./dist/index.js", - "default": "./dist/index.js" - }, - "./package.json": "./package.json" + "dependencies": { + "fetch-super-headers": "^0.3.2" }, - "author": "Michael Jackson ", - "license": "MIT", "devDependencies": { "@types/node": "^20.14.10", - "esbuild": "^0.23.0", "tsimp": "^2.0.11", "typescript": "^5.5.3" }, - "dependencies": { - "fetch-super-headers": "^0.3.2" + "scripts": { + "build": "tsc --outDir dist --project tsconfig.lib.json", + "test": "node --import tsimp/import --test ./src/**/*.spec.ts", + "prepare": "npm run build", + "prepublishOnly": "npm run test" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c7c352e7175..859f00036b7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,9 +15,6 @@ importers: '@types/node': specifier: ^20.14.10 version: 20.14.10 - esbuild: - specifier: ^0.23.0 - version: 0.23.0 tsimp: specifier: ^2.0.11 version: 2.0.11(typescript@5.5.3) @@ -27,150 +24,6 @@ importers: packages: - '@esbuild/aix-ppc64@0.23.0': - resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.23.0': - resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.23.0': - resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.23.0': - resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.23.0': - resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.23.0': - resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.23.0': - resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.23.0': - resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.23.0': - resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.23.0': - resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.23.0': - resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.23.0': - resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.23.0': - resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.23.0': - resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.23.0': - resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.23.0': - resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.23.0': - resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-x64@0.23.0': - resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.23.0': - resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.23.0': - resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/sunos-x64@0.23.0': - resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.23.0': - resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.23.0': - resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.23.0': - resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - '@isaacs/cached@1.0.1': resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} @@ -230,11 +83,6 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - esbuild@0.23.0: - resolution: {integrity: sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==} - engines: {node: '>=18'} - hasBin: true - fetch-super-headers@0.3.2: resolution: {integrity: sha512-bq+upFu2iaEMjJs7zS9k8cABlLU3TBQgbWxA1rZUNDzzYdDGi6q9KdHcYADzCi7OJ7eIKowxjBVUTOcYQEO7bQ==} @@ -361,78 +209,6 @@ packages: snapshots: - '@esbuild/aix-ppc64@0.23.0': - optional: true - - '@esbuild/android-arm64@0.23.0': - optional: true - - '@esbuild/android-arm@0.23.0': - optional: true - - '@esbuild/android-x64@0.23.0': - optional: true - - '@esbuild/darwin-arm64@0.23.0': - optional: true - - '@esbuild/darwin-x64@0.23.0': - optional: true - - '@esbuild/freebsd-arm64@0.23.0': - optional: true - - '@esbuild/freebsd-x64@0.23.0': - optional: true - - '@esbuild/linux-arm64@0.23.0': - optional: true - - '@esbuild/linux-arm@0.23.0': - optional: true - - '@esbuild/linux-ia32@0.23.0': - optional: true - - '@esbuild/linux-loong64@0.23.0': - optional: true - - '@esbuild/linux-mips64el@0.23.0': - optional: true - - '@esbuild/linux-ppc64@0.23.0': - optional: true - - '@esbuild/linux-riscv64@0.23.0': - optional: true - - '@esbuild/linux-s390x@0.23.0': - optional: true - - '@esbuild/linux-x64@0.23.0': - optional: true - - '@esbuild/netbsd-x64@0.23.0': - optional: true - - '@esbuild/openbsd-arm64@0.23.0': - optional: true - - '@esbuild/openbsd-x64@0.23.0': - optional: true - - '@esbuild/sunos-x64@0.23.0': - optional: true - - '@esbuild/win32-arm64@0.23.0': - optional: true - - '@esbuild/win32-ia32@0.23.0': - optional: true - - '@esbuild/win32-x64@0.23.0': - optional: true - '@isaacs/cached@1.0.1': dependencies: '@isaacs/catcher': 1.0.4 @@ -489,33 +265,6 @@ snapshots: emoji-regex@9.2.2: {} - esbuild@0.23.0: - optionalDependencies: - '@esbuild/aix-ppc64': 0.23.0 - '@esbuild/android-arm': 0.23.0 - '@esbuild/android-arm64': 0.23.0 - '@esbuild/android-x64': 0.23.0 - '@esbuild/darwin-arm64': 0.23.0 - '@esbuild/darwin-x64': 0.23.0 - '@esbuild/freebsd-arm64': 0.23.0 - '@esbuild/freebsd-x64': 0.23.0 - '@esbuild/linux-arm': 0.23.0 - '@esbuild/linux-arm64': 0.23.0 - '@esbuild/linux-ia32': 0.23.0 - '@esbuild/linux-loong64': 0.23.0 - '@esbuild/linux-mips64el': 0.23.0 - '@esbuild/linux-ppc64': 0.23.0 - '@esbuild/linux-riscv64': 0.23.0 - '@esbuild/linux-s390x': 0.23.0 - '@esbuild/linux-x64': 0.23.0 - '@esbuild/netbsd-x64': 0.23.0 - '@esbuild/openbsd-arm64': 0.23.0 - '@esbuild/openbsd-x64': 0.23.0 - '@esbuild/sunos-x64': 0.23.0 - '@esbuild/win32-arm64': 0.23.0 - '@esbuild/win32-ia32': 0.23.0 - '@esbuild/win32-x64': 0.23.0 - fetch-super-headers@0.3.2: {} foreground-child@3.2.1: diff --git a/tsconfig.json b/tsconfig.json index ba16aeed449..d8aaef54f9d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,13 +4,5 @@ "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true - }, - "references": [ - { - "path": "./tsconfig.lib.json" - }, - { - "path": "./tsconfig.spec.json" - } - ] + } } From 53a25777eca7799c86451f1cc5b2b81e3739ded1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 16:35:51 -0700 Subject: [PATCH 045/730] 0.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 33e394a7830..dae0cf6b1e3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fetch-multipart-parser", - "version": "0.2.1", + "version": "0.3.0", "description": "A multipart parser for fetch streams", "author": "Michael Jackson ", "license": "MIT", From f319118872f974cfc55c08d0444506a4c108f13f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 16:38:12 -0700 Subject: [PATCH 046/730] Update fetch-super-headers dep --- package.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index dae0cf6b1e3..226d8fb071d 100644 --- a/package.json +++ b/package.json @@ -4,15 +4,15 @@ "description": "A multipart parser for fetch streams", "author": "Michael Jackson ", "license": "MIT", - "type": "module", - "main": "./dist/index.js", "files": [ "dist", "LICENSE", "README.md" ], + "type": "module", + "main": "./dist/index.js", "dependencies": { - "fetch-super-headers": "^0.3.2" + "fetch-super-headers": "^0.4.0" }, "devDependencies": { "@types/node": "^20.14.10", @@ -24,5 +24,6 @@ "test": "node --import tsimp/import --test ./src/**/*.spec.ts", "prepare": "npm run build", "prepublishOnly": "npm run test" - } + }, + "packageManager": "pnpm@9.4.0" } From dcf2132e53cd6862454dc651afbab29a85d6a9c9 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 16:38:22 -0700 Subject: [PATCH 047/730] 0.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 226d8fb071d..5a75c9e69ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fetch-multipart-parser", - "version": "0.3.0", + "version": "0.4.0", "description": "A multipart parser for fetch streams", "author": "Michael Jackson ", "license": "MIT", From 6f3e58a2495fc2c2f5485cb0b78911d6ebea6aa0 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 16:39:04 -0700 Subject: [PATCH 048/730] Re-arrange package.json --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a71f0f8ab51..1b59d48a2cb 100644 --- a/package.json +++ b/package.json @@ -11,16 +11,16 @@ ], "type": "module", "main": "./dist/index.js", + "devDependencies": { + "@types/node": "^20.14.10", + "tsimp": "^2.0.11", + "typescript": "^5.5.3" + }, "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", "prepare": "npm run build", "prepublishOnly": "npm run test" }, - "devDependencies": { - "@types/node": "^20.14.10", - "tsimp": "^2.0.11", - "typescript": "^5.5.3" - }, "packageManager": "pnpm@9.4.0" } From af0c0c9470cbc49948ff69ca2aa231c9b1e1d581 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 16:52:54 -0700 Subject: [PATCH 049/730] Update README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index c94370e7dd4..f0429d762b7 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ `fetch-multipart-parser` is a streaming multipart parser for JavaScript's fetch API. +## Features + +This package is a streaming multipart parser for JavaScript's fetch API, making it easy to parse incoming `Request` bodies that are generated by `` in the browser. + ## Installation ```sh From 70c22568635707066f8ca4591a2f1bf6e4e7d317 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 16 Jul 2024 17:05:03 -0700 Subject: [PATCH 050/730] Update doc comment --- src/lib/multipart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 6d3eafcdeac..d5524249224 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -116,7 +116,7 @@ export async function* parseMultipartFormData( * * Throw `MultipartParseError` if the parse fails for some reason. * - * Note: This is a low-level function that requires manually handling the stream and boundary. For most common use cases, + * Note: This is a low-level API that requires manually handling the stream and boundary. For most common use cases, * consider using `parseMultipartFormData(request)` instead. */ export async function* parseMultipartStream( From 36b68ecee92aa006ce36af3c718ffc20ceb4ad64 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 17 Jul 2024 00:28:47 -0700 Subject: [PATCH 051/730] Use a ring buffer to improve perf --- src/lib/multipart.ts | 97 +++++++++++++------------ src/lib/ring-buffer.spec.ts | 139 ++++++++++++++++++++++++++++++++++++ src/lib/ring-buffer.ts | 94 ++++++++++++++++++++++++ 3 files changed, 281 insertions(+), 49 deletions(-) create mode 100644 src/lib/ring-buffer.spec.ts create mode 100644 src/lib/ring-buffer.ts diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index d5524249224..7a439059828 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -1,5 +1,7 @@ import { SuperHeaders } from 'fetch-super-headers'; +import { RingBuffer } from './ring-buffer.js'; + const CRLF = '\r\n'; const DefaultMaxHeaderSize = 1024 * 1024; // 1 MB @@ -53,10 +55,6 @@ export interface MultipartParseOptions { maxPartSize?: number; } -const textEncoder = new TextEncoder(); -const textDecoder = new TextDecoder(); -const findDoubleCRLF = createSeqFinder(textEncoder.encode(CRLF + CRLF)); - /** * Parse a `multipart/form-data` request body and yield each part as a `MultipartPart` object. * @@ -111,6 +109,10 @@ export async function* parseMultipartFormData( yield* parseMultipartStream(boundary, request.body, options); } +const textEncoder = new TextEncoder(); +const textDecoder = new TextDecoder(); +const findHeaderEnd = createSeqFinder(textEncoder.encode(CRLF + CRLF)); + /** * Parse a multipart stream and yield each part as a `MultipartPart` object. * @@ -130,11 +132,11 @@ export async function* parseMultipartStream( let boundarySeq = textEncoder.encode(`--${boundary}`); let findBoundary = createSeqFinder(boundarySeq); - let initialBoundaryFound = false; - let isFinished = false; let reader = stream.getReader(); - let buffer = new Uint8Array(0); + let buffer = new RingBuffer(16 * 1024); // Start with a 16KB buffer let boundarySearchStartIndex = 0; + let initialBoundaryFound = false; + let isFinished = false; try { while (!isFinished) { @@ -146,31 +148,33 @@ export async function* parseMultipartStream( break; } - buffer = Uint8Array.from([...buffer, ...value]); + buffer.append(value); while (true) { - let boundaryIndex = findBoundary(buffer, boundarySearchStartIndex); + let boundaryIndex = findBoundary(buffer.peek(buffer.length), boundarySearchStartIndex); if (boundaryIndex === -1) { - // No boundary found, remember the last search index + // No boundary found, begin the boundary search on the next iteration from + // the start of the last potential boundary sequence. boundarySearchStartIndex = Math.max(0, buffer.length - boundarySeq.length); break; } if (initialBoundaryFound) { - let partData = buffer.subarray(0, boundaryIndex - 2); // -2 to remove \r\n before boundary - let headerEndIndex = findDoubleCRLF(partData); + let partData = buffer.read(boundaryIndex - 2); // -2 to avoid \r\n before the boundary + let headerEndIndex = findHeaderEnd(partData); let headers: SuperHeaders; let content: Uint8Array; if (headerEndIndex !== -1) { - if (headerEndIndex > maxHeaderSize) { + let header = partData.subarray(0, headerEndIndex); + if (header.length > maxHeaderSize) { throw new MultipartParseError( `Headers size exceeds maximum allowed size of ${maxHeaderSize} bytes` ); } - headers = new SuperHeaders(textDecoder.decode(partData.subarray(0, headerEndIndex))); - content = partData.subarray(headerEndIndex + 4); // +4 to remove \r\n\r\n after headers + headers = new SuperHeaders(textDecoder.decode(header)); + content = partData.subarray(headerEndIndex + 4); // +4 to remove \r\n\r\n after header } else { // No headers found, treat entire part as content headers = new SuperHeaders(); @@ -184,24 +188,26 @@ export async function* parseMultipartStream( } yield new MultipartPart(headers, content); + + buffer.read(2); // Skip the \r\n before the boundary } else { initialBoundaryFound = true; } - buffer = buffer.subarray(boundaryIndex + boundarySeq.length); + buffer.read(boundarySeq.length); // Skip the boundary boundarySearchStartIndex = 0; - if (buffer.length > 1 && buffer[0] === 45 && buffer[1] === 45) { - isFinished = true; - buffer = buffer.subarray(2); // Keep any data after final boundary - break; + if (buffer.length > 1) { + let endMarker = buffer.peek(2); // Check for "--" + if (endMarker[0] === 45 && endMarker[1] === 45) { + isFinished = true; + break; + } else { + buffer.read(2); // Skip the \r\n after the boundary + } } } } - - if (buffer.length > 0) { - throw new MultipartParseError('Unexpected data after final boundary'); - } } finally { reader.releaseLock(); } @@ -213,32 +219,25 @@ function createSeqFinder(needle: Uint8Array): (haystack: Uint8Array, offset?: nu skipTable.set(needle[i], needle.length - 1 - i); } - return (haystack: Uint8Array, offset = 0) => findSeq(haystack, needle, skipTable, offset); -} - -function findSeq( - haystack: Uint8Array, - needle: Uint8Array, - skipTable: Map, - offset: number -): number { - // boyer-moore-horspool algorithm - if (needle.length === 0) { - return offset; - } - - let i = offset + needle.length - 1; - while (i < haystack.length) { - let j = needle.length - 1; - while (j >= 0 && haystack[i] === needle[j]) { - i--; - j--; + return (haystack: Uint8Array, offset = 0) => { + // boyer-moore-horspool algorithm + if (needle.length === 0) { + return offset; } - if (j < 0) { - return i + 1; + + let i = offset + needle.length - 1; + while (i < haystack.length) { + let j = needle.length - 1; + while (j >= 0 && haystack[i] === needle[j]) { + i--; + j--; + } + if (j < 0) { + return i + 1; + } + i += Math.max(needle.length - j, skipTable.get(haystack[i]) || needle.length); } - i += Math.max(needle.length - j, skipTable.get(haystack[i]) || needle.length); - } - return -1; + return -1; + }; } diff --git a/src/lib/ring-buffer.spec.ts b/src/lib/ring-buffer.spec.ts new file mode 100644 index 00000000000..5578da3e0ed --- /dev/null +++ b/src/lib/ring-buffer.spec.ts @@ -0,0 +1,139 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { RingBuffer } from './ring-buffer.js'; + +describe('RingBuffer', () => { + it('handles initialization with the correct capacity', () => { + let buffer = new RingBuffer(10); + assert.equal(buffer.capacity, 10); + assert.equal(buffer.length, 0); + }); + + it('handles appending data correctly', () => { + let buffer = new RingBuffer(5); + buffer.append(new Uint8Array([1, 2, 3])); + assert.equal(buffer.length, 3); + assert.deepEqual(buffer.peek(3), new Uint8Array([1, 2, 3])); + }); + + it('handles appending an empty array', () => { + let buffer = new RingBuffer(5); + buffer.append(new Uint8Array([1, 2])); + buffer.append(new Uint8Array([])); + assert.equal(buffer.length, 2); + assert.deepEqual(buffer.peek(2), new Uint8Array([1, 2])); + }); + + it('handles appending data larger than initial capacity', () => { + let buffer = new RingBuffer(3); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + assert.equal(buffer.capacity, 6); + assert.equal(buffer.length, 5); + assert.deepEqual(buffer.peek(5), new Uint8Array([1, 2, 3, 4, 5])); + }); + + it('handles reading data correctly', () => { + let buffer = new RingBuffer(5); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + assert.equal(buffer.length, 5); + assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); + assert.equal(buffer.length, 2); + }); + + it('handles reading zero bytes', () => { + let buffer = new RingBuffer(5); + buffer.append(new Uint8Array([1, 2, 3])); + assert.deepEqual(buffer.read(0), new Uint8Array([])); + assert.equal(buffer.length, 3); + }); + + it('handles reading all data and then appending', () => { + let buffer = new RingBuffer(5); + buffer.append(new Uint8Array([1, 2, 3])); + buffer.read(3); + buffer.append(new Uint8Array([4, 5])); + assert.equal(buffer.length, 2); + assert.deepEqual(buffer.peek(2), new Uint8Array([4, 5])); + }); + + it('handles circular behavior when appending', () => { + let buffer = new RingBuffer(5); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + buffer.append(new Uint8Array([6, 7])); + assert.equal(buffer.length, 7); + assert.deepEqual(buffer.peek(5), new Uint8Array([1, 2, 3, 4, 5])); + }); + + it('handles circular behavior when reading', () => { + let buffer = new RingBuffer(5); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); + buffer.append(new Uint8Array([6, 7, 8])); + assert.equal(buffer.length, 5); + assert.deepEqual(buffer.read(5), new Uint8Array([4, 5, 6, 7, 8])); + }); + + it('handles resizing the buffer when necessary', () => { + let buffer = new RingBuffer(5); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + buffer.append(new Uint8Array([6, 7, 8, 9, 10])); + assert.equal(buffer.capacity, 10); + assert.equal(buffer.length, 10); + assert.deepEqual(buffer.peek(10), new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])); + }); + + it('handles reading past the end of the internal buffer', () => { + let buffer = new RingBuffer(5); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); + buffer.append(new Uint8Array([6, 7, 8])); + assert.equal(buffer.length, 5); + assert.deepEqual(buffer.read(5), new Uint8Array([4, 5, 6, 7, 8])); + assert.equal(buffer.length, 0); + }); + + it('handles multiple resize operations', () => { + let buffer = new RingBuffer(2); + buffer.append(new Uint8Array([1, 2])); + buffer.append(new Uint8Array([3, 4])); + buffer.append(new Uint8Array([5, 6])); + assert.equal(buffer.capacity, 8); + assert.equal(buffer.length, 6); + assert.deepEqual(buffer.peek(6), new Uint8Array([1, 2, 3, 4, 5, 6])); + }); + + it('throws an error when reading with negative size', () => { + let buffer = new RingBuffer(5); + buffer.append(new Uint8Array([1, 2, 3])); + assert.throws(() => buffer.read(-1), { + name: 'Error', + message: 'Requested size must be non-negative', + }); + }); + + it('handles peeking with zero size', () => { + let buffer = new RingBuffer(5); + buffer.append(new Uint8Array([1, 2, 3])); + assert.deepEqual(buffer.peek(0), new Uint8Array([])); + }); + + it('throws an error when peeking more data than available', () => { + let buffer = new RingBuffer(5); + buffer.append(new Uint8Array([1, 2, 3])); + assert.equal(buffer.length, 3); + assert.throws(() => buffer.peek(4), { + name: 'Error', + message: 'Requested size is larger than buffer length', + }); + }); + + it('throws an error when exceeding the maximum capacity', () => { + let buffer = new RingBuffer(5, 9); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + assert.throws(() => buffer.append(new Uint8Array([6, 7, 8, 9, 10])), { + name: 'Error', + message: 'Buffer capacity exceeded', + }); + }); +}); diff --git a/src/lib/ring-buffer.ts b/src/lib/ring-buffer.ts new file mode 100644 index 00000000000..f39a35e7f34 --- /dev/null +++ b/src/lib/ring-buffer.ts @@ -0,0 +1,94 @@ +export class RingBuffer { + private start = 0; + private end = 0; + private _length = 0; + private buffer: Uint8Array; + + constructor(initialCapacity: number, public maxCapacity = Infinity) { + this.buffer = new Uint8Array(initialCapacity); + } + + get capacity(): number { + return this.buffer.length; + } + + get length(): number { + return this._length; + } + + private resize(newCapacity: number): void { + let newBuffer = new Uint8Array(newCapacity); + let length = this._length; + + if (length === 0) { + this.buffer = newBuffer; + this.start = this.end = 0; + return; + } + + if (this.start < this.end) { + newBuffer.set(this.buffer.subarray(this.start, this.end), 0); + } else { + let firstPart = this.buffer.subarray(this.start); + newBuffer.set(firstPart, 0); + newBuffer.set(this.buffer.subarray(0, this.end), firstPart.length); + } + + this.buffer = newBuffer; + this.start = 0; + this.end = length; + } + + append(chunk: Uint8Array): void { + if (chunk.length === 0) return; + + if (chunk.length > this.capacity - this._length) { + let minCapacity = this._length + chunk.length; + if (minCapacity > this.maxCapacity) { + throw new Error('Buffer capacity exceeded'); + } + let newCapacity = Math.min(Math.max(this.capacity * 2, minCapacity), this.maxCapacity); + this.resize(newCapacity); + } + + let spaceToEnd = this.capacity - this.end; + if (chunk.length <= spaceToEnd) { + this.buffer.set(chunk, this.end); + this.end += chunk.length; + } else { + this.buffer.set(chunk.subarray(0, spaceToEnd), this.end); + this.buffer.set(chunk.subarray(spaceToEnd), 0); + this.end = chunk.length - spaceToEnd; + } + + this._length += chunk.length; + } + + peek(size: number): Uint8Array { + if (size < 0) { + throw new Error('Requested size must be non-negative'); + } + if (size > this._length) { + throw new Error('Requested size is larger than buffer length'); + } + + let result = new Uint8Array(size); + + if (this.start < this.end) { + result.set(this.buffer.subarray(this.start, this.start + size), 0); + } else { + let firstPart = Math.min(size, this.capacity - this.start); + result.set(this.buffer.subarray(this.start, this.start + firstPart), 0); + result.set(this.buffer.subarray(0, size - firstPart), firstPart); + } + + return result; + } + + read(size: number): Uint8Array { + let result = this.peek(size); + this.start = (this.start + size) % this.capacity; + this._length -= size; + return result; + } +} From 107d0118abc4ffa3cb48d9383379e314bf86be98 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 17 Jul 2024 00:42:40 -0700 Subject: [PATCH 052/730] Rename maxPartSize => maxFileSize --- src/lib/multipart.spec.ts | 2 +- src/lib/multipart.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 565869caf4e..5b6751eab8b 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -216,7 +216,7 @@ describe('parseMultipartFormData', async () => { ); await assert.rejects(async () => { - await parseMultipartFormData(request, { maxPartSize: 1024 * 1024 * 10 }).next(); + await parseMultipartFormData(request, { maxFileSize: 1024 * 1024 * 10 }).next(); }, MultipartParseError); }); diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 7a439059828..e7a2b192720 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -5,7 +5,7 @@ import { RingBuffer } from './ring-buffer.js'; const CRLF = '\r\n'; const DefaultMaxHeaderSize = 1024 * 1024; // 1 MB -const DefaultMaxPartSize = 1024 * 1024 * 10; // 10 MB +const DefaultMaxFileSize = 1024 * 1024 * 10; // 10 MB export class MultipartParseError extends Error { constructor(message: string) { @@ -52,7 +52,7 @@ export function isMultipartFormData(request: Request): boolean { export interface MultipartParseOptions { maxHeaderSize?: number; - maxPartSize?: number; + maxFileSize?: number; } /** @@ -127,7 +127,7 @@ export async function* parseMultipartStream( options: MultipartParseOptions = {} ) { let maxHeaderSize = options.maxHeaderSize || DefaultMaxHeaderSize; - let maxPartSize = options.maxPartSize || DefaultMaxPartSize; + let maxFileSize = options.maxFileSize || DefaultMaxFileSize; let boundarySeq = textEncoder.encode(`--${boundary}`); let findBoundary = createSeqFinder(boundarySeq); @@ -181,9 +181,9 @@ export async function* parseMultipartStream( content = partData; } - if (content.length > maxPartSize) { + if (content.length > maxFileSize) { throw new MultipartParseError( - `Part size exceeds maximum allowed size of ${maxPartSize} bytes` + `Part size exceeds maximum allowed size of ${maxFileSize} bytes` ); } From 6b8e40a3a068956db94d0b30b836b4df27577785 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 17 Jul 2024 01:17:11 -0700 Subject: [PATCH 053/730] Add text getter --- src/lib/multipart.spec.ts | 16 ++++++++-------- src/lib/multipart.ts | 11 ++++++++++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 5b6751eab8b..3a6a4e88504 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -64,7 +64,7 @@ describe('parseMultipartFormData', async () => { assert.equal(parts.length, 1); assert.equal(parts[0].name, 'field1'); - assert.equal(new TextDecoder().decode(parts[0].content), 'value1'); + assert.equal(parts[0].text, 'value1'); }); it('Handles multiple parts correctly', async () => { @@ -90,9 +90,9 @@ describe('parseMultipartFormData', async () => { assert.equal(parts.length, 2); assert.equal(parts[0].name, 'field1'); - assert.equal(new TextDecoder().decode(parts[0].content), 'value1'); + assert.equal(parts[0].text, 'value1'); assert.equal(parts[1].name, 'field2'); - assert.equal(new TextDecoder().decode(parts[1].content), 'value2'); + assert.equal(parts[1].text, 'value2'); }); it('Handles file uploads correctly', async () => { @@ -117,7 +117,7 @@ describe('parseMultipartFormData', async () => { assert.equal(parts[0].name, 'file1'); assert.equal(parts[0].filename, 'test.txt'); assert.equal(parts[0].mediaType, 'text/plain'); - assert.equal(new TextDecoder().decode(parts[0].content), 'File content here'); + assert.equal(parts[0].text, 'File content here'); }); it('Handles multiple fields and a file upload', async () => { @@ -148,13 +148,13 @@ describe('parseMultipartFormData', async () => { assert.equal(parts.length, 3); assert.equal(parts[0].name, 'field1'); - assert.equal(new TextDecoder().decode(parts[0].content), 'value1'); + assert.equal(parts[0].text, 'value1'); assert.equal(parts[1].name, 'field2'); - assert.equal(new TextDecoder().decode(parts[1].content), 'value2'); + assert.equal(parts[1].text, 'value2'); assert.equal(parts[2].name, 'file1'); assert.equal(parts[2].filename, 'test.txt'); assert.equal(parts[2].mediaType, 'text/plain'); - assert.equal(new TextDecoder().decode(parts[2].content), 'File content here'); + assert.equal(parts[2].text, 'File content here'); }); it('Throws error when Content-Type is not multipart/form-data', async () => { @@ -235,7 +235,7 @@ describe('parseMultipartFormData', async () => { assert.equal(parts.length, 1); assert.equal(parts[0].headers.get('Invalid-Header'), null); - assert.equal(new TextDecoder().decode(parts[0].content), 'Some content'); + assert.equal(parts[0].text, 'Some content'); }); it('Throws error when final boundary is missing', async () => { diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index e7a2b192720..5d3b2f78387 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -40,6 +40,15 @@ export class MultipartPart { get name(): string | null { return this.headers.contentDisposition.name || null; } + + /** + * The content of the part as a string. + * + * Note: Do not use this for binary data, use `part.content` instead. + */ + get text(): string { + return new TextDecoder().decode(this.content); + } } /** @@ -183,7 +192,7 @@ export async function* parseMultipartStream( if (content.length > maxFileSize) { throw new MultipartParseError( - `Part size exceeds maximum allowed size of ${maxFileSize} bytes` + `File size exceeds maximum allowed size of ${maxFileSize} bytes` ); } From 60f776a6d6a444b0fca961008bf6ea271e08c2a1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 17 Jul 2024 01:48:55 -0700 Subject: [PATCH 054/730] Add some doc comments --- src/lib/ring-buffer.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/lib/ring-buffer.ts b/src/lib/ring-buffer.ts index f39a35e7f34..152ed582877 100644 --- a/src/lib/ring-buffer.ts +++ b/src/lib/ring-buffer.ts @@ -1,3 +1,6 @@ +/** + * A ring buffer that automatically resizes to accomodate more data when it is full. + */ export class RingBuffer { private start = 0; private end = 0; @@ -8,10 +11,16 @@ export class RingBuffer { this.buffer = new Uint8Array(initialCapacity); } + /** + * The maximum number of bytes the buffer can hold. + */ get capacity(): number { return this.buffer.length; } + /** + * The number of bytes in the buffer. + */ get length(): number { return this._length; } @@ -39,6 +48,9 @@ export class RingBuffer { this.end = length; } + /** + * Appends a chunk of data to the buffer. If the buffer is full, it will be resized. + */ append(chunk: Uint8Array): void { if (chunk.length === 0) return; @@ -64,6 +76,9 @@ export class RingBuffer { this._length += chunk.length; } + /** + * Returns a view of the next `size` bytes in the buffer without removing them. + */ peek(size: number): Uint8Array { if (size < 0) { throw new Error('Requested size must be non-negative'); @@ -85,6 +100,9 @@ export class RingBuffer { return result; } + /** + * Removes and returns the next `size` bytes from the buffer. + */ read(size: number): Uint8Array { let result = this.peek(size); this.start = (this.start + size) % this.capacity; From 5a491e4769d54fb2079edc003e15c5aec8e33a5f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 17 Jul 2024 02:17:23 -0700 Subject: [PATCH 055/730] Defer parsing of part headers --- src/lib/multipart.ts | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 5d3b2f78387..4e77c2aaf45 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -18,27 +18,34 @@ export class MultipartParseError extends Error { * Represents a part of a `multipart/form-data` request. */ export class MultipartPart { - constructor(public headers: SuperHeaders, public content: Uint8Array) {} + constructor(public header: string, public content: Uint8Array) {} + + get headers(): Headers { + return new SuperHeaders(this.header); + } /** * The filename of the part, if it is a file upload. */ get filename(): string | null { - return this.headers.contentDisposition.preferredFilename || null; + let headers = this.headers as SuperHeaders; + return headers.contentDisposition.preferredFilename || null; } /** * The media type of the part. */ get mediaType(): string | null { - return this.headers.contentType.mediaType || null; + let headers = this.headers as SuperHeaders; + return headers.contentType.mediaType || null; } /** * The name of the part, usually the `name` of the field in the `` that submitted the request. */ get name(): string | null { - return this.headers.contentDisposition.name || null; + let headers = this.headers as SuperHeaders; + return headers.contentDisposition.name || null; } /** @@ -172,21 +179,21 @@ export async function* parseMultipartStream( let partData = buffer.read(boundaryIndex - 2); // -2 to avoid \r\n before the boundary let headerEndIndex = findHeaderEnd(partData); - let headers: SuperHeaders; + let header: string; let content: Uint8Array; if (headerEndIndex !== -1) { - let header = partData.subarray(0, headerEndIndex); - if (header.length > maxHeaderSize) { + let headerBytes = partData.subarray(0, headerEndIndex); + if (headerBytes.length > maxHeaderSize) { throw new MultipartParseError( `Headers size exceeds maximum allowed size of ${maxHeaderSize} bytes` ); } - headers = new SuperHeaders(textDecoder.decode(header)); + header = textDecoder.decode(headerBytes); content = partData.subarray(headerEndIndex + 4); // +4 to remove \r\n\r\n after header } else { // No headers found, treat entire part as content - headers = new SuperHeaders(); + header = ''; content = partData; } @@ -196,7 +203,7 @@ export async function* parseMultipartStream( ); } - yield new MultipartPart(headers, content); + yield new MultipartPart(header, content); buffer.read(2); // Skip the \r\n before the boundary } else { From a0c21d8adf603f1eba425385d903171b3d3d7ed8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 17 Jul 2024 08:36:22 -0700 Subject: [PATCH 056/730] Some micro-optimizations --- src/lib/multipart.ts | 48 +++++++++++++++++++----------------------- src/lib/ring-buffer.ts | 16 +++++++++++++- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 4e77c2aaf45..296072da456 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -170,33 +170,29 @@ export async function* parseMultipartStream( let boundaryIndex = findBoundary(buffer.peek(buffer.length), boundarySearchStartIndex); if (boundaryIndex === -1) { // No boundary found, begin the boundary search on the next iteration from - // the start of the last potential boundary sequence. + // the start of the last potential boundary sequence boundarySearchStartIndex = Math.max(0, buffer.length - boundarySeq.length); break; } if (initialBoundaryFound) { - let partData = buffer.read(boundaryIndex - 2); // -2 to avoid \r\n before the boundary - let headerEndIndex = findHeaderEnd(partData); - - let header: string; - let content: Uint8Array; - if (headerEndIndex !== -1) { - let headerBytes = partData.subarray(0, headerEndIndex); - if (headerBytes.length > maxHeaderSize) { - throw new MultipartParseError( - `Headers size exceeds maximum allowed size of ${maxHeaderSize} bytes` - ); - } - - header = textDecoder.decode(headerBytes); - content = partData.subarray(headerEndIndex + 4); // +4 to remove \r\n\r\n after header - } else { - // No headers found, treat entire part as content - header = ''; - content = partData; + let partBytes = buffer.read(boundaryIndex - 2); // -2 to avoid \r\n before the boundary + + let headerEndIndex = findHeaderEnd(partBytes); + if (headerEndIndex === -1) { + throw new MultipartParseError('Invalid part: missing header'); + } + + let headerBytes = partBytes.subarray(0, headerEndIndex); + if (headerBytes.length > maxHeaderSize) { + throw new MultipartParseError( + `Header size exceeds maximum allowed size of ${maxHeaderSize} bytes` + ); } + let header = textDecoder.decode(headerBytes); + let content = partBytes.subarray(headerEndIndex + 4); // +4 to skip \r\n\r\n after the header + if (content.length > maxFileSize) { throw new MultipartParseError( `File size exceeds maximum allowed size of ${maxFileSize} bytes` @@ -205,21 +201,21 @@ export async function* parseMultipartStream( yield new MultipartPart(header, content); - buffer.read(2); // Skip the \r\n before the boundary + buffer.skip(2); // Skip \r\n before the boundary } else { initialBoundaryFound = true; } - buffer.read(boundarySeq.length); // Skip the boundary + buffer.skip(boundarySeq.length); // Skip the boundary boundarySearchStartIndex = 0; if (buffer.length > 1) { - let endMarker = buffer.peek(2); // Check for "--" - if (endMarker[0] === 45 && endMarker[1] === 45) { + // If the next two bytes are "--", it's the final boundary and we're done. + // Otherwise, it's the \r\n after the boundary and we can discard it. + let twoBytes = buffer.read(2); + if (twoBytes[0] === 45 && twoBytes[1] === 45) { isFinished = true; break; - } else { - buffer.read(2); // Skip the \r\n after the boundary } } } diff --git a/src/lib/ring-buffer.ts b/src/lib/ring-buffer.ts index 152ed582877..a9c7f2b84da 100644 --- a/src/lib/ring-buffer.ts +++ b/src/lib/ring-buffer.ts @@ -105,8 +105,22 @@ export class RingBuffer { */ read(size: number): Uint8Array { let result = this.peek(size); + this.skip(size); + return result; + } + + /** + * Removes the next `size` bytes from the buffer without returning them. + */ + skip(size: number): void { + if (size < 0) { + throw new Error('Requested size must be non-negative'); + } + if (size > this._length) { + throw new Error('Requested size is larger than buffer length'); + } + this.start = (this.start + size) % this.capacity; this._length -= size; - return result; } } From a8416a8719b365cf1c0fc94f26709e0b9ae7ac4f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 17 Jul 2024 15:19:59 -0700 Subject: [PATCH 057/730] Re-arrange some constants --- pnpm-lock.yaml | 10 +++++----- src/lib/multipart.ts | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 859f00036b7..9aac4184fa3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: fetch-super-headers: - specifier: ^0.3.2 - version: 0.3.2 + specifier: ^0.4.0 + version: 0.4.0 devDependencies: '@types/node': specifier: ^20.14.10 @@ -83,8 +83,8 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - fetch-super-headers@0.3.2: - resolution: {integrity: sha512-bq+upFu2iaEMjJs7zS9k8cABlLU3TBQgbWxA1rZUNDzzYdDGi6q9KdHcYADzCi7OJ7eIKowxjBVUTOcYQEO7bQ==} + fetch-super-headers@0.4.0: + resolution: {integrity: sha512-3lx+QZ3WnsQCxnUX7Ug+BPDvd1JxZ+CTn5QpvmLEx6jNev7lzd+56mfMr5fWd49X8VeHwZr4De88eeIKavwOIw==} foreground-child@3.2.1: resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} @@ -265,7 +265,7 @@ snapshots: emoji-regex@9.2.2: {} - fetch-super-headers@0.3.2: {} + fetch-super-headers@0.4.0: {} foreground-child@3.2.1: dependencies: diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 296072da456..384ac690497 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -2,11 +2,6 @@ import { SuperHeaders } from 'fetch-super-headers'; import { RingBuffer } from './ring-buffer.js'; -const CRLF = '\r\n'; - -const DefaultMaxHeaderSize = 1024 * 1024; // 1 MB -const DefaultMaxFileSize = 1024 * 1024 * 10; // 10 MB - export class MultipartParseError extends Error { constructor(message: string) { super(message); @@ -125,9 +120,14 @@ export async function* parseMultipartFormData( yield* parseMultipartStream(boundary, request.body, options); } -const textEncoder = new TextEncoder(); +const DefaultMaxHeaderSize = 1024 * 1024; // 1 MB +const DefaultMaxFileSize = 1024 * 1024 * 10; // 10 MB + +const doubleCRLFSeq = new Uint8Array([13, 10, 13, 10]); +const findHeaderEnd = createSeqFinder(doubleCRLFSeq); + const textDecoder = new TextDecoder(); -const findHeaderEnd = createSeqFinder(textEncoder.encode(CRLF + CRLF)); +const textEncoder = new TextEncoder(); /** * Parse a multipart stream and yield each part as a `MultipartPart` object. From 433da41c6c5b4624edef0694a0923dd31f06f942 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 17 Jul 2024 15:23:42 -0700 Subject: [PATCH 058/730] Add benchmarks --- package.json | 1 + scripts/benchmark.ts | 178 +++++++++++++++++++++++++++++++++++++++++ scripts/package.json | 9 +++ scripts/pnpm-lock.yaml | 61 ++++++++++++++ 4 files changed, 249 insertions(+) create mode 100644 scripts/benchmark.ts create mode 100644 scripts/package.json create mode 100644 scripts/pnpm-lock.yaml diff --git a/package.json b/package.json index 5a75c9e69ae..0606ce5f1fe 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "typescript": "^5.5.3" }, "scripts": { + "bench": "node --import tsimp/import ./scripts/benchmark.ts", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", "prepare": "npm run build", diff --git a/scripts/benchmark.ts b/scripts/benchmark.ts new file mode 100644 index 00000000000..595c7f0d4f8 --- /dev/null +++ b/scripts/benchmark.ts @@ -0,0 +1,178 @@ +interface MultipartMessage { + boundary: string; + payload: string; +} + +function createMultipartMessage(boundary: string, partSizes: number[]): MultipartMessage { + let parts = []; + for (let i = 0; i < partSizes.length; i++) { + parts.push(`--${boundary}`); + parts.push(`Content-Disposition: form-data; name="file${i}"; filename="file${i}.txt"`); + parts.push('Content-Type: text/plain'); + parts.push(''); + parts.push('x'.repeat(partSizes[i])); + } + parts.push(`--${boundary}--`); + return { + boundary, + payload: parts.join('\r\n'), + }; +} + +interface MultipartBenchmark { + name: string; + message: MultipartMessage; +} + +const oneKb = 1024; +const oneMb = 1024 * oneKb; +const benchmarks: MultipartBenchmark[] = [ + { + name: '1-small-file', + message: createMultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [oneKb]), + }, + { + name: '100-small-files', + message: createMultipartMessage( + '----WebKitFormBoundaryzv0Og5zWtGjvzP2A', + Array(100).fill(oneKb) + ), + }, + { + name: '1-large-file', + message: createMultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [10 * oneMb]), + }, + { + name: '5-large-files', + message: createMultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [ + 10 * oneMb, + 10 * oneMb, + 10 * oneMb, + 20 * oneMb, + 50 * oneMb, + ]), + }, +]; + +interface MultipartParser { + name: string; + parse: (message: MultipartMessage) => Promise; +} + +const parsers: MultipartParser[] = [ + { + name: 'fetch-multipart-parser', + async parse(message: MultipartMessage): Promise { + const { parseMultipartStream } = await import('../dist/index.js'); + + let buffer = new TextEncoder().encode(message.payload); + let stream = new ReadableStream({ + start(controller) { + controller.enqueue(buffer); + controller.close(); + }, + }); + + let start = performance.now(); + + let iterator = parseMultipartStream(message.boundary, stream, { maxFileSize: Infinity }); + for await (let part of iterator) { + // Do nothing + } + + return performance.now() - start; + }, + }, + { + name: 'busboy', + async parse(message: MultipartMessage): Promise { + const { Readable } = await import('stream'); + const busboy = await import('busboy'); + + let stream = new Readable({ + read() { + this.push(message.payload); + this.push(null); + }, + }); + + return new Promise((resolve, reject) => { + let start = performance.now(); + + let bb = busboy.default({ + headers: { 'content-type': `multipart/form-data; boundary=${message.boundary}` }, + limits: { fileSize: Infinity }, + }); + + bb.on('error', reject); + + bb.on('close', () => { + resolve(performance.now() - start); + }); + + stream.pipe(bb); + }); + }, + }, + { + name: '@fastify/busboy', + async parse(message: MultipartMessage): Promise { + const { Readable } = await import('stream'); + const busboy = await import('@fastify/busboy'); + + let stream = new Readable({ + read() { + this.push(message.payload); + this.push(null); + }, + }); + + return new Promise((resolve, reject) => { + let start = performance.now(); + + let bb = new busboy.Busboy({ + headers: { 'content-type': `multipart/form-data; boundary=${message.boundary}` }, + limits: { fileSize: Infinity }, + }); + + bb.on('error', reject); + + bb.on('finish', () => { + resolve(performance.now() - start); + }); + + stream.pipe(bb); + }); + }, + }, +]; + +interface BenchmarkResults { + [parserName: string]: { + [testName: string]: string; + }; +} + +async function runBenchmarks(): Promise { + let results: BenchmarkResults = {}; + + for (let parser of parsers) { + results[parser.name] = {}; + + for (let benchmark of benchmarks) { + let time = await parser.parse(benchmark.message); + results[parser.name][benchmark.name] = time.toFixed(2) + ' ms'; + } + } + + return results; +} + +function printResults(results: BenchmarkResults) { + console.table(results); +} + +runBenchmarks().then(printResults, (error) => { + console.error(error); + process.exit(1); +}); diff --git a/scripts/package.json b/scripts/package.json new file mode 100644 index 00000000000..12a2c560125 --- /dev/null +++ b/scripts/package.json @@ -0,0 +1,9 @@ +{ + "name": "fetch-multipart-parser-benchmark", + "private": true, + "dependencies": { + "@fastify/busboy": "^3.0.0", + "@types/busboy": "^1.5.4", + "busboy": "^1.6.0" + } +} diff --git a/scripts/pnpm-lock.yaml b/scripts/pnpm-lock.yaml new file mode 100644 index 00000000000..a7e589cd8da --- /dev/null +++ b/scripts/pnpm-lock.yaml @@ -0,0 +1,61 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@fastify/busboy': + specifier: ^3.0.0 + version: 3.0.0 + '@types/busboy': + specifier: ^1.5.4 + version: 1.5.4 + busboy: + specifier: ^1.6.0 + version: 1.6.0 + +packages: + + '@fastify/busboy@3.0.0': + resolution: {integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==} + + '@types/busboy@1.5.4': + resolution: {integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==} + + '@types/node@20.14.11': + resolution: {integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==} + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + +snapshots: + + '@fastify/busboy@3.0.0': {} + + '@types/busboy@1.5.4': + dependencies: + '@types/node': 20.14.11 + + '@types/node@20.14.11': + dependencies: + undici-types: 5.26.5 + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + streamsearch@1.1.0: {} + + undici-types@5.26.5: {} From 5556fb8d8bb1e91ca12431cd2b18f3691325bfc1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 01:26:30 -0700 Subject: [PATCH 059/730] Add MultipartParser class --- scripts/benchmark.ts | 2 +- src/index.ts | 5 +- src/lib/multipart.ts | 321 ++++++++++++++++++++++++------------------- 3 files changed, 187 insertions(+), 141 deletions(-) diff --git a/scripts/benchmark.ts b/scripts/benchmark.ts index 595c7f0d4f8..bfff699cd04 100644 --- a/scripts/benchmark.ts +++ b/scripts/benchmark.ts @@ -75,7 +75,7 @@ const parsers: MultipartParser[] = [ let start = performance.now(); - let iterator = parseMultipartStream(message.boundary, stream, { maxFileSize: Infinity }); + let iterator = parseMultipartStream(stream, message.boundary, { maxFileSize: Infinity }); for await (let part of iterator) { // Do nothing } diff --git a/src/index.ts b/src/index.ts index 473869b5f9c..fbce68f8f31 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,9 @@ export { - MultipartParseError, - MultipartPart, isMultipartFormData, + MultipartParseError, MultipartParseOptions, parseMultipartFormData, parseMultipartStream, + MultipartParser, + MultipartPart, } from './lib/multipart.js'; diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 384ac690497..740a737e473 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -2,57 +2,6 @@ import { SuperHeaders } from 'fetch-super-headers'; import { RingBuffer } from './ring-buffer.js'; -export class MultipartParseError extends Error { - constructor(message: string) { - super(message); - this.name = 'MultipartParseError'; - } -} - -/** - * Represents a part of a `multipart/form-data` request. - */ -export class MultipartPart { - constructor(public header: string, public content: Uint8Array) {} - - get headers(): Headers { - return new SuperHeaders(this.header); - } - - /** - * The filename of the part, if it is a file upload. - */ - get filename(): string | null { - let headers = this.headers as SuperHeaders; - return headers.contentDisposition.preferredFilename || null; - } - - /** - * The media type of the part. - */ - get mediaType(): string | null { - let headers = this.headers as SuperHeaders; - return headers.contentType.mediaType || null; - } - - /** - * The name of the part, usually the `name` of the field in the `` that submitted the request. - */ - get name(): string | null { - let headers = this.headers as SuperHeaders; - return headers.contentDisposition.name || null; - } - - /** - * The content of the part as a string. - * - * Note: Do not use this for binary data, use `part.content` instead. - */ - get text(): string { - return new TextDecoder().decode(this.content); - } -} - /** * Returns true if the request is `multipart/form-data`. */ @@ -61,7 +10,15 @@ export function isMultipartFormData(request: Request): boolean { return contentType != null && contentType.startsWith('multipart/form-data'); } +export class MultipartParseError extends Error { + constructor(message: string) { + super(message); + this.name = 'MultipartParseError'; + } +} + export interface MultipartParseOptions { + initialBufferSize?: number; maxHeaderSize?: number; maxFileSize?: number; } @@ -117,18 +74,9 @@ export async function* parseMultipartFormData( let boundary = boundaryMatch[1] || boundaryMatch[2]; // handle quoted and unquoted boundaries - yield* parseMultipartStream(boundary, request.body, options); + yield* parseMultipartStream(request.body, boundary, options); } -const DefaultMaxHeaderSize = 1024 * 1024; // 1 MB -const DefaultMaxFileSize = 1024 * 1024 * 10; // 10 MB - -const doubleCRLFSeq = new Uint8Array([13, 10, 13, 10]); -const findHeaderEnd = createSeqFinder(doubleCRLFSeq); - -const textDecoder = new TextDecoder(); -const textEncoder = new TextEncoder(); - /** * Parse a multipart stream and yield each part as a `MultipartPart` object. * @@ -138,118 +86,215 @@ const textEncoder = new TextEncoder(); * consider using `parseMultipartFormData(request)` instead. */ export async function* parseMultipartStream( - boundary: string, stream: ReadableStream, + boundary: string, options: MultipartParseOptions = {} ) { - let maxHeaderSize = options.maxHeaderSize || DefaultMaxHeaderSize; - let maxFileSize = options.maxFileSize || DefaultMaxFileSize; - - let boundarySeq = textEncoder.encode(`--${boundary}`); - let findBoundary = createSeqFinder(boundarySeq); - + let parser = new MultipartParser(boundary, options); let reader = stream.getReader(); - let buffer = new RingBuffer(16 * 1024); // Start with a 16KB buffer - let boundarySearchStartIndex = 0; - let initialBoundaryFound = false; - let isFinished = false; try { - while (!isFinished) { + while (true) { const { done, value } = await reader.read(); + if (done) { - if (!isFinished) { - throw new MultipartParseError('Unexpected end of stream: final boundary not found'); + if (!parser.done) { + throw new MultipartParseError('Unexpected end of stream'); } + break; } - buffer.append(value); + for (let part of parser.push(value)) { + yield part; + } + } + } finally { + reader.releaseLock(); + } +} - while (true) { - let boundaryIndex = findBoundary(buffer.peek(buffer.length), boundarySearchStartIndex); - if (boundaryIndex === -1) { - // No boundary found, begin the boundary search on the next iteration from - // the start of the last potential boundary sequence - boundarySearchStartIndex = Math.max(0, buffer.length - boundarySeq.length); - break; - } +const textDecoder = new TextDecoder(); +const textEncoder = new TextEncoder(); - if (initialBoundaryFound) { - let partBytes = buffer.read(boundaryIndex - 2); // -2 to avoid \r\n before the boundary +/** + * A parser for `multipart/form-data` streams. + */ +export class MultipartParser { + public buffer: RingBuffer; + public done = false; + + private boundaryArray: Uint8Array; + private boundarySkipTable: Map; + private maxHeaderSize: number; + private maxFileSize: number; + private boundarySearchIndex = 0; + private initialBoundaryFound = false; + + constructor(public boundary: string, options: MultipartParseOptions = {}) { + this.boundaryArray = textEncoder.encode(`--${boundary}`); + this.boundarySkipTable = createSkipTable(this.boundaryArray); + this.buffer = new RingBuffer(options.initialBufferSize || 16 * 1024); + this.maxHeaderSize = options.maxHeaderSize || 1024 * 1024; + this.maxFileSize = options.maxFileSize || 10 * 1024 * 1024; + } - let headerEndIndex = findHeaderEnd(partBytes); - if (headerEndIndex === -1) { - throw new MultipartParseError('Invalid part: missing header'); - } + push(chunk: Uint8Array): MultipartPart[] { + if (this.done) { + throw new MultipartParseError('Cannot push, parser is done'); + } - let headerBytes = partBytes.subarray(0, headerEndIndex); - if (headerBytes.length > maxHeaderSize) { - throw new MultipartParseError( - `Header size exceeds maximum allowed size of ${maxHeaderSize} bytes` - ); - } + this.buffer.append(chunk); + + let parts: MultipartPart[] = []; + + while (true) { + let boundaryIndex = findBoundary( + this.buffer.peek(this.buffer.length), + this.boundaryArray, + this.boundarySkipTable, + this.boundarySearchIndex + ); + if (boundaryIndex === -1) { + // No boundary found, begin the boundary search on the next iteration from + // the start of the last potential boundary sequence + this.boundarySearchIndex = Math.max(0, this.buffer.length - this.boundaryArray.length); + break; + } else { + this.boundarySearchIndex = 0; + } - let header = textDecoder.decode(headerBytes); - let content = partBytes.subarray(headerEndIndex + 4); // +4 to skip \r\n\r\n after the header + if (this.initialBoundaryFound) { + let partArray = this.buffer.read(boundaryIndex - 2); // -2 to avoid \r\n before the boundary - if (content.length > maxFileSize) { - throw new MultipartParseError( - `File size exceeds maximum allowed size of ${maxFileSize} bytes` - ); - } + let headerEndIndex = findDoubleCRLF(partArray); + if (headerEndIndex === -1) { + throw new MultipartParseError('Invalid part: missing header'); + } - yield new MultipartPart(header, content); + let headerArray = partArray.subarray(0, headerEndIndex); + if (headerArray.length > this.maxHeaderSize) { + throw new MultipartParseError( + `Header size exceeds maximum allowed size of ${this.maxHeaderSize} bytes` + ); + } - buffer.skip(2); // Skip \r\n before the boundary - } else { - initialBoundaryFound = true; + let contentArray = partArray.subarray(headerEndIndex + 4); // +4 to skip \r\n\r\n after the header + if (contentArray.length > this.maxFileSize) { + throw new MultipartParseError( + `File size exceeds maximum allowed size of ${this.maxFileSize} bytes` + ); } - buffer.skip(boundarySeq.length); // Skip the boundary - boundarySearchStartIndex = 0; - - if (buffer.length > 1) { - // If the next two bytes are "--", it's the final boundary and we're done. - // Otherwise, it's the \r\n after the boundary and we can discard it. - let twoBytes = buffer.read(2); - if (twoBytes[0] === 45 && twoBytes[1] === 45) { - isFinished = true; - break; - } + let header = textDecoder.decode(headerArray); + parts.push(new MultipartPart(header, contentArray)); + + this.buffer.skip(2 + this.boundaryArray.length); // Skip \r\n + boundary + } else { + this.initialBoundaryFound = true; + this.buffer.skip(this.boundaryArray.length); // Skip the boundary + } + + if (this.buffer.length > 1) { + // If the next two bytes are "--", it's the final boundary and we're done. + // Otherwise, it's the \r\n after the boundary and we can discard it. + let twoBytes = this.buffer.read(2); + if (twoBytes[0] === 45 && twoBytes[1] === 45) { + this.done = true; + break; } } } - } finally { - reader.releaseLock(); + + return parts; } } -function createSeqFinder(needle: Uint8Array): (haystack: Uint8Array, offset?: number) => number { +function createSkipTable(needle: Uint8Array): Map { let skipTable = new Map(); for (let i = 0; i < needle.length - 1; i++) { skipTable.set(needle[i], needle.length - 1 - i); } + return skipTable; +} + +function findBoundary( + buffer: Uint8Array, + boundaryArray: Uint8Array, + skipTable: Map, + offset = 0 +): number { + // boyer-moore-horspool algorithm + if (boundaryArray.length === 0) { + return offset; + } - return (haystack: Uint8Array, offset = 0) => { - // boyer-moore-horspool algorithm - if (needle.length === 0) { - return offset; + let i = offset + boundaryArray.length - 1; + while (i < buffer.length) { + let j = boundaryArray.length - 1; + while (j >= 0 && buffer[i] === boundaryArray[j]) { + i--; + j--; } + if (j < 0) { + return i + 1; + } + i += Math.max(boundaryArray.length - j, skipTable.get(buffer[i]) || boundaryArray.length); + } - let i = offset + needle.length - 1; - while (i < haystack.length) { - let j = needle.length - 1; - while (j >= 0 && haystack[i] === needle[j]) { - i--; - j--; - } - if (j < 0) { - return i + 1; - } - i += Math.max(needle.length - j, skipTable.get(haystack[i]) || needle.length); + return -1; +} + +function findDoubleCRLF(buffer: Uint8Array): number { + for (let i = 0; i < buffer.length - 3; i++) { + if (buffer[i] === 13 && buffer[i + 1] === 10 && buffer[i + 2] === 13 && buffer[i + 3] === 10) { + return i; } + } + + return -1; +} + +/** + * A part of a `multipart/form-data` message. + */ +export class MultipartPart { + constructor(public header: string, public content: Uint8Array) {} + + get headers(): Headers { + return new SuperHeaders(this.header); + } + + /** + * The filename of the part, if it is a file upload. + */ + get filename(): string | null { + let headers = this.headers as SuperHeaders; + return headers.contentDisposition.preferredFilename || null; + } + + /** + * The media type of the part. + */ + get mediaType(): string | null { + let headers = this.headers as SuperHeaders; + return headers.contentType.mediaType || null; + } + + /** + * The name of the part, usually the `name` of the field in the `` that submitted the request. + */ + get name(): string | null { + let headers = this.headers as SuperHeaders; + return headers.contentDisposition.name || null; + } - return -1; - }; + /** + * The content of the part as a string. + * + * Note: Do not use this for binary data, use `part.content` instead. + */ + get text(): string { + return textDecoder.decode(this.content); + } } From 4b9004357fb220e8efcbcc80e1f03c040998e0a9 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 01:57:28 -0700 Subject: [PATCH 060/730] Add RingBuffer#find method --- src/lib/multipart.ts | 50 +++++---------------------- src/lib/ring-buffer.spec.ts | 18 +++++----- src/lib/ring-buffer.ts | 68 +++++++++++++++++++++++++++++++------ 3 files changed, 76 insertions(+), 60 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 740a737e473..edef723f446 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -1,6 +1,6 @@ import { SuperHeaders } from 'fetch-super-headers'; -import { RingBuffer } from './ring-buffer.js'; +import { RingBuffer, computeSkipTable } from './ring-buffer.js'; /** * Returns true if the request is `multipart/form-data`. @@ -125,7 +125,7 @@ export class MultipartParser { public done = false; private boundaryArray: Uint8Array; - private boundarySkipTable: Map; + private boundarySkipTable: Uint8Array; private maxHeaderSize: number; private maxFileSize: number; private boundarySearchIndex = 0; @@ -133,7 +133,7 @@ export class MultipartParser { constructor(public boundary: string, options: MultipartParseOptions = {}) { this.boundaryArray = textEncoder.encode(`--${boundary}`); - this.boundarySkipTable = createSkipTable(this.boundaryArray); + this.boundarySkipTable = computeSkipTable(this.boundaryArray); this.buffer = new RingBuffer(options.initialBufferSize || 16 * 1024); this.maxHeaderSize = options.maxHeaderSize || 1024 * 1024; this.maxFileSize = options.maxFileSize || 10 * 1024 * 1024; @@ -149,8 +149,7 @@ export class MultipartParser { let parts: MultipartPart[] = []; while (true) { - let boundaryIndex = findBoundary( - this.buffer.peek(this.buffer.length), + let boundaryIndex = this.buffer.find( this.boundaryArray, this.boundarySkipTable, this.boundarySearchIndex @@ -199,7 +198,7 @@ export class MultipartParser { // If the next two bytes are "--", it's the final boundary and we're done. // Otherwise, it's the \r\n after the boundary and we can discard it. let twoBytes = this.buffer.read(2); - if (twoBytes[0] === 45 && twoBytes[1] === 45) { + if (twoBytes[0] === HYPHEN && twoBytes[1] === HYPHEN) { this.done = true; break; } @@ -210,44 +209,13 @@ export class MultipartParser { } } -function createSkipTable(needle: Uint8Array): Map { - let skipTable = new Map(); - for (let i = 0; i < needle.length - 1; i++) { - skipTable.set(needle[i], needle.length - 1 - i); - } - return skipTable; -} - -function findBoundary( - buffer: Uint8Array, - boundaryArray: Uint8Array, - skipTable: Map, - offset = 0 -): number { - // boyer-moore-horspool algorithm - if (boundaryArray.length === 0) { - return offset; - } - - let i = offset + boundaryArray.length - 1; - while (i < buffer.length) { - let j = boundaryArray.length - 1; - while (j >= 0 && buffer[i] === boundaryArray[j]) { - i--; - j--; - } - if (j < 0) { - return i + 1; - } - i += Math.max(boundaryArray.length - j, skipTable.get(buffer[i]) || boundaryArray.length); - } - - return -1; -} +const HYPHEN = 45; +const CR = 13; +const LF = 10; function findDoubleCRLF(buffer: Uint8Array): number { for (let i = 0; i < buffer.length - 3; i++) { - if (buffer[i] === 13 && buffer[i + 1] === 10 && buffer[i + 2] === 13 && buffer[i + 3] === 10) { + if (buffer[i] === CR && buffer[i + 1] === LF && buffer[i + 2] === CR && buffer[i + 3] === LF) { return i; } } diff --git a/src/lib/ring-buffer.spec.ts b/src/lib/ring-buffer.spec.ts index 5578da3e0ed..a604a2b7006 100644 --- a/src/lib/ring-buffer.spec.ts +++ b/src/lib/ring-buffer.spec.ts @@ -14,7 +14,7 @@ describe('RingBuffer', () => { let buffer = new RingBuffer(5); buffer.append(new Uint8Array([1, 2, 3])); assert.equal(buffer.length, 3); - assert.deepEqual(buffer.peek(3), new Uint8Array([1, 2, 3])); + assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); }); it('handles appending an empty array', () => { @@ -22,7 +22,7 @@ describe('RingBuffer', () => { buffer.append(new Uint8Array([1, 2])); buffer.append(new Uint8Array([])); assert.equal(buffer.length, 2); - assert.deepEqual(buffer.peek(2), new Uint8Array([1, 2])); + assert.deepEqual(buffer.read(2), new Uint8Array([1, 2])); }); it('handles appending data larger than initial capacity', () => { @@ -30,7 +30,7 @@ describe('RingBuffer', () => { buffer.append(new Uint8Array([1, 2, 3, 4, 5])); assert.equal(buffer.capacity, 6); assert.equal(buffer.length, 5); - assert.deepEqual(buffer.peek(5), new Uint8Array([1, 2, 3, 4, 5])); + assert.deepEqual(buffer.read(5), new Uint8Array([1, 2, 3, 4, 5])); }); it('handles reading data correctly', () => { @@ -54,7 +54,7 @@ describe('RingBuffer', () => { buffer.read(3); buffer.append(new Uint8Array([4, 5])); assert.equal(buffer.length, 2); - assert.deepEqual(buffer.peek(2), new Uint8Array([4, 5])); + assert.deepEqual(buffer.read(2), new Uint8Array([4, 5])); }); it('handles circular behavior when appending', () => { @@ -62,7 +62,7 @@ describe('RingBuffer', () => { buffer.append(new Uint8Array([1, 2, 3, 4, 5])); buffer.append(new Uint8Array([6, 7])); assert.equal(buffer.length, 7); - assert.deepEqual(buffer.peek(5), new Uint8Array([1, 2, 3, 4, 5])); + assert.deepEqual(buffer.read(5), new Uint8Array([1, 2, 3, 4, 5])); }); it('handles circular behavior when reading', () => { @@ -80,7 +80,7 @@ describe('RingBuffer', () => { buffer.append(new Uint8Array([6, 7, 8, 9, 10])); assert.equal(buffer.capacity, 10); assert.equal(buffer.length, 10); - assert.deepEqual(buffer.peek(10), new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])); + assert.deepEqual(buffer.read(10), new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])); }); it('handles reading past the end of the internal buffer', () => { @@ -100,7 +100,7 @@ describe('RingBuffer', () => { buffer.append(new Uint8Array([5, 6])); assert.equal(buffer.capacity, 8); assert.equal(buffer.length, 6); - assert.deepEqual(buffer.peek(6), new Uint8Array([1, 2, 3, 4, 5, 6])); + assert.deepEqual(buffer.read(6), new Uint8Array([1, 2, 3, 4, 5, 6])); }); it('throws an error when reading with negative size', () => { @@ -115,14 +115,14 @@ describe('RingBuffer', () => { it('handles peeking with zero size', () => { let buffer = new RingBuffer(5); buffer.append(new Uint8Array([1, 2, 3])); - assert.deepEqual(buffer.peek(0), new Uint8Array([])); + assert.deepEqual(buffer.read(0), new Uint8Array([])); }); it('throws an error when peeking more data than available', () => { let buffer = new RingBuffer(5); buffer.append(new Uint8Array([1, 2, 3])); assert.equal(buffer.length, 3); - assert.throws(() => buffer.peek(4), { + assert.throws(() => buffer.read(4), { name: 'Error', message: 'Requested size is larger than buffer length', }); diff --git a/src/lib/ring-buffer.ts b/src/lib/ring-buffer.ts index a9c7f2b84da..068cb84b19c 100644 --- a/src/lib/ring-buffer.ts +++ b/src/lib/ring-buffer.ts @@ -77,9 +77,9 @@ export class RingBuffer { } /** - * Returns a view of the next `size` bytes in the buffer without removing them. + * Removes and returns the next `size` bytes from the buffer. */ - peek(size: number): Uint8Array { + read(size: number): Uint8Array { if (size < 0) { throw new Error('Requested size must be non-negative'); } @@ -97,15 +97,9 @@ export class RingBuffer { result.set(this.buffer.subarray(0, size - firstPart), firstPart); } - return result; - } + this.start = (this.start + size) % this.capacity; + this._length -= size; - /** - * Removes and returns the next `size` bytes from the buffer. - */ - read(size: number): Uint8Array { - let result = this.peek(size); - this.skip(size); return result; } @@ -123,4 +117,58 @@ export class RingBuffer { this.start = (this.start + size) % this.capacity; this._length -= size; } + + find(needle: Uint8Array, skipTable: Uint8Array, offset = 0): number { + // boyer-moore-horspool algorithm + if (needle.length === 0 || needle.length > this._length - offset) { + return -1; + } + + let bufferLength = this.buffer.length; + let searchStart = (this.start + offset) % bufferLength; + let remaining = this._length - offset; + + while (remaining >= needle.length) { + let j = needle.length - 1; + let i = searchStart + j; + if (i >= bufferLength) { + i -= bufferLength; + } + + // Check characters from right to left + while (j >= 0 && this.buffer[i] === needle[j]) { + j--; + i = i === 0 ? bufferLength - 1 : i - 1; + } + + if (j < 0) { + // Match found + return offset; + } + + // Shift based on the skip table + let shift = skipTable[this.buffer[i]]; + searchStart += shift; + if (searchStart >= bufferLength) { + searchStart -= bufferLength; + } + offset += shift; + remaining -= shift; + } + + return -1; + } +} + +/** + * Computes a skip table to use with buffer.find(). + */ +export function computeSkipTable(needle: Uint8Array): Uint8Array { + let skipTable = new Uint8Array(256).fill(needle.length); + + for (let i = 0; i < needle.length - 1; i++) { + skipTable[needle[i]] = needle.length - 1 - i; + } + + return skipTable; } From 273f84ba715cb5395758eb3e4c022850f55d15eb Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 12:40:05 -0700 Subject: [PATCH 061/730] Better benchmarking --- README.md | 18 +++ bench/content.ts | 39 ++++++ {scripts => bench}/package.json | 3 +- bench/parsers/busboy.ts | 30 ++++ bench/parsers/fastify-busboy.ts | 30 ++++ bench/parsers/fetch-multipart-parser.ts | 26 ++++ {scripts => bench}/pnpm-lock.yaml | 0 bench/runner.ts | 78 +++++++++++ bench/tsconfig.json | 8 ++ package.json | 2 +- scripts/benchmark.ts | 178 ------------------------ 11 files changed, 232 insertions(+), 180 deletions(-) create mode 100644 bench/content.ts rename {scripts => bench}/package.json (68%) create mode 100644 bench/parsers/busboy.ts create mode 100644 bench/parsers/fastify-busboy.ts create mode 100644 bench/parsers/fetch-multipart-parser.ts rename {scripts => bench}/pnpm-lock.yaml (100%) create mode 100644 bench/runner.ts create mode 100644 bench/tsconfig.json delete mode 100644 scripts/benchmark.ts diff --git a/README.md b/README.md index f0429d762b7..f1f7c52a22c 100644 --- a/README.md +++ b/README.md @@ -40,3 +40,21 @@ function handleMultipartRequest(request: Request): void { } } ``` + +## Benchmark + +The results of running the benchmarks on my laptop: + +``` +Platform: Darwin (23.5.0) +CPU: Apple M2 Pro +Node.js v20.15.1 +Date: 7/18/2024, 12:36:05 PM +┌────────────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ +│ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ +├────────────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ +│ fetch-multipart-parser │ '0.02 ms ± 0.10' │ '1.95 ms ± 0.29' │ '0.13 ms ± 0.03' │ '29.52 ms ± 1.46' │ +│ busboy │ '0.03 ms ± 0.11' │ '4.10 ms ± 0.49' │ '0.17 ms ± 0.03' │ '43.38 ms ± 2.96' │ +│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.86 ms ± 0.67' │ '0.32 ms ± 0.04' │ '21.15 ms ± 1.63' │ +└────────────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ +``` diff --git a/bench/content.ts b/bench/content.ts new file mode 100644 index 00000000000..9b900380516 --- /dev/null +++ b/bench/content.ts @@ -0,0 +1,39 @@ +export class MultipartMessage { + public payload: string; + + constructor(public boundary: string, partSizes: number[]) { + let parts = []; + for (let i = 0; i < partSizes.length; i++) { + parts.push(`--${boundary}`); + parts.push(`Content-Disposition: form-data; name="file${i}"; filename="file${i}.txt"`); + parts.push('Content-Type: text/plain'); + parts.push(''); + parts.push('x'.repeat(partSizes[i])); + } + parts.push(`--${boundary}--`); + + this.payload = parts.join('\r\n'); + } +} + +const oneKb = 1024; +const oneMb = 1024 * oneKb; + +export const oneSmallFile = new MultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [oneKb]); + +export const oneLargeFile = new MultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [ + 10 * oneMb, +]); + +export const oneHundredSmallFiles = new MultipartMessage( + '----WebKitFormBoundaryzv0Og5zWtGjvzP2A', + Array(100).fill(oneKb) +); + +export const fiveLargeFiles = new MultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [ + 10 * oneMb, + 10 * oneMb, + 10 * oneMb, + 20 * oneMb, + 50 * oneMb, +]); diff --git a/scripts/package.json b/bench/package.json similarity index 68% rename from scripts/package.json rename to bench/package.json index 12a2c560125..3ea1acc7840 100644 --- a/scripts/package.json +++ b/bench/package.json @@ -1,6 +1,7 @@ { - "name": "fetch-multipart-parser-benchmark", + "name": "fetch-multipart-parser-bench", "private": true, + "type": "module", "dependencies": { "@fastify/busboy": "^3.0.0", "@types/busboy": "^1.5.4", diff --git a/bench/parsers/busboy.ts b/bench/parsers/busboy.ts new file mode 100644 index 00000000000..c64855c8cdd --- /dev/null +++ b/bench/parsers/busboy.ts @@ -0,0 +1,30 @@ +import { Readable } from 'node:stream'; +import busboy from 'busboy'; + +import { MultipartMessage } from '../content.js'; + +export function parse(message: MultipartMessage): Promise { + let stream = new Readable({ + read() { + this.push(message.payload); + this.push(null); + }, + }); + + return new Promise((resolve, reject) => { + let start = performance.now(); + + let bb = busboy({ + headers: { 'content-type': `multipart/form-data; boundary=${message.boundary}` }, + limits: { fileSize: Infinity }, + }); + + bb.on('error', reject); + + bb.on('close', () => { + resolve(performance.now() - start); + }); + + stream.pipe(bb); + }); +} diff --git a/bench/parsers/fastify-busboy.ts b/bench/parsers/fastify-busboy.ts new file mode 100644 index 00000000000..e52cd653fe1 --- /dev/null +++ b/bench/parsers/fastify-busboy.ts @@ -0,0 +1,30 @@ +import { Readable } from 'node:stream'; +import busboy from '@fastify/busboy'; + +import { MultipartMessage } from '../content.js'; + +export async function parse(message: MultipartMessage): Promise { + let stream = new Readable({ + read() { + this.push(message.payload); + this.push(null); + }, + }); + + return new Promise((resolve, reject) => { + let start = performance.now(); + + let bb = new busboy.Busboy({ + headers: { 'content-type': `multipart/form-data; boundary=${message.boundary}` }, + limits: { fileSize: Infinity }, + }); + + bb.on('error', reject); + + bb.on('finish', () => { + resolve(performance.now() - start); + }); + + stream.pipe(bb); + }); +} diff --git a/bench/parsers/fetch-multipart-parser.ts b/bench/parsers/fetch-multipart-parser.ts new file mode 100644 index 00000000000..8ac9657f921 --- /dev/null +++ b/bench/parsers/fetch-multipart-parser.ts @@ -0,0 +1,26 @@ +import { parseMultipartFormData } from '../../dist/index.js'; + +import { MultipartMessage } from '../content.js'; + +export async function parse(message: MultipartMessage): Promise { + let buffer = new TextEncoder().encode(message.payload); + let request = { + headers: new Headers({ + 'content-type': `multipart/form-data; boundary=${message.boundary}`, + }), + body: new ReadableStream({ + start(controller) { + controller.enqueue(buffer); + controller.close(); + }, + }), + } as Request; + + let start = performance.now(); + + for await (let part of parseMultipartFormData(request, { maxFileSize: Infinity })) { + // Do nothing + } + + return performance.now() - start; +} diff --git a/scripts/pnpm-lock.yaml b/bench/pnpm-lock.yaml similarity index 100% rename from scripts/pnpm-lock.yaml rename to bench/pnpm-lock.yaml diff --git a/bench/runner.ts b/bench/runner.ts new file mode 100644 index 00000000000..546e7cddaf6 --- /dev/null +++ b/bench/runner.ts @@ -0,0 +1,78 @@ +import * as os from 'node:os'; + +import * as content from './content.js'; + +import * as busboy from './parsers/busboy.js'; +import * as fastifyBusboy from './parsers/fastify-busboy.js'; +import * as fetchMultipartParser from './parsers/fetch-multipart-parser.js'; + +const benchmarks = [ + { name: '1 small file', message: content.oneSmallFile }, + { name: '1 large file', message: content.oneLargeFile }, + { name: '100 small files', message: content.oneHundredSmallFiles }, + { name: '5 large files', message: content.fiveLargeFiles }, +]; + +function getMeanAndStdDev(measurements: number[]): string { + let mean = measurements.reduce((a, b) => a + b, 0) / measurements.length; + let variance = measurements.reduce((a, b) => a + (b - mean) ** 2, 0) / measurements.length; + let stdDev = Math.sqrt(variance); + return mean.toFixed(2) + ' ms ± ' + stdDev.toFixed(2); +} + +interface Parser { + parse(message: content.MultipartMessage): Promise; +} + +async function runParserBenchmarks( + parser: Parser, + times = 1000 +): Promise<{ [testName: string]: string }> { + let results: { [testName: string]: string } = {}; + + for (let benchmark of benchmarks) { + let measurements: number[] = []; + for (let i = 0; i < times; ++i) { + measurements.push(await parser.parse(benchmark.message)); + } + + results[benchmark.name] = getMeanAndStdDev(measurements); + } + + return results; +} + +interface BenchmarkResults { + [parserName: string]: { + [testName: string]: string; + }; +} + +async function runBenchmarks(parserName?: string): Promise { + let results: BenchmarkResults = {}; + + if (parserName === 'fetch-multipart-parser' || parserName === undefined) { + results['fetch-multipart-parser'] = await runParserBenchmarks(fetchMultipartParser); + } + if (parserName === 'busboy' || parserName === undefined) { + results.busboy = await runParserBenchmarks(busboy); + } + if (parserName === 'fastify-busboy' || parserName === undefined) { + results['@fastify/busboy'] = await runParserBenchmarks(fastifyBusboy); + } + + return results; +} + +function printResults(results: BenchmarkResults) { + console.log(`Platform: ${os.type()} (${os.release()})`); + console.log(`CPU: ${os.cpus()[0].model}`); + console.log(`Node.js ${process.version}`); + console.log(`Date: ${new Date().toLocaleString()}`); + console.table(results); +} + +runBenchmarks(process.argv[2]).then(printResults, (error) => { + console.error(error); + process.exit(1); +}); diff --git a/bench/tsconfig.json b/bench/tsconfig.json new file mode 100644 index 00000000000..d8aaef54f9d --- /dev/null +++ b/bench/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "lib": ["DOM", "ES2020"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true + } +} diff --git a/package.json b/package.json index 0606ce5f1fe..16ded38c994 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "typescript": "^5.5.3" }, "scripts": { - "bench": "node --import tsimp/import ./scripts/benchmark.ts", + "bench": "node --import tsimp/import ./bench/runner.ts", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", "prepare": "npm run build", diff --git a/scripts/benchmark.ts b/scripts/benchmark.ts deleted file mode 100644 index bfff699cd04..00000000000 --- a/scripts/benchmark.ts +++ /dev/null @@ -1,178 +0,0 @@ -interface MultipartMessage { - boundary: string; - payload: string; -} - -function createMultipartMessage(boundary: string, partSizes: number[]): MultipartMessage { - let parts = []; - for (let i = 0; i < partSizes.length; i++) { - parts.push(`--${boundary}`); - parts.push(`Content-Disposition: form-data; name="file${i}"; filename="file${i}.txt"`); - parts.push('Content-Type: text/plain'); - parts.push(''); - parts.push('x'.repeat(partSizes[i])); - } - parts.push(`--${boundary}--`); - return { - boundary, - payload: parts.join('\r\n'), - }; -} - -interface MultipartBenchmark { - name: string; - message: MultipartMessage; -} - -const oneKb = 1024; -const oneMb = 1024 * oneKb; -const benchmarks: MultipartBenchmark[] = [ - { - name: '1-small-file', - message: createMultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [oneKb]), - }, - { - name: '100-small-files', - message: createMultipartMessage( - '----WebKitFormBoundaryzv0Og5zWtGjvzP2A', - Array(100).fill(oneKb) - ), - }, - { - name: '1-large-file', - message: createMultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [10 * oneMb]), - }, - { - name: '5-large-files', - message: createMultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [ - 10 * oneMb, - 10 * oneMb, - 10 * oneMb, - 20 * oneMb, - 50 * oneMb, - ]), - }, -]; - -interface MultipartParser { - name: string; - parse: (message: MultipartMessage) => Promise; -} - -const parsers: MultipartParser[] = [ - { - name: 'fetch-multipart-parser', - async parse(message: MultipartMessage): Promise { - const { parseMultipartStream } = await import('../dist/index.js'); - - let buffer = new TextEncoder().encode(message.payload); - let stream = new ReadableStream({ - start(controller) { - controller.enqueue(buffer); - controller.close(); - }, - }); - - let start = performance.now(); - - let iterator = parseMultipartStream(stream, message.boundary, { maxFileSize: Infinity }); - for await (let part of iterator) { - // Do nothing - } - - return performance.now() - start; - }, - }, - { - name: 'busboy', - async parse(message: MultipartMessage): Promise { - const { Readable } = await import('stream'); - const busboy = await import('busboy'); - - let stream = new Readable({ - read() { - this.push(message.payload); - this.push(null); - }, - }); - - return new Promise((resolve, reject) => { - let start = performance.now(); - - let bb = busboy.default({ - headers: { 'content-type': `multipart/form-data; boundary=${message.boundary}` }, - limits: { fileSize: Infinity }, - }); - - bb.on('error', reject); - - bb.on('close', () => { - resolve(performance.now() - start); - }); - - stream.pipe(bb); - }); - }, - }, - { - name: '@fastify/busboy', - async parse(message: MultipartMessage): Promise { - const { Readable } = await import('stream'); - const busboy = await import('@fastify/busboy'); - - let stream = new Readable({ - read() { - this.push(message.payload); - this.push(null); - }, - }); - - return new Promise((resolve, reject) => { - let start = performance.now(); - - let bb = new busboy.Busboy({ - headers: { 'content-type': `multipart/form-data; boundary=${message.boundary}` }, - limits: { fileSize: Infinity }, - }); - - bb.on('error', reject); - - bb.on('finish', () => { - resolve(performance.now() - start); - }); - - stream.pipe(bb); - }); - }, - }, -]; - -interface BenchmarkResults { - [parserName: string]: { - [testName: string]: string; - }; -} - -async function runBenchmarks(): Promise { - let results: BenchmarkResults = {}; - - for (let parser of parsers) { - results[parser.name] = {}; - - for (let benchmark of benchmarks) { - let time = await parser.parse(benchmark.message); - results[parser.name][benchmark.name] = time.toFixed(2) + ' ms'; - } - } - - return results; -} - -function printResults(results: BenchmarkResults) { - console.table(results); -} - -runBenchmarks().then(printResults, (error) => { - console.error(error); - process.exit(1); -}); From eaab2adaa611ed076abcf4595d4d268a1aaa42bc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 13:12:00 -0700 Subject: [PATCH 062/730] Update description, keywords --- README.md | 11 +++++++---- package.json | 8 ++++++-- src/lib/super-headers.ts | 14 +------------- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 9ad26997839..bfc4bad7539 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@ # fetch-super-headers -`SuperHeaders` is a drop-in replacement for JavaScript `Headers` with type-safe access. +`SuperHeaders` is an enhanced JavaScript `Headers` interface with type-safe access. Another way to think about it is a spec-compliant, type-safe way to parse, modify, and stringify various HTTP headers and collections of them. -## Key Features +## Features This package is a suite of tools that make it a little more fun to work with `Headers`. -- Drop-in replacement for [the standard `Headers` class](https://developer.mozilla.org/en-US/docs/Web/API/Headers) - Strongly typed header-specific getters and setters (e.g., `headers.contentType`, `headers.setCookie`, etc.) - Easy parsing and manipulation of complex headers like `Content-Disposition`, `Content-Type`, `Set-Cookie`, and more - Iterable interface for easy header enumeration - Convenient string conversion for HTTP message parsing and assembly +- Drop-in replacement for [the standard `Headers` class](https://developer.mozilla.org/en-US/docs/Web/API/Headers) ## Installation @@ -22,7 +22,7 @@ $ npm install fetch-super-headers ## Usage -fetch-super-headers is designed to be a drop-in replacement for `Headers`, with some additions that make working with HTTP headers feel a lot more like working with JavaScript objects. +fetch-super-headers is an enhanced interface for `Headers`, with some additions that make working with HTTP headers feel a lot more like working with JavaScript objects. ```ts import SuperHeaders from 'fetch-super-headers'; @@ -38,6 +38,9 @@ console.log(headers.contentType.mediaType); // 'application/json' console.log(headers.contentType.charset); // 'utf-8' headers.contentType.charset = 'iso-8859-1'; + +// SuperHeaders *extends* Headers, so all methods of Headers work just +// as you'd expect them to. console.log(headers.get('Content-Type')); // 'application/json; charset=iso-8859-1' // Content-Disposition diff --git a/package.json b/package.json index 1b59d48a2cb..9a8a9cac159 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "fetch-super-headers", "version": "0.4.0", - "description": "A drop-in replacement for JavaScript Headers with type-safe access", + "description": "An enhanced JavaScript Headers interface type-safe access", "author": "Michael Jackson ", "license": "MIT", "files": [ @@ -22,5 +22,9 @@ "prepare": "npm run build", "prepublishOnly": "npm run test" }, - "packageManager": "pnpm@9.4.0" + "packageManager": "pnpm@9.4.0", + "keywords": [ + "fetch", + "headers" + ] } diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index 8512bb7a086..0947f0f3d09 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -16,19 +16,7 @@ export type SuperHeadersInit = | Record; /** - * A drop-in replacement for JavaScript `Headers` with type-safe access. - * - * @example - * - * ```ts - * let headers = new SuperHeaders(); - * headers.contentType = 'text/plain; charset=utf-8'; - * headers.contentType.mediaType; // 'text/plain' - * headers.contentType.charset; // 'utf-8' - * - * headers.contentType.mediaType = 'text/html'; - * headers.get('Content-Type'); // 'text/html; charset=utf-8' - * ``` + * An enhanced JavaScript `Headers` interface with type-safe access. */ export class SuperHeaders extends Headers implements Iterable<[string, string]> { private map: Map; From 5a93cf362bae2949e6f9b501ab40cffc5eb321d8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 13:12:25 -0700 Subject: [PATCH 063/730] 0.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9a8a9cac159..6d74415fcbc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fetch-super-headers", - "version": "0.4.0", + "version": "0.4.1", "description": "An enhanced JavaScript Headers interface type-safe access", "author": "Michael Jackson ", "license": "MIT", From 80adab8e66320ac50a69222e5412267f225cf97a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 13:21:48 -0700 Subject: [PATCH 064/730] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bfc4bad7539..e50d9f08cb0 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This package is a suite of tools that make it a little more fun to work with `He - Easy parsing and manipulation of complex headers like `Content-Disposition`, `Content-Type`, `Set-Cookie`, and more - Iterable interface for easy header enumeration - Convenient string conversion for HTTP message parsing and assembly -- Drop-in replacement for [the standard `Headers` class](https://developer.mozilla.org/en-US/docs/Web/API/Headers) +- Extends [the standard `Headers` class](https://developer.mozilla.org/en-US/docs/Web/API/Headers), so all `Headers` methods work as you'd expect ## Installation From 860a752d28a591273e0b9e6f2bd9d7cf914ebc85 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 13:22:25 -0700 Subject: [PATCH 065/730] Remove extraneous async --- bench/parsers/fastify-busboy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bench/parsers/fastify-busboy.ts b/bench/parsers/fastify-busboy.ts index e52cd653fe1..74947366b2f 100644 --- a/bench/parsers/fastify-busboy.ts +++ b/bench/parsers/fastify-busboy.ts @@ -3,7 +3,7 @@ import busboy from '@fastify/busboy'; import { MultipartMessage } from '../content.js'; -export async function parse(message: MultipartMessage): Promise { +export function parse(message: MultipartMessage): Promise { let stream = new Readable({ read() { this.push(message.payload); From 4b94dc73dca045a72cc77784ec7fb267e4ee2dd0 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 14:10:56 -0700 Subject: [PATCH 066/730] Update super-headers dep --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 16ded38c994..147f66352a4 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "type": "module", "main": "./dist/index.js", "dependencies": { - "fetch-super-headers": "^0.4.0" + "fetch-super-headers": "^0.4.1" }, "devDependencies": { "@types/node": "^20.14.10", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9aac4184fa3..7570fa95cbb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: fetch-super-headers: - specifier: ^0.4.0 - version: 0.4.0 + specifier: ^0.4.1 + version: 0.4.1 devDependencies: '@types/node': specifier: ^20.14.10 @@ -83,8 +83,8 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - fetch-super-headers@0.4.0: - resolution: {integrity: sha512-3lx+QZ3WnsQCxnUX7Ug+BPDvd1JxZ+CTn5QpvmLEx6jNev7lzd+56mfMr5fWd49X8VeHwZr4De88eeIKavwOIw==} + fetch-super-headers@0.4.1: + resolution: {integrity: sha512-jXB/p3m6iMeDFhHpJ56BgqrvoDIiyueNPF39twy2N63DMcme0imKhGoEZH8AAbnplnggU9OdUs9eFFPZxPULFA==} foreground-child@3.2.1: resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} @@ -265,7 +265,7 @@ snapshots: emoji-regex@9.2.2: {} - fetch-super-headers@0.4.0: {} + fetch-super-headers@0.4.1: {} foreground-child@3.2.1: dependencies: From 6a7f87dc143bb8d79e4e23791d398064b67e18a6 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 14:12:22 -0700 Subject: [PATCH 067/730] Add static RingBuffer.computeSkipTable method --- src/lib/multipart.ts | 11 ++++++----- src/lib/ring-buffer.ts | 26 +++++++++++++++----------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index edef723f446..026068f1b8f 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -1,6 +1,6 @@ import { SuperHeaders } from 'fetch-super-headers'; -import { RingBuffer, computeSkipTable } from './ring-buffer.js'; +import { RingBuffer } from './ring-buffer.js'; /** * Returns true if the request is `multipart/form-data`. @@ -133,7 +133,7 @@ export class MultipartParser { constructor(public boundary: string, options: MultipartParseOptions = {}) { this.boundaryArray = textEncoder.encode(`--${boundary}`); - this.boundarySkipTable = computeSkipTable(this.boundaryArray); + this.boundarySkipTable = RingBuffer.computeSkipTable(this.boundaryArray); this.buffer = new RingBuffer(options.initialBufferSize || 16 * 1024); this.maxHeaderSize = options.maxHeaderSize || 1024 * 1024; this.maxFileSize = options.maxFileSize || 10 * 1024 * 1024; @@ -149,12 +149,13 @@ export class MultipartParser { let parts: MultipartPart[] = []; while (true) { - let boundaryIndex = this.buffer.find( + let nextBoundaryIndex = this.buffer.find( this.boundaryArray, this.boundarySkipTable, this.boundarySearchIndex ); - if (boundaryIndex === -1) { + + if (nextBoundaryIndex === -1) { // No boundary found, begin the boundary search on the next iteration from // the start of the last potential boundary sequence this.boundarySearchIndex = Math.max(0, this.buffer.length - this.boundaryArray.length); @@ -164,7 +165,7 @@ export class MultipartParser { } if (this.initialBoundaryFound) { - let partArray = this.buffer.read(boundaryIndex - 2); // -2 to avoid \r\n before the boundary + let partArray = this.buffer.read(nextBoundaryIndex - 2); // -2 to avoid \r\n before the boundary let headerEndIndex = findDoubleCRLF(partArray); if (headerEndIndex === -1) { diff --git a/src/lib/ring-buffer.ts b/src/lib/ring-buffer.ts index 068cb84b19c..34ef3f1edad 100644 --- a/src/lib/ring-buffer.ts +++ b/src/lib/ring-buffer.ts @@ -118,7 +118,10 @@ export class RingBuffer { this._length -= size; } - find(needle: Uint8Array, skipTable: Uint8Array, offset = 0): number { + /** + * Returns the index of the first occurrence of `needle` in the buffer starting at `offset`. + */ + find(needle: Uint8Array, skipTable = RingBuffer.computeSkipTable(needle), offset = 0): number { // boyer-moore-horspool algorithm if (needle.length === 0 || needle.length > this._length - offset) { return -1; @@ -158,17 +161,18 @@ export class RingBuffer { return -1; } -} -/** - * Computes a skip table to use with buffer.find(). - */ -export function computeSkipTable(needle: Uint8Array): Uint8Array { - let skipTable = new Uint8Array(256).fill(needle.length); + /** + * Computes a skip table ahead of time to use later with `buffer.find(needle, skipTable)`. + * This can improve performance when searching for the same `needle` multiple times. + */ + static computeSkipTable(needle: Uint8Array): Uint8Array { + let skipTable = new Uint8Array(256).fill(needle.length); - for (let i = 0; i < needle.length - 1; i++) { - skipTable[needle[i]] = needle.length - 1 - i; - } + for (let i = 0; i < needle.length - 1; i++) { + skipTable[needle[i]] = needle.length - 1 - i; + } - return skipTable; + return skipTable; + } } From e82d195bd755efef6f15f05615cac2e2137abf5b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 14:12:43 -0700 Subject: [PATCH 068/730] Cache SuperHeaders instance in MultipartPart --- src/lib/multipart.ts | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 026068f1b8f..0157c9ec62a 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -186,8 +186,7 @@ export class MultipartParser { ); } - let header = textDecoder.decode(headerArray); - parts.push(new MultipartPart(header, contentArray)); + parts.push(new MultipartPart(headerArray, contentArray)); this.buffer.skip(2 + this.boundaryArray.length); // Skip \r\n + boundary } else { @@ -228,34 +227,43 @@ function findDoubleCRLF(buffer: Uint8Array): number { * A part of a `multipart/form-data` message. */ export class MultipartPart { - constructor(public header: string, public content: Uint8Array) {} + private _rawHeader: Uint8Array; + private _headers?: SuperHeaders; - get headers(): Headers { - return new SuperHeaders(this.header); + constructor(header: Uint8Array, public content: Uint8Array) { + this._rawHeader = header; + } + + /** + * The headers associated with this part. + */ + get headers(): SuperHeaders { + if (!this._headers) { + this._headers = new SuperHeaders(textDecoder.decode(this._rawHeader)); + } + + return this._headers; } /** * The filename of the part, if it is a file upload. */ get filename(): string | null { - let headers = this.headers as SuperHeaders; - return headers.contentDisposition.preferredFilename || null; + return this.headers.contentDisposition.preferredFilename || null; } /** * The media type of the part. */ get mediaType(): string | null { - let headers = this.headers as SuperHeaders; - return headers.contentType.mediaType || null; + return this.headers.contentType.mediaType || null; } /** * The name of the part, usually the `name` of the field in the `` that submitted the request. */ get name(): string | null { - let headers = this.headers as SuperHeaders; - return headers.contentDisposition.name || null; + return this.headers.contentDisposition.name || null; } /** From a54a3ad1c8b88521fe19f4d0d94cb04367fa5372 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 15:16:46 -0700 Subject: [PATCH 069/730] Rework some tests --- src/lib/multipart.spec.ts | 318 ++++++++++++++++++------------------ src/lib/ring-buffer.spec.ts | 4 +- 2 files changed, 161 insertions(+), 161 deletions(-) diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 3a6a4e88504..1db0b86e889 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -1,11 +1,13 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; +import { ContentDisposition, ContentType, SuperHeaders } from 'fetch-super-headers'; + import { MultipartParseError, parseMultipartFormData } from './multipart.js'; const CRLF = '\r\n'; -function createReadableStreamFromString( +function createBody( content: string, chunkSize = 1024 * 16 // 16 KB is default on node servers ): ReadableStream { @@ -31,30 +33,83 @@ function createReadableStreamFromString( }); } -function createMockRequest( - body: string, - headers: { [key: string]: string }, - chunkSize?: number -): Request { +function createRequest({ + headers, + body = '', +}: { + headers?: Headers | HeadersInit; + body?: string | ReadableStream; +}): Request { return { - headers: new Headers(headers), - body: createReadableStreamFromString(body, chunkSize), + headers: headers instanceof Headers ? headers : new Headers(headers), + body: typeof body === 'string' ? createBody(body) : body, } as unknown as Request; } +type PartValue = + | string + | { + filename?: string; + filenameSplat?: string; + mediaType?: string; + content: string; + }; + +function createMultipartBody(boundary: string, parts: { [name: string]: PartValue }): string { + let lines = []; + + for (let [name, part] of Object.entries(parts)) { + lines.push(`--${boundary}`); + + if (typeof part === 'string') { + let contentDisposition = new ContentDisposition(); + contentDisposition.type = 'form-data'; + contentDisposition.name = name; + lines.push(`Content-Disposition: ${contentDisposition}`); + lines.push(''); + lines.push(part); + } else { + let contentDisposition = new ContentDisposition(); + contentDisposition.type = 'form-data'; + contentDisposition.name = name; + contentDisposition.filename = part.filename; + contentDisposition.filenameSplat = part.filenameSplat; + + lines.push(`Content-Disposition: ${contentDisposition}`); + + if (part.mediaType) { + let contentType = new ContentType(); + contentType.mediaType = part.mediaType; + + lines.push(`Content-Type: ${contentType}`); + } + + lines.push(''); + lines.push(part.content); + } + } + + lines.push(`--${boundary}--`); + + return lines.join(CRLF); +} + +function createMultipartRequest(boundary: string, parts: { [name: string]: PartValue }): Request { + let headers = new SuperHeaders(); + headers.contentType.mediaType = 'multipart/form-data'; + headers.contentType.boundary = boundary; + + let body = createMultipartBody(boundary, parts); + + return createRequest({ headers, body }); +} + describe('parseMultipartFormData', async () => { let boundary = 'boundary123'; - it('Successfully parses a simple multipart form', async () => { - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="field1"', - '', - 'value1', - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, + it('parses a simple multipart form', async () => { + let request = createMultipartRequest(boundary, { + field1: 'value1', }); let parts = []; @@ -67,20 +122,10 @@ describe('parseMultipartFormData', async () => { assert.equal(parts[0].text, 'value1'); }); - it('Handles multiple parts correctly', async () => { - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="field1"', - '', - 'value1', - `--${boundary}`, - 'Content-Disposition: form-data; name="field2"', - '', - 'value2', - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, + it('parses multiple parts correctly', async () => { + let request = createMultipartRequest(boundary, { + field1: 'value1', + field2: 'value2', }); let parts = []; @@ -95,17 +140,28 @@ describe('parseMultipartFormData', async () => { assert.equal(parts[1].text, 'value2'); }); - it('Handles file uploads correctly', async () => { - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="file1"; filename="test.txt"', - 'Content-Type: text/plain', - '', - 'File content here', - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, + it('parses empty parts correctly', async () => { + let request = createMultipartRequest(boundary, { + empty: '', + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'empty'); + assert.equal(parts[0].content.byteLength, 0); + }); + + it('parses file uploads correctly', async () => { + let request = createMultipartRequest(boundary, { + file1: { + filename: 'test.txt', + mediaType: 'text/plain', + content: 'File content', + }, }); let parts = []; @@ -117,28 +173,18 @@ describe('parseMultipartFormData', async () => { assert.equal(parts[0].name, 'file1'); assert.equal(parts[0].filename, 'test.txt'); assert.equal(parts[0].mediaType, 'text/plain'); - assert.equal(parts[0].text, 'File content here'); + assert.equal(parts[0].text, 'File content'); }); - it('Handles multiple fields and a file upload', async () => { - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="field1"', - '', - 'value1', - `--${boundary}`, - 'Content-Disposition: form-data; name="field2"', - '', - 'value2', - `--${boundary}`, - 'Content-Disposition: form-data; name="file1"; filename="test.txt"', - 'Content-Type: text/plain', - '', - 'File content here', - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, + it('parses multiple fields and a file upload', async () => { + let request = createMultipartRequest(boundary, { + field1: 'value1', + field2: 'value2', + file1: { + filename: 'test.txt', + mediaType: 'text/plain', + content: 'File content', + }, }); let parts = []; @@ -154,78 +200,74 @@ describe('parseMultipartFormData', async () => { assert.equal(parts[2].name, 'file1'); assert.equal(parts[2].filename, 'test.txt'); assert.equal(parts[2].mediaType, 'text/plain'); - assert.equal(parts[2].text, 'File content here'); + assert.equal(parts[2].text, 'File content'); }); - it('Throws error when Content-Type is not multipart/form-data', async () => { - let body = 'Some body'; - let request = createMockRequest(body, { 'Content-Type': 'text/plain' }); + it('throws when Content-Type is not multipart/form-data', async () => { + let request = createRequest({ + headers: { 'Content-Type': 'text/plain' }, + }); await assert.rejects(async () => { await parseMultipartFormData(request).next(); }, MultipartParseError); }); - it('Throws error when boundary is missing', async () => { - let body = 'Some body'; - let request = createMockRequest(body, { 'Content-Type': 'multipart/form-data' }); + it('throws when boundary is missing', async () => { + let request = createRequest({ + headers: { 'Content-Type': 'multipart/form-data' }, + }); await assert.rejects(async () => { await parseMultipartFormData(request).next(); }, MultipartParseError); }); - it('Throws error when headers exceed maximum size', async () => { - let largeHeader = 'X-Large-Header: ' + 'a'.repeat(1024 * 1024); // 1MB header - let body = [ - `--${boundary}`, - largeHeader, - 'Content-Disposition: form-data; name="field1"', - '', - 'value1', - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest( - body, - { + it('throws when header exceeds maximum size', async () => { + let request = createRequest({ + headers: { 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, - 1024 * 256 - ); + body: [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + 'X-Large-Header: ' + 'a'.repeat(1024 * 1024), // 1MB header + '', + 'value1', + `--${boundary}--`, + ].join(CRLF), + }); await assert.rejects(async () => { await parseMultipartFormData(request, { maxHeaderSize: 1024 }).next(); }, MultipartParseError); }); - it('Throws error when part exceeds maximum size', async () => { - let largeContent = 'a'.repeat(1024 * 1024 * 11); // 11MB content - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="field1"', - '', - largeContent, - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest( - body, - { + it('throws when file exceeds maximum size', async () => { + let request = createRequest({ + headers: { 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, - 1024 * 1024 - ); + body: [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + '', + 'a'.repeat(1024 * 1024 * 11), // 11MB content + `--${boundary}--`, + ].join(CRLF), + }); await assert.rejects(async () => { await parseMultipartFormData(request, { maxFileSize: 1024 * 1024 * 10 }).next(); }, MultipartParseError); }); - it('Handles malformed messages', async () => { - let body = [`--${boundary}`, 'Invalid-Header', '', 'Some content', `--${boundary}--`].join( - CRLF - ); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, + it('parses malformed parts', async () => { + let request = createRequest({ + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + body: [`--${boundary}`, 'Invalid-Header', '', 'Some content', `--${boundary}--`].join(CRLF), }); let parts = []; @@ -238,16 +280,18 @@ describe('parseMultipartFormData', async () => { assert.equal(parts[0].text, 'Some content'); }); - it('Throws error when final boundary is missing', async () => { - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="field1"', - '', - 'value1', - `--${boundary}`, - ].join(CRLF); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, + it('throws error when final boundary is missing', async () => { + let request = createRequest({ + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + body: [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + '', + 'value1', + `--${boundary}`, + ].join(CRLF), }); await assert.rejects(async () => { @@ -256,48 +300,4 @@ describe('parseMultipartFormData', async () => { } }, MultipartParseError); }); - - it('Handles empty parts correctly', async () => { - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="empty"', - '', - '', - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }); - - let parts = []; - for await (let part of parseMultipartFormData(request)) { - parts.push(part); - } - - assert.equal(parts.length, 1); - assert.equal(parts[0].name, 'empty'); - assert.equal(parts[0].content.byteLength, 0); - }); - - it('Parses complex Content-Disposition correctly', async () => { - let body = [ - `--${boundary}`, - 'Content-Disposition: form-data; name="file"; filename="name with spaces.txt"; filename*=utf-8\'\'encoded%20filename.txt', - '', - 'content', - `--${boundary}--`, - ].join(CRLF); - let request = createMockRequest(body, { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }); - - let parts = []; - for await (let part of parseMultipartFormData(request)) { - parts.push(part); - } - - assert.equal(parts.length, 1); - assert.equal(parts[0].name, 'file'); - assert.equal(parts[0].filename, 'encoded filename.txt'); - }); }); diff --git a/src/lib/ring-buffer.spec.ts b/src/lib/ring-buffer.spec.ts index a604a2b7006..5778d855168 100644 --- a/src/lib/ring-buffer.spec.ts +++ b/src/lib/ring-buffer.spec.ts @@ -112,13 +112,13 @@ describe('RingBuffer', () => { }); }); - it('handles peeking with zero size', () => { + it('handles reading with zero size', () => { let buffer = new RingBuffer(5); buffer.append(new Uint8Array([1, 2, 3])); assert.deepEqual(buffer.read(0), new Uint8Array([])); }); - it('throws an error when peeking more data than available', () => { + it('throws an error when reading more data than available', () => { let buffer = new RingBuffer(5); buffer.append(new Uint8Array([1, 2, 3])); assert.equal(buffer.length, 3); From 541a21c7e44f29c3a90707df17dada1a95c0a940 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 15:47:35 -0700 Subject: [PATCH 070/730] Add test for large files that overflow the initial buffer size --- src/lib/multipart.spec.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 1db0b86e889..00adde81aa8 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -203,6 +203,28 @@ describe('parseMultipartFormData', async () => { assert.equal(parts[2].text, 'File content'); }); + it('parses large files that overflow the initial buffer', async () => { + let content = 'Multipart parsing is fun! '.repeat(1000); + let request = createMultipartRequest(boundary, { + file1: { + filename: 'large.txt', + mediaType: 'text/plain', + content, + }, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request, { initialBufferSize: 1024 })) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'file1'); + assert.equal(parts[0].filename, 'large.txt'); + assert.equal(parts[0].mediaType, 'text/plain'); + assert.equal(parts[0].text, content); + }); + it('throws when Content-Type is not multipart/form-data', async () => { let request = createRequest({ headers: { 'Content-Type': 'text/plain' }, From 4f473da11f71f6d124e55c81b8d34c5784f46f27 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 16:24:33 -0700 Subject: [PATCH 071/730] Allow individual headers to be initialized with objects --- README.md | 2 +- src/index.ts | 8 +-- src/lib/content-disposition.ts | 40 +++++++++----- src/lib/content-type.ts | 34 ++++++++---- src/lib/cookie.ts | 22 ++++++-- src/lib/set-cookie.ts | 96 +++++++++++++++++++++------------- src/lib/super-headers.ts | 5 +- 7 files changed, 133 insertions(+), 74 deletions(-) diff --git a/README.md b/README.md index e50d9f08cb0..02ebb75d9e7 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ `SuperHeaders` is an enhanced JavaScript `Headers` interface with type-safe access. -Another way to think about it is a spec-compliant, type-safe way to parse, modify, and stringify various HTTP headers and collections of them. +Another way to think about it is as a Swiss Army knife for HTTP headers. Whenever you need a spec-compliant, type-safe way to parse, modify, and stringify various HTTP headers and collections of them, SuperHeaders has you covered. ## Features diff --git a/src/index.ts b/src/index.ts index 65209a0b491..8517c3ead09 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ export { SuperHeadersInit, SuperHeaders, SuperHeaders as default } from './lib/super-headers.js'; -export { ContentDisposition } from './lib/content-disposition.js'; -export { ContentType } from './lib/content-type.js'; -export { Cookie } from './lib/cookie.js'; -export { SetCookie } from './lib/set-cookie.js'; +export { ContentDispositionInit, ContentDisposition } from './lib/content-disposition.js'; +export { ContentTypeInit, ContentType } from './lib/content-type.js'; +export { CookieInit, Cookie } from './lib/cookie.js'; +export { SetCookieInit, SetCookie } from './lib/set-cookie.js'; diff --git a/src/lib/content-disposition.ts b/src/lib/content-disposition.ts index c70c70007b4..2c2cc417311 100644 --- a/src/lib/content-disposition.ts +++ b/src/lib/content-disposition.ts @@ -1,29 +1,43 @@ import { HeaderValue } from './header-value.js'; import { parseParams, quote } from './param-values.js'; +export interface ContentDispositionInit { + filename?: string; + filenameSplat?: string; + name?: string; + type?: string; +} + /** * Represents the value of a `Content-Disposition` HTTP header. */ export class ContentDisposition implements HeaderValue { - public type?: string; public filename?: string; public filenameSplat?: string; public name?: string; + public type?: string; - constructor(initialValue?: string) { - if (initialValue) { - let params = parseParams(initialValue); - if (params.length > 0) { - this.type = params[0][0]; - for (let [name, value] of params.slice(1)) { - if (name === 'filename') { - this.filename = value; - } else if (name === 'filename*') { - this.filenameSplat = value; - } else if (name === 'name') { - this.name = value; + constructor(init?: string | ContentDispositionInit) { + if (init) { + if (typeof init === 'string') { + let params = parseParams(init); + if (params.length > 0) { + this.type = params[0][0]; + for (let [name, value] of params.slice(1)) { + if (name === 'filename') { + this.filename = value; + } else if (name === 'filename*') { + this.filenameSplat = value; + } else if (name === 'name') { + this.name = value; + } } } + } else { + this.filename = init.filename; + this.filenameSplat = init.filenameSplat; + this.name = init.name; + this.type = init.type; } } } diff --git a/src/lib/content-type.ts b/src/lib/content-type.ts index 4148ee069db..f09202d24e2 100644 --- a/src/lib/content-type.ts +++ b/src/lib/content-type.ts @@ -1,26 +1,38 @@ import { HeaderValue } from './header-value.js'; import { parseParams, quote } from './param-values.js'; +export interface ContentTypeInit { + boundary?: string; + charset?: string; + mediaType?: string; +} + /** * Represents the value of a `Content-Type` HTTP header. */ export class ContentType implements HeaderValue { - public mediaType?: string; public boundary?: string; public charset?: string; + public mediaType?: string; - constructor(initialValue?: string) { - if (initialValue) { - let params = parseParams(initialValue); - if (params.length > 0) { - this.mediaType = params[0][0]; - for (let [name, value] of params.slice(1)) { - if (name === 'boundary') { - this.boundary = value; - } else if (name === 'charset') { - this.charset = value; + constructor(init?: string | ContentTypeInit) { + if (init) { + if (typeof init === 'string') { + let params = parseParams(init); + if (params.length > 0) { + this.mediaType = params[0][0]; + for (let [name, value] of params.slice(1)) { + if (name === 'boundary') { + this.boundary = value; + } else if (name === 'charset') { + this.charset = value; + } } } + } else { + this.boundary = init.boundary; + this.charset = init.charset; + this.mediaType = init.mediaType; } } } diff --git a/src/lib/cookie.ts b/src/lib/cookie.ts index c030a0ac26a..c146bf82376 100644 --- a/src/lib/cookie.ts +++ b/src/lib/cookie.ts @@ -1,18 +1,30 @@ import { HeaderValue } from './header-value.js'; import { parseParams, quote } from './param-values.js'; +export interface CookieInit { + [name: string]: string; +} + /** * Represents the value of a `Cookie` HTTP header. */ export class Cookie implements HeaderValue, Iterable<[string, string]> { private cookies: Map; - constructor(initialValue?: string) { + constructor(init?: string | CookieInit) { this.cookies = new Map(); - if (initialValue) { - let params = parseParams(initialValue); - for (let [name, value] of params) { - this.cookies.set(name, value || ''); + if (init) { + if (typeof init === 'string') { + let params = parseParams(init); + for (let [name, value] of params) { + this.cookies.set(name, value || ''); + } + } else { + for (let name in init) { + if (Object.prototype.hasOwnProperty.call(init, name)) { + this.cookies.set(name, init[name]); + } + } } } } diff --git a/src/lib/set-cookie.ts b/src/lib/set-cookie.ts index 0758c860eb9..7b8c79a3d39 100644 --- a/src/lib/set-cookie.ts +++ b/src/lib/set-cookie.ts @@ -4,6 +4,18 @@ import { capitalize, isValidDate } from './utils.js'; type SameSiteValue = 'Strict' | 'Lax' | 'None'; +export interface SetCookieInit { + domain?: string; + expires?: Date; + httpOnly?: true; + maxAge?: number; + name?: string; + path?: string; + sameSite?: SameSiteValue; + secure?: true; + value?: string; +} + /** * Represents the value of a `Set-Cookie` HTTP header. */ @@ -18,48 +30,60 @@ export class SetCookie implements HeaderValue { public secure?: true; public value?: string; - constructor(initialValue?: string) { - if (initialValue) { - let params = parseParams(initialValue); - if (params.length > 0) { - this.name = params[0][0]; - this.value = params[0][1]; + constructor(init?: string | SetCookieInit) { + if (init) { + if (typeof init === 'string') { + let params = parseParams(init); + if (params.length > 0) { + this.name = params[0][0]; + this.value = params[0][1]; - for (let [key, value] of params.slice(1)) { - switch (key.toLowerCase()) { - case 'domain': - this.domain = value; - break; - case 'expires': { - if (typeof value === 'string') { - let v = new Date(value); - if (isValidDate(v)) this.expires = v; + for (let [key, value] of params.slice(1)) { + switch (key.toLowerCase()) { + case 'domain': + this.domain = value; + break; + case 'expires': { + if (typeof value === 'string') { + let v = new Date(value); + if (isValidDate(v)) this.expires = v; + } + break; } - break; - } - case 'httponly': - this.httpOnly = true; - break; - case 'max-age': { - if (typeof value === 'string') { - let v = parseInt(value, 10); - if (!isNaN(v)) this.maxAge = v; + case 'httponly': + this.httpOnly = true; + break; + case 'max-age': { + if (typeof value === 'string') { + let v = parseInt(value, 10); + if (!isNaN(v)) this.maxAge = v; + } + break; } - break; + case 'path': + this.path = value; + break; + case 'samesite': + if (typeof value === 'string' && /strict|lax|none/i.test(value)) { + this.sameSite = capitalize(value) as SameSiteValue; + } + break; + case 'secure': + this.secure = true; + break; } - case 'path': - this.path = value; - break; - case 'samesite': - if (typeof value === 'string' && /strict|lax|none/i.test(value)) { - this.sameSite = capitalize(value) as SameSiteValue; - } - break; - case 'secure': - this.secure = true; - break; } } + } else { + this.domain = init.domain; + this.expires = init.expires; + this.httpOnly = init.httpOnly; + this.maxAge = init.maxAge; + this.name = init.name; + this.path = init.path; + this.sameSite = init.sameSite; + this.secure = init.secure; + this.value = init.value; } } } diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index 0947f0f3d09..d987dbda7ea 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -305,10 +305,7 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } } - private getHeaderValue( - key: string, - ctor: new (initialValue?: string) => T - ): T { + private getHeaderValue(key: string, ctor: new (init?: string) => T): T { let value = this.map.get(key); if (value) { if (typeof value === 'string') { From 7bb9db7130ee8bf06895768d3dfe89935285e0fc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 16:38:55 -0700 Subject: [PATCH 072/730] More docs --- README.md | 21 +++++++++++++++------ src/lib/cookie.ts | 20 +++++++++++--------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 02ebb75d9e7..597017c3cd5 100644 --- a/README.md +++ b/README.md @@ -138,19 +138,28 @@ console.log(headers.toString()); // get [object Headers] from toString(). ``` -In addition to the high-level API, fetch-super-headers also provides a rich set of primitives you can use to work with just about any complex HTTP header value. Each header class includes a spec-compliant parser (the constructor), stringifier (`toString`), and getters/setters for all relevant attributes. Classes for headers that contain a list of fields, like `Cookie`, are iterable. +In addition to the high-level `SuperHeaders` API, fetch-super-headers also provides a rich set of primitives you can use to work with just about any complex HTTP header value. Each header class includes a spec-compliant parser (the constructor), stringifier (`toString`), and getters/setters for all relevant attributes. Classes for headers that contain a list of fields, like `Cookie`, are iterable. + +All individual header classes may be initialized with either a) the string value of the header or b) an `init` object specific to that class. ```ts -import { ContentType, Cookie } from 'fetch-super-headers'; +import { ContentDisposition, ContentType, Cookie } from 'fetch-super-headers'; +// Parse a Content-Type header value let contentType = new ContentType('text/html; charset=utf-8'); console.log(contentType.charset); -let cookie = new Cookie(); -cookie.set('theme', 'dark'); -cookie.set('session_id', '123'); +// Stringify a Content-Disposition header value +let contentDisposition = new ContentDisposition({ + type: 'attachment', + name: 'file1', + filename: 'file1.txt', +}); +console.log(`${contentDisposition}`); // "attachment; name=file1; filename=file1.txt" -for (let [key, value] of cookie) { +// Parse a Cookie header value and iterate over name/value pairs +let cookie = new Cookie('theme=dark; session_id=123'); +for (let [name, value] of cookie) { // ... } ``` diff --git a/src/lib/cookie.ts b/src/lib/cookie.ts index c146bf82376..e2ad7bcf9ea 100644 --- a/src/lib/cookie.ts +++ b/src/lib/cookie.ts @@ -1,9 +1,7 @@ import { HeaderValue } from './header-value.js'; import { parseParams, quote } from './param-values.js'; -export interface CookieInit { - [name: string]: string; -} +export type CookieInit = [string, string][] | Record; /** * Represents the value of a `Cookie` HTTP header. @@ -19,6 +17,10 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> { for (let [name, value] of params) { this.cookies.set(name, value || ''); } + } else if (Array.isArray(init)) { + for (let [name, value] of init) { + this.cookies.set(name, value); + } } else { for (let name in init) { if (Object.prototype.hasOwnProperty.call(init, name)) { @@ -49,10 +51,6 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> { this.cookies.clear(); } - [Symbol.iterator](): IterableIterator<[string, string]> { - return this.cookies.entries(); - } - entries(): IterableIterator<[string, string]> { return this.cookies.entries(); } @@ -65,11 +63,15 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> { return this.cookies.values(); } + [Symbol.iterator](): IterableIterator<[string, string]> { + return this.entries(); + } + forEach( - callbackfn: (value: string, key: string, map: Map) => void, + callback: (value: string, key: string, map: Map) => void, thisArg?: any ): void { - this.cookies.forEach(callbackfn, thisArg); + this.cookies.forEach(callback, thisArg); } get size(): number { From fef7c9da3c9234e62285912bbae1dbddadb40322 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 19:00:31 -0700 Subject: [PATCH 073/730] Make test wrap around ring buffer --- src/lib/multipart.spec.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 00adde81aa8..33b7b7abc92 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -206,8 +206,17 @@ describe('parseMultipartFormData', async () => { it('parses large files that overflow the initial buffer', async () => { let content = 'Multipart parsing is fun! '.repeat(1000); let request = createMultipartRequest(boundary, { + // This first file will overflow the initial buffer and trigger a resize (or two). file1: { - filename: 'large.txt', + filename: 'large1.txt', + mediaType: 'text/plain', + content, + }, + // The second file should wrap around the end of the resized buffer because its internal + // pointer will be updated after the first file is read() but it is already large enough + // to hold this file since it already expanded to hold the first one. + file2: { + filename: 'large2.txt', mediaType: 'text/plain', content, }, @@ -218,11 +227,15 @@ describe('parseMultipartFormData', async () => { parts.push(part); } - assert.equal(parts.length, 1); + assert.equal(parts.length, 2); assert.equal(parts[0].name, 'file1'); - assert.equal(parts[0].filename, 'large.txt'); + assert.equal(parts[0].filename, 'large1.txt'); assert.equal(parts[0].mediaType, 'text/plain'); assert.equal(parts[0].text, content); + assert.equal(parts[1].name, 'file2'); + assert.equal(parts[1].filename, 'large2.txt'); + assert.equal(parts[1].mediaType, 'text/plain'); + assert.equal(parts[1].text, content); }); it('throws when Content-Type is not multipart/form-data', async () => { From c59b33be7d0120ce616842c5f84841e6ab94bace Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 23:10:23 -0700 Subject: [PATCH 074/730] Better test for ring buffer overflow behavior --- src/lib/multipart.spec.ts | 70 ++++++++++--------------------------- src/lib/ring-buffer.spec.ts | 8 ++--- 2 files changed, 23 insertions(+), 55 deletions(-) diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 33b7b7abc92..58480d80329 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -7,7 +7,7 @@ import { MultipartParseError, parseMultipartFormData } from './multipart.js'; const CRLF = '\r\n'; -function createBody( +function createReadableStream( content: string, chunkSize = 1024 * 16 // 16 KB is default on node servers ): ReadableStream { @@ -33,7 +33,7 @@ function createBody( }); } -function createRequest({ +function createMockRequest({ headers, body = '', }: { @@ -42,7 +42,7 @@ function createRequest({ }): Request { return { headers: headers instanceof Headers ? headers : new Headers(headers), - body: typeof body === 'string' ? createBody(body) : body, + body: typeof body === 'string' ? createReadableStream(body) : body, } as unknown as Request; } @@ -94,21 +94,24 @@ function createMultipartBody(boundary: string, parts: { [name: string]: PartValu return lines.join(CRLF); } -function createMultipartRequest(boundary: string, parts: { [name: string]: PartValue }): Request { +function createMultipartMockRequest( + boundary: string, + parts: { [name: string]: PartValue } +): Request { let headers = new SuperHeaders(); headers.contentType.mediaType = 'multipart/form-data'; headers.contentType.boundary = boundary; let body = createMultipartBody(boundary, parts); - return createRequest({ headers, body }); + return createMockRequest({ headers, body }); } describe('parseMultipartFormData', async () => { let boundary = 'boundary123'; it('parses a simple multipart form', async () => { - let request = createMultipartRequest(boundary, { + let request = createMultipartMockRequest(boundary, { field1: 'value1', }); @@ -123,7 +126,7 @@ describe('parseMultipartFormData', async () => { }); it('parses multiple parts correctly', async () => { - let request = createMultipartRequest(boundary, { + let request = createMultipartMockRequest(boundary, { field1: 'value1', field2: 'value2', }); @@ -141,7 +144,7 @@ describe('parseMultipartFormData', async () => { }); it('parses empty parts correctly', async () => { - let request = createMultipartRequest(boundary, { + let request = createMultipartMockRequest(boundary, { empty: '', }); @@ -156,7 +159,7 @@ describe('parseMultipartFormData', async () => { }); it('parses file uploads correctly', async () => { - let request = createMultipartRequest(boundary, { + let request = createMultipartMockRequest(boundary, { file1: { filename: 'test.txt', mediaType: 'text/plain', @@ -177,7 +180,7 @@ describe('parseMultipartFormData', async () => { }); it('parses multiple fields and a file upload', async () => { - let request = createMultipartRequest(boundary, { + let request = createMultipartMockRequest(boundary, { field1: 'value1', field2: 'value2', file1: { @@ -203,43 +206,8 @@ describe('parseMultipartFormData', async () => { assert.equal(parts[2].text, 'File content'); }); - it('parses large files that overflow the initial buffer', async () => { - let content = 'Multipart parsing is fun! '.repeat(1000); - let request = createMultipartRequest(boundary, { - // This first file will overflow the initial buffer and trigger a resize (or two). - file1: { - filename: 'large1.txt', - mediaType: 'text/plain', - content, - }, - // The second file should wrap around the end of the resized buffer because its internal - // pointer will be updated after the first file is read() but it is already large enough - // to hold this file since it already expanded to hold the first one. - file2: { - filename: 'large2.txt', - mediaType: 'text/plain', - content, - }, - }); - - let parts = []; - for await (let part of parseMultipartFormData(request, { initialBufferSize: 1024 })) { - parts.push(part); - } - - assert.equal(parts.length, 2); - assert.equal(parts[0].name, 'file1'); - assert.equal(parts[0].filename, 'large1.txt'); - assert.equal(parts[0].mediaType, 'text/plain'); - assert.equal(parts[0].text, content); - assert.equal(parts[1].name, 'file2'); - assert.equal(parts[1].filename, 'large2.txt'); - assert.equal(parts[1].mediaType, 'text/plain'); - assert.equal(parts[1].text, content); - }); - it('throws when Content-Type is not multipart/form-data', async () => { - let request = createRequest({ + let request = createMockRequest({ headers: { 'Content-Type': 'text/plain' }, }); @@ -249,7 +217,7 @@ describe('parseMultipartFormData', async () => { }); it('throws when boundary is missing', async () => { - let request = createRequest({ + let request = createMockRequest({ headers: { 'Content-Type': 'multipart/form-data' }, }); @@ -259,7 +227,7 @@ describe('parseMultipartFormData', async () => { }); it('throws when header exceeds maximum size', async () => { - let request = createRequest({ + let request = createMockRequest({ headers: { 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, @@ -279,7 +247,7 @@ describe('parseMultipartFormData', async () => { }); it('throws when file exceeds maximum size', async () => { - let request = createRequest({ + let request = createMockRequest({ headers: { 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, @@ -298,7 +266,7 @@ describe('parseMultipartFormData', async () => { }); it('parses malformed parts', async () => { - let request = createRequest({ + let request = createMockRequest({ headers: { 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, @@ -316,7 +284,7 @@ describe('parseMultipartFormData', async () => { }); it('throws error when final boundary is missing', async () => { - let request = createRequest({ + let request = createMockRequest({ headers: { 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, diff --git a/src/lib/ring-buffer.spec.ts b/src/lib/ring-buffer.spec.ts index 5778d855168..affe83637b3 100644 --- a/src/lib/ring-buffer.spec.ts +++ b/src/lib/ring-buffer.spec.ts @@ -67,11 +67,11 @@ describe('RingBuffer', () => { it('handles circular behavior when reading', () => { let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + buffer.append(new Uint8Array([1, 2, 3, 4])); assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); - buffer.append(new Uint8Array([6, 7, 8])); - assert.equal(buffer.length, 5); - assert.deepEqual(buffer.read(5), new Uint8Array([4, 5, 6, 7, 8])); + buffer.append(new Uint8Array([5, 6, 7])); + assert.equal(buffer.length, 4); + assert.deepEqual(buffer.read(4), new Uint8Array([4, 5, 6, 7])); }); it('handles resizing the buffer when necessary', () => { From d607d532fe2ad1dfc2082c676d97da5101bf7779 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 18 Jul 2024 23:32:36 -0700 Subject: [PATCH 075/730] Additional RingBuffer tests --- src/lib/ring-buffer.spec.ts | 32 ++++++++++++++++++++++++++++++++ src/lib/ring-buffer.ts | 9 ++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/lib/ring-buffer.spec.ts b/src/lib/ring-buffer.spec.ts index affe83637b3..bc4223607db 100644 --- a/src/lib/ring-buffer.spec.ts +++ b/src/lib/ring-buffer.spec.ts @@ -33,6 +33,38 @@ describe('RingBuffer', () => { assert.deepEqual(buffer.read(5), new Uint8Array([1, 2, 3, 4, 5])); }); + it('handles appending data that exactly fills the remaining capacity', () => { + let buffer = new RingBuffer(5); + buffer.append(new Uint8Array([1, 2, 3])); + assert.equal(buffer.length, 3); + assert.equal(buffer.capacity, 5); + + // This should exactly fill the remaining capacity + buffer.append(new Uint8Array([4, 5])); + + assert.equal(buffer.length, 5); + assert.equal(buffer.capacity, 5); + + // This should trigger a resize + buffer.append(new Uint8Array([6])); + + assert.equal(buffer.length, 6); + assert.ok(buffer.capacity > 5, 'Buffer should have resized'); + + // Verify the content + assert.deepEqual(buffer.read(6), new Uint8Array([1, 2, 3, 4, 5, 6])); + }); + + it('handles appending data that causes multiple wraps', () => { + let buffer = new RingBuffer(5); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + assert.deepEqual(buffer.read(2), new Uint8Array([1, 2])); + buffer.append(new Uint8Array([6, 7])); + // Append more data that will cause another wrap and resize + buffer.append(new Uint8Array([8, 9, 10, 11, 12])); + assert.deepEqual(buffer.read(10), new Uint8Array([3, 4, 5, 6, 7, 8, 9, 10, 11, 12])); + }); + it('handles reading data correctly', () => { let buffer = new RingBuffer(5); buffer.append(new Uint8Array([1, 2, 3, 4, 5])); diff --git a/src/lib/ring-buffer.ts b/src/lib/ring-buffer.ts index 34ef3f1edad..ef6c9204622 100644 --- a/src/lib/ring-buffer.ts +++ b/src/lib/ring-buffer.ts @@ -7,7 +7,14 @@ export class RingBuffer { private _length = 0; private buffer: Uint8Array; - constructor(initialCapacity: number, public maxCapacity = Infinity) { + constructor(initialCapacity: number, public readonly maxCapacity = Infinity) { + if (initialCapacity < 0) { + throw new Error('Initial capacity must be positive'); + } + if (maxCapacity < initialCapacity) { + throw new Error('Max capacity must be greater than or equal to initial capacity'); + } + this.buffer = new Uint8Array(initialCapacity); } From ac1287b2c002a63c2e39895c0a8a7ae3b5e1564e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 19 Jul 2024 00:09:28 -0700 Subject: [PATCH 076/730] Switch order of args in RingBuffer#find --- src/lib/multipart.ts | 7 ++++--- src/lib/ring-buffer.ts | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 0157c9ec62a..0ea80fc1c7e 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -128,11 +128,12 @@ export class MultipartParser { private boundarySkipTable: Uint8Array; private maxHeaderSize: number; private maxFileSize: number; - private boundarySearchIndex = 0; + private boundarySearchIndex: number; private initialBoundaryFound = false; constructor(public boundary: string, options: MultipartParseOptions = {}) { this.boundaryArray = textEncoder.encode(`--${boundary}`); + this.boundarySearchIndex = 0; this.boundarySkipTable = RingBuffer.computeSkipTable(this.boundaryArray); this.buffer = new RingBuffer(options.initialBufferSize || 16 * 1024); this.maxHeaderSize = options.maxHeaderSize || 1024 * 1024; @@ -151,8 +152,8 @@ export class MultipartParser { while (true) { let nextBoundaryIndex = this.buffer.find( this.boundaryArray, - this.boundarySkipTable, - this.boundarySearchIndex + this.boundarySearchIndex, + this.boundarySkipTable ); if (nextBoundaryIndex === -1) { diff --git a/src/lib/ring-buffer.ts b/src/lib/ring-buffer.ts index ef6c9204622..732e2a1786d 100644 --- a/src/lib/ring-buffer.ts +++ b/src/lib/ring-buffer.ts @@ -128,7 +128,7 @@ export class RingBuffer { /** * Returns the index of the first occurrence of `needle` in the buffer starting at `offset`. */ - find(needle: Uint8Array, skipTable = RingBuffer.computeSkipTable(needle), offset = 0): number { + find(needle: Uint8Array, offset = 0, skipTable = RingBuffer.computeSkipTable(needle)): number { // boyer-moore-horspool algorithm if (needle.length === 0 || needle.length > this._length - offset) { return -1; From 24478f1e8ed2fb96ca0fa8cdf614ec762c86a0c1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 19 Jul 2024 00:18:52 -0700 Subject: [PATCH 077/730] Rename some things --- bench/{content.ts => messages.ts} | 4 ++-- bench/parsers/busboy.ts | 4 ++-- bench/parsers/fastify-busboy.ts | 4 ++-- bench/parsers/fetch-multipart-parser.ts | 6 +++--- bench/runner.ts | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) rename bench/{content.ts => messages.ts} (93%) diff --git a/bench/content.ts b/bench/messages.ts similarity index 93% rename from bench/content.ts rename to bench/messages.ts index 9b900380516..4b70e9fe31c 100644 --- a/bench/content.ts +++ b/bench/messages.ts @@ -1,5 +1,5 @@ export class MultipartMessage { - public payload: string; + public content: string; constructor(public boundary: string, partSizes: number[]) { let parts = []; @@ -12,7 +12,7 @@ export class MultipartMessage { } parts.push(`--${boundary}--`); - this.payload = parts.join('\r\n'); + this.content = parts.join('\r\n'); } } diff --git a/bench/parsers/busboy.ts b/bench/parsers/busboy.ts index c64855c8cdd..26e1233968d 100644 --- a/bench/parsers/busboy.ts +++ b/bench/parsers/busboy.ts @@ -1,12 +1,12 @@ import { Readable } from 'node:stream'; import busboy from 'busboy'; -import { MultipartMessage } from '../content.js'; +import { MultipartMessage } from '../messages.js'; export function parse(message: MultipartMessage): Promise { let stream = new Readable({ read() { - this.push(message.payload); + this.push(message.content); this.push(null); }, }); diff --git a/bench/parsers/fastify-busboy.ts b/bench/parsers/fastify-busboy.ts index 74947366b2f..54cca23a85e 100644 --- a/bench/parsers/fastify-busboy.ts +++ b/bench/parsers/fastify-busboy.ts @@ -1,12 +1,12 @@ import { Readable } from 'node:stream'; import busboy from '@fastify/busboy'; -import { MultipartMessage } from '../content.js'; +import { MultipartMessage } from '../messages.js'; export function parse(message: MultipartMessage): Promise { let stream = new Readable({ read() { - this.push(message.payload); + this.push(message.content); this.push(null); }, }); diff --git a/bench/parsers/fetch-multipart-parser.ts b/bench/parsers/fetch-multipart-parser.ts index 8ac9657f921..0469fbc4a9a 100644 --- a/bench/parsers/fetch-multipart-parser.ts +++ b/bench/parsers/fetch-multipart-parser.ts @@ -1,12 +1,12 @@ import { parseMultipartFormData } from '../../dist/index.js'; -import { MultipartMessage } from '../content.js'; +import { MultipartMessage } from '../messages.js'; export async function parse(message: MultipartMessage): Promise { - let buffer = new TextEncoder().encode(message.payload); + let buffer = new TextEncoder().encode(message.content); let request = { headers: new Headers({ - 'content-type': `multipart/form-data; boundary=${message.boundary}`, + 'Content-Type': `multipart/form-data; boundary=${message.boundary}`, }), body: new ReadableStream({ start(controller) { diff --git a/bench/runner.ts b/bench/runner.ts index 546e7cddaf6..92e37188a7f 100644 --- a/bench/runner.ts +++ b/bench/runner.ts @@ -1,6 +1,6 @@ import * as os from 'node:os'; -import * as content from './content.js'; +import * as content from './messages.js'; import * as busboy from './parsers/busboy.js'; import * as fastifyBusboy from './parsers/fastify-busboy.js'; From a48a10251756b36ff1ddcba7a1ff1d98c3ef8462 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 21 Jul 2024 23:23:32 -0600 Subject: [PATCH 078/730] Use consistent chunk sizes in benchmarks --- bench/messages.ts | 7 ++++++ bench/parsers/busboy.ts | 10 ++++++++- bench/parsers/fastify-busboy.ts | 10 ++++++++- bench/parsers/fetch-multipart-parser.ts | 11 ++++++--- bench/runner.ts | 13 +++++------ src/lib/multipart.spec.ts | 30 +++++++------------------ 6 files changed, 47 insertions(+), 34 deletions(-) diff --git a/bench/messages.ts b/bench/messages.ts index 4b70e9fe31c..bb76f03858f 100644 --- a/bench/messages.ts +++ b/bench/messages.ts @@ -14,6 +14,13 @@ export class MultipartMessage { this.content = parts.join('\r\n'); } + + *generateChunks(chunkSize = 16 * 1024): Generator { + let encoder = new TextEncoder(); + for (let i = 0; i < this.content.length; i += chunkSize) { + yield encoder.encode(this.content.slice(i, i + chunkSize)); + } + } } const oneKb = 1024; diff --git a/bench/parsers/busboy.ts b/bench/parsers/busboy.ts index 26e1233968d..ed3dfc7fced 100644 --- a/bench/parsers/busboy.ts +++ b/bench/parsers/busboy.ts @@ -6,7 +6,9 @@ import { MultipartMessage } from '../messages.js'; export function parse(message: MultipartMessage): Promise { let stream = new Readable({ read() { - this.push(message.content); + for (let chunk of message.generateChunks()) { + this.push(chunk); + } this.push(null); }, }); @@ -19,6 +21,12 @@ export function parse(message: MultipartMessage): Promise { limits: { fileSize: Infinity }, }); + bb.on('field', () => {}); + + bb.on('file', (_name, stream) => { + stream.resume(); + }); + bb.on('error', reject); bb.on('close', () => { diff --git a/bench/parsers/fastify-busboy.ts b/bench/parsers/fastify-busboy.ts index 54cca23a85e..7bb3cbdd962 100644 --- a/bench/parsers/fastify-busboy.ts +++ b/bench/parsers/fastify-busboy.ts @@ -6,7 +6,9 @@ import { MultipartMessage } from '../messages.js'; export function parse(message: MultipartMessage): Promise { let stream = new Readable({ read() { - this.push(message.content); + for (let chunk of message.generateChunks()) { + this.push(chunk); + } this.push(null); }, }); @@ -19,6 +21,12 @@ export function parse(message: MultipartMessage): Promise { limits: { fileSize: Infinity }, }); + bb.on('field', () => {}); + + bb.on('file', (_name, stream) => { + stream.resume(); + }); + bb.on('error', reject); bb.on('finish', () => { diff --git a/bench/parsers/fetch-multipart-parser.ts b/bench/parsers/fetch-multipart-parser.ts index 0469fbc4a9a..9c0f77d6f33 100644 --- a/bench/parsers/fetch-multipart-parser.ts +++ b/bench/parsers/fetch-multipart-parser.ts @@ -3,14 +3,15 @@ import { parseMultipartFormData } from '../../dist/index.js'; import { MultipartMessage } from '../messages.js'; export async function parse(message: MultipartMessage): Promise { - let buffer = new TextEncoder().encode(message.content); let request = { headers: new Headers({ 'Content-Type': `multipart/form-data; boundary=${message.boundary}`, }), body: new ReadableStream({ start(controller) { - controller.enqueue(buffer); + for (let chunk of message.generateChunks()) { + controller.enqueue(chunk); + } controller.close(); }, }), @@ -18,7 +19,11 @@ export async function parse(message: MultipartMessage): Promise { let start = performance.now(); - for await (let part of parseMultipartFormData(request, { maxFileSize: Infinity })) { + let options = { + maxBufferSize: Math.pow(2, 26), + maxFileSize: Infinity, + }; + for await (let _ of parseMultipartFormData(request, options)) { // Do nothing } diff --git a/bench/runner.ts b/bench/runner.ts index 92e37188a7f..6f4cb4276c9 100644 --- a/bench/runner.ts +++ b/bench/runner.ts @@ -1,16 +1,15 @@ import * as os from 'node:os'; -import * as content from './messages.js'; - +import * as messages from './messages.js'; import * as busboy from './parsers/busboy.js'; import * as fastifyBusboy from './parsers/fastify-busboy.js'; import * as fetchMultipartParser from './parsers/fetch-multipart-parser.js'; const benchmarks = [ - { name: '1 small file', message: content.oneSmallFile }, - { name: '1 large file', message: content.oneLargeFile }, - { name: '100 small files', message: content.oneHundredSmallFiles }, - { name: '5 large files', message: content.fiveLargeFiles }, + { name: '1 small file', message: messages.oneSmallFile }, + { name: '1 large file', message: messages.oneLargeFile }, + { name: '100 small files', message: messages.oneHundredSmallFiles }, + { name: '5 large files', message: messages.fiveLargeFiles }, ]; function getMeanAndStdDev(measurements: number[]): string { @@ -21,7 +20,7 @@ function getMeanAndStdDev(measurements: number[]): string { } interface Parser { - parse(message: content.MultipartMessage): Promise; + parse(message: messages.MultipartMessage): Promise; } async function runParserBenchmarks( diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 58480d80329..7a97944d679 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -7,30 +7,16 @@ import { MultipartParseError, parseMultipartFormData } from './multipart.js'; const CRLF = '\r\n'; -function createReadableStream( - content: string, - chunkSize = 1024 * 16 // 16 KB is default on node servers -): ReadableStream { +function* generateChunks(content: string, chunkSize = 16 * 1024): Generator { let encoder = new TextEncoder(); + for (let i = 0; i < content.length; i += chunkSize) { + yield encoder.encode(content.slice(i, i + chunkSize)); + } +} - return new ReadableStream({ - start(controller) { - let offset = 0; - - function pushChunk() { - if (offset < content.length) { - let chunk = content.slice(offset, offset + chunkSize); - controller.enqueue(encoder.encode(chunk)); - offset += chunkSize; - setTimeout(pushChunk, 0); - } else { - controller.close(); - } - } - - pushChunk(); - }, - }); +function createReadableStream(content: string, chunkSize?: number): ReadableStream { + // @ts-expect-error ReadableStream.from is not yet in the DOM types + return ReadableStream.from(generateChunks(content, chunkSize)); } function createMockRequest({ From eb3282d40e1deec71d38debaf32a2108ae251f0e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 22 Jul 2024 11:56:56 -0600 Subject: [PATCH 079/730] Rename RingBuffer#find => RingBuffer#indexOf --- src/lib/multipart.ts | 2 +- src/lib/ring-buffer.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 0ea80fc1c7e..6542dbe0ef8 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -150,7 +150,7 @@ export class MultipartParser { let parts: MultipartPart[] = []; while (true) { - let nextBoundaryIndex = this.buffer.find( + let nextBoundaryIndex = this.buffer.indexOf( this.boundaryArray, this.boundarySearchIndex, this.boundarySkipTable diff --git a/src/lib/ring-buffer.ts b/src/lib/ring-buffer.ts index 732e2a1786d..6af7f91888f 100644 --- a/src/lib/ring-buffer.ts +++ b/src/lib/ring-buffer.ts @@ -128,7 +128,7 @@ export class RingBuffer { /** * Returns the index of the first occurrence of `needle` in the buffer starting at `offset`. */ - find(needle: Uint8Array, offset = 0, skipTable = RingBuffer.computeSkipTable(needle)): number { + indexOf(needle: Uint8Array, offset = 0, skipTable = RingBuffer.computeSkipTable(needle)): number { // boyer-moore-horspool algorithm if (needle.length === 0 || needle.length > this._length - offset) { return -1; From 589c599f3c86005b3a59a110eed810f94a68e48c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 25 Jul 2024 22:42:40 -0600 Subject: [PATCH 080/730] More efficient RingBuffer implementation --- src/lib/multipart.ts | 39 ++-- src/lib/ring-buffer.spec.ts | 404 ++++++++++++++++++++++++------------ src/lib/ring-buffer.ts | 203 ++++++++++-------- 3 files changed, 410 insertions(+), 236 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 6542dbe0ef8..579667309e3 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -18,7 +18,7 @@ export class MultipartParseError extends Error { } export interface MultipartParseOptions { - initialBufferSize?: number; + maxBufferSize?: number; maxHeaderSize?: number; maxFileSize?: number; } @@ -125,19 +125,32 @@ export class MultipartParser { public done = false; private boundaryArray: Uint8Array; + private boundaryLength: number; private boundarySkipTable: Uint8Array; + private boundarySearchOffset: number; + private initialBoundaryFound = false; private maxHeaderSize: number; private maxFileSize: number; - private boundarySearchIndex: number; - private initialBoundaryFound = false; - constructor(public boundary: string, options: MultipartParseOptions = {}) { + constructor( + public boundary: string, + { + maxBufferSize = Math.pow(2, 25), // 32 MB + maxHeaderSize = 8 * 1024, // 8 KB + maxFileSize = 10 * 1024 * 1024, // 10 MB + }: MultipartParseOptions = {} + ) { + if ((maxBufferSize & (maxBufferSize - 1)) !== 0) { + throw new Error('Max buffer size must be a power of 2'); + } + this.boundaryArray = textEncoder.encode(`--${boundary}`); - this.boundarySearchIndex = 0; + this.boundaryLength = this.boundaryArray.length; + this.boundarySearchOffset = 0; this.boundarySkipTable = RingBuffer.computeSkipTable(this.boundaryArray); - this.buffer = new RingBuffer(options.initialBufferSize || 16 * 1024); - this.maxHeaderSize = options.maxHeaderSize || 1024 * 1024; - this.maxFileSize = options.maxFileSize || 10 * 1024 * 1024; + this.buffer = new RingBuffer(64 * 1024, maxBufferSize); + this.maxHeaderSize = maxHeaderSize; + this.maxFileSize = maxFileSize; } push(chunk: Uint8Array): MultipartPart[] { @@ -152,17 +165,17 @@ export class MultipartParser { while (true) { let nextBoundaryIndex = this.buffer.indexOf( this.boundaryArray, - this.boundarySearchIndex, + this.boundarySearchOffset, this.boundarySkipTable ); if (nextBoundaryIndex === -1) { // No boundary found, begin the boundary search on the next iteration from // the start of the last potential boundary sequence - this.boundarySearchIndex = Math.max(0, this.buffer.length - this.boundaryArray.length); + this.boundarySearchOffset = Math.max(0, this.buffer.length - this.boundaryLength); break; } else { - this.boundarySearchIndex = 0; + this.boundarySearchOffset = 0; } if (this.initialBoundaryFound) { @@ -189,10 +202,10 @@ export class MultipartParser { parts.push(new MultipartPart(headerArray, contentArray)); - this.buffer.skip(2 + this.boundaryArray.length); // Skip \r\n + boundary + this.buffer.skip(2 + this.boundaryLength); // Skip \r\n + boundary } else { this.initialBoundaryFound = true; - this.buffer.skip(this.boundaryArray.length); // Skip the boundary + this.buffer.skip(this.boundaryLength); // Skip the boundary } if (this.buffer.length > 1) { diff --git a/src/lib/ring-buffer.spec.ts b/src/lib/ring-buffer.spec.ts index bc4223607db..ad33d1c2c7d 100644 --- a/src/lib/ring-buffer.spec.ts +++ b/src/lib/ring-buffer.spec.ts @@ -4,168 +4,308 @@ import { describe, it } from 'node:test'; import { RingBuffer } from './ring-buffer.js'; describe('RingBuffer', () => { - it('handles initialization with the correct capacity', () => { - let buffer = new RingBuffer(10); - assert.equal(buffer.capacity, 10); - assert.equal(buffer.length, 0); - }); + describe('constructor', () => { + it('handles initialization with the correct capacity', () => { + let buffer = new RingBuffer(16); + assert.equal(buffer.capacity, 16); + assert.equal(buffer.length, 0); + }); - it('handles appending data correctly', () => { - let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2, 3])); - assert.equal(buffer.length, 3); - assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); + it('throws an error when exceeding the maximum capacity', () => { + let buffer = new RingBuffer(8, 16); + buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + assert.throws(() => buffer.append(new Uint8Array([9, 10, 11, 12, 13, 14, 15, 16, 17])), { + name: 'Error', + message: 'New capacity exceeds max capacity', + }); + }); }); - it('handles appending an empty array', () => { - let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2])); - buffer.append(new Uint8Array([])); - assert.equal(buffer.length, 2); - assert.deepEqual(buffer.read(2), new Uint8Array([1, 2])); + describe('capacity management', () => { + it('handles resizing the buffer when necessary', () => { + let buffer = new RingBuffer(8, 16); + buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + buffer.append(new Uint8Array([9, 10, 11, 12, 13, 14, 15, 16])); + assert.equal(buffer.capacity, 16); + assert.equal(buffer.length, 16); + assert.deepEqual( + buffer.read(16), + new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) + ); + }); + + it('handles multiple resize operations', () => { + let buffer = new RingBuffer(2, 8); + buffer.append(new Uint8Array([1, 2])); + buffer.append(new Uint8Array([3, 4])); + buffer.append(new Uint8Array([5, 6])); + assert.equal(buffer.capacity, 8); + assert.equal(buffer.length, 6); + assert.deepEqual(buffer.read(6), new Uint8Array([1, 2, 3, 4, 5, 6])); + }); }); - it('handles appending data larger than initial capacity', () => { - let buffer = new RingBuffer(3); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - assert.equal(buffer.capacity, 6); - assert.equal(buffer.length, 5); - assert.deepEqual(buffer.read(5), new Uint8Array([1, 2, 3, 4, 5])); + describe('at', () => { + it('returns the value of a byte at a given index', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + assert.equal(buffer.at(0), 1); + assert.equal(buffer.at(1), 2); + assert.equal(buffer.at(2), 3); + assert.equal(buffer.at(3), 4); + assert.equal(buffer.at(4), 5); + assert.equal(buffer.at(5), undefined); + assert.equal(buffer.at(-1), 5); + assert.equal(buffer.at(-2), 4); + assert.equal(buffer.at(-3), 3); + assert.equal(buffer.at(-4), 2); + assert.equal(buffer.at(-5), 1); + assert.equal(buffer.at(-6), undefined); + }); }); - it('handles appending data that exactly fills the remaining capacity', () => { - let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2, 3])); - assert.equal(buffer.length, 3); - assert.equal(buffer.capacity, 5); + describe('append', () => { + it('handles appending data correctly', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3])); + assert.equal(buffer.length, 3); + assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); + }); - // This should exactly fill the remaining capacity - buffer.append(new Uint8Array([4, 5])); + it('handles appending an empty array', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2])); + buffer.append(new Uint8Array([])); + assert.equal(buffer.length, 2); + assert.deepEqual(buffer.read(2), new Uint8Array([1, 2])); + }); - assert.equal(buffer.length, 5); - assert.equal(buffer.capacity, 5); + it('handles appending data larger than initial capacity', () => { + let buffer = new RingBuffer(4, 8); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + assert.equal(buffer.capacity, 8); + assert.equal(buffer.length, 5); + assert.deepEqual(buffer.read(5), new Uint8Array([1, 2, 3, 4, 5])); + }); - // This should trigger a resize - buffer.append(new Uint8Array([6])); + it('handles appending data that exactly fills the remaining capacity', () => { + let buffer = new RingBuffer(8, 16); + buffer.append(new Uint8Array([1, 2, 3])); + assert.equal(buffer.length, 3); + assert.equal(buffer.capacity, 8); - assert.equal(buffer.length, 6); - assert.ok(buffer.capacity > 5, 'Buffer should have resized'); + buffer.append(new Uint8Array([4, 5, 6, 7, 8])); + assert.equal(buffer.length, 8); + assert.equal(buffer.capacity, 8); - // Verify the content - assert.deepEqual(buffer.read(6), new Uint8Array([1, 2, 3, 4, 5, 6])); - }); + buffer.append(new Uint8Array([9])); + assert.equal(buffer.length, 9); + assert.equal(buffer.capacity, 16); - it('handles appending data that causes multiple wraps', () => { - let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - assert.deepEqual(buffer.read(2), new Uint8Array([1, 2])); - buffer.append(new Uint8Array([6, 7])); - // Append more data that will cause another wrap and resize - buffer.append(new Uint8Array([8, 9, 10, 11, 12])); - assert.deepEqual(buffer.read(10), new Uint8Array([3, 4, 5, 6, 7, 8, 9, 10, 11, 12])); - }); + assert.deepEqual(buffer.read(9), new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9])); + }); - it('handles reading data correctly', () => { - let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - assert.equal(buffer.length, 5); - assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); - assert.equal(buffer.length, 2); - }); + it('handles appending data that causes multiple wraps', () => { + let buffer = new RingBuffer(8, 32); + buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + assert.deepEqual(buffer.read(2), new Uint8Array([1, 2])); + buffer.append(new Uint8Array([9, 10])); + buffer.append(new Uint8Array([11, 12, 13, 14, 15, 16])); + assert.deepEqual( + buffer.read(14), + new Uint8Array([3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) + ); + }); - it('handles reading zero bytes', () => { - let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2, 3])); - assert.deepEqual(buffer.read(0), new Uint8Array([])); - assert.equal(buffer.length, 3); + it('handles circular behavior when appending', () => { + let buffer = new RingBuffer(8, 16); + buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + buffer.append(new Uint8Array([9, 10])); + assert.equal(buffer.length, 10); + assert.deepEqual(buffer.read(8), new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + }); }); - it('handles reading all data and then appending', () => { - let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2, 3])); - buffer.read(3); - buffer.append(new Uint8Array([4, 5])); - assert.equal(buffer.length, 2); - assert.deepEqual(buffer.read(2), new Uint8Array([4, 5])); - }); + describe('read', () => { + it('handles reading data correctly', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + assert.equal(buffer.length, 5); + assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); + assert.equal(buffer.length, 2); + }); - it('handles circular behavior when appending', () => { - let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - buffer.append(new Uint8Array([6, 7])); - assert.equal(buffer.length, 7); - assert.deepEqual(buffer.read(5), new Uint8Array([1, 2, 3, 4, 5])); - }); + it('handles reading zero bytes', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3])); + assert.deepEqual(buffer.read(0), new Uint8Array([])); + assert.equal(buffer.length, 3); + }); - it('handles circular behavior when reading', () => { - let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2, 3, 4])); - assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); - buffer.append(new Uint8Array([5, 6, 7])); - assert.equal(buffer.length, 4); - assert.deepEqual(buffer.read(4), new Uint8Array([4, 5, 6, 7])); - }); + it('handles reading all data and then appending', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3])); + buffer.read(3); + buffer.append(new Uint8Array([4, 5])); + assert.equal(buffer.length, 2); + assert.deepEqual(buffer.read(2), new Uint8Array([4, 5])); + }); - it('handles resizing the buffer when necessary', () => { - let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - buffer.append(new Uint8Array([6, 7, 8, 9, 10])); - assert.equal(buffer.capacity, 10); - assert.equal(buffer.length, 10); - assert.deepEqual(buffer.read(10), new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])); - }); + it('handles circular behavior when reading', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6])); + assert.deepEqual(buffer.read(4), new Uint8Array([1, 2, 3, 4])); + buffer.append(new Uint8Array([7, 8, 9])); + assert.equal(buffer.length, 5); + assert.deepEqual(buffer.read(5), new Uint8Array([5, 6, 7, 8, 9])); + }); - it('handles reading past the end of the internal buffer', () => { - let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); - buffer.append(new Uint8Array([6, 7, 8])); - assert.equal(buffer.length, 5); - assert.deepEqual(buffer.read(5), new Uint8Array([4, 5, 6, 7, 8])); - assert.equal(buffer.length, 0); - }); + it('handles reading past the end of the internal buffer', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + assert.deepEqual(buffer.read(4), new Uint8Array([1, 2, 3, 4])); + buffer.append(new Uint8Array([9, 10, 11, 12])); + assert.equal(buffer.length, 8); + assert.deepEqual(buffer.read(8), new Uint8Array([5, 6, 7, 8, 9, 10, 11, 12])); + assert.equal(buffer.length, 0); + }); - it('handles multiple resize operations', () => { - let buffer = new RingBuffer(2); - buffer.append(new Uint8Array([1, 2])); - buffer.append(new Uint8Array([3, 4])); - buffer.append(new Uint8Array([5, 6])); - assert.equal(buffer.capacity, 8); - assert.equal(buffer.length, 6); - assert.deepEqual(buffer.read(6), new Uint8Array([1, 2, 3, 4, 5, 6])); - }); + it('throws an error when reading with negative size', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3])); + assert.throws(() => buffer.read(-1), { + name: 'Error', + message: 'Cannot read a negative number of bytes', + }); + }); - it('throws an error when reading with negative size', () => { - let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2, 3])); - assert.throws(() => buffer.read(-1), { - name: 'Error', - message: 'Requested size must be non-negative', + it('throws an error when reading more data than available', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3])); + assert.equal(buffer.length, 3); + assert.throws(() => buffer.read(4), { + name: 'Error', + message: 'Cannot read past the end of the buffer', + }); }); }); - it('handles reading with zero size', () => { - let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2, 3])); - assert.deepEqual(buffer.read(0), new Uint8Array([])); - }); + describe('skip', () => { + it('handles skipping data correctly', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + buffer.skip(2); + assert.equal(buffer.length, 3); + assert.deepEqual(buffer.read(3), new Uint8Array([3, 4, 5])); + }); + + it('handles skipping with wrap-around', () => { + let buffer = new RingBuffer(4); + buffer.append(new Uint8Array([1, 2, 3, 4])); + buffer.skip(3); + buffer.append(new Uint8Array([5, 6])); + assert.equal(buffer.length, 3); + assert.deepEqual(buffer.read(3), new Uint8Array([4, 5, 6])); + }); + + it('handles skipping all data', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3, 4])); + buffer.skip(4); + assert.equal(buffer.length, 0); + buffer.append(new Uint8Array([5, 6])); + assert.deepEqual(buffer.read(2), new Uint8Array([5, 6])); + }); + + it('throws an error when skipping negative number of bytes', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3])); + assert.throws(() => buffer.skip(-1), { + name: 'Error', + message: 'Cannot skip a negative number of bytes', + }); + }); + + it('throws an error when skipping more bytes than available', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3])); + assert.throws(() => buffer.skip(4), { + name: 'Error', + message: 'Cannot skip past the end of the buffer', + }); + }); - it('throws an error when reading more data than available', () => { - let buffer = new RingBuffer(5); - buffer.append(new Uint8Array([1, 2, 3])); - assert.equal(buffer.length, 3); - assert.throws(() => buffer.read(4), { - name: 'Error', - message: 'Requested size is larger than buffer length', + it('handles skipping zero bytes', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3])); + buffer.skip(0); + assert.equal(buffer.length, 3); + assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); }); }); - it('throws an error when exceeding the maximum capacity', () => { - let buffer = new RingBuffer(5, 9); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - assert.throws(() => buffer.append(new Uint8Array([6, 7, 8, 9, 10])), { - name: 'Error', - message: 'Buffer capacity exceeded', + describe('indexOf', () => { + it('finds a simple pattern', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + assert.equal(buffer.indexOf(new Uint8Array([3, 4])), 2); + }); + + it('returns -1 when pattern is not found', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + assert.equal(buffer.indexOf(new Uint8Array([6])), -1); + }); + + it('handles wrap-around search', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + buffer.skip(6); + buffer.append(new Uint8Array([9, 10, 11, 12])); + assert.equal(buffer.indexOf(new Uint8Array([8, 9, 10])), 1); + }); + + it('finds pattern at the beginning', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + assert.equal(buffer.indexOf(new Uint8Array([1, 2])), 0); + }); + + it('finds pattern at the end', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + assert.equal(buffer.indexOf(new Uint8Array([4, 5])), 3); + }); + + it('handles empty needle', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3])); + assert.equal(buffer.indexOf(new Uint8Array([])), 0); + }); + + it('handles search with offset', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3, 1, 2, 3])); + assert.equal(buffer.indexOf(new Uint8Array([1, 2]), 2), 3); + }); + + it('handles string input', () => { + let buffer = new RingBuffer(16); + buffer.append(new TextEncoder().encode('Hello, world!')); + assert.equal(buffer.indexOf('world'), 7); + }); + + it('returns -1 when needle is longer than haystack', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3])); + assert.equal(buffer.indexOf(new Uint8Array([1, 2, 3, 4])), -1); + }); + + it('uses provided skip table', () => { + let buffer = new RingBuffer(8); + buffer.append(new Uint8Array([1, 2, 3, 4, 5])); + let skipTable = RingBuffer.computeSkipTable(new Uint8Array([3, 4])); + assert.equal(buffer.indexOf(new Uint8Array([3, 4]), 0, skipTable), 2); }); }); }); diff --git a/src/lib/ring-buffer.ts b/src/lib/ring-buffer.ts index 6af7f91888f..41ee2685f96 100644 --- a/src/lib/ring-buffer.ts +++ b/src/lib/ring-buffer.ts @@ -1,30 +1,60 @@ /** * A ring buffer that automatically resizes to accomodate more data when it is full. */ -export class RingBuffer { +export class RingBuffer implements RelativeIndexable { + private buffer: Uint8Array; private start = 0; private end = 0; private _length = 0; - private buffer: Uint8Array; + private mask: number; - constructor(initialCapacity: number, public readonly maxCapacity = Infinity) { - if (initialCapacity < 0) { - throw new Error('Initial capacity must be positive'); + /** + * Creates a new ring buffer with the given initial `capacity`, which must be a power of 2. + * The buffer will automatically resize to accomodate more data when it is full, up to the + * given `maxCapacity`. + */ + constructor(capacity: number, public readonly maxCapacity = capacity) { + if ((capacity & (capacity - 1)) !== 0) { + throw new Error('Initial capacity must be a power of 2'); } - if (maxCapacity < initialCapacity) { + if (maxCapacity < capacity) { throw new Error('Max capacity must be greater than or equal to initial capacity'); } - this.buffer = new Uint8Array(initialCapacity); + this.buffer = new Uint8Array(capacity); + this.mask = capacity - 1; } - /** - * The maximum number of bytes the buffer can hold. - */ get capacity(): number { return this.buffer.length; } + set capacity(newCapacity: number) { + if ((newCapacity & (newCapacity - 1)) !== 0) { + throw new Error('New capacity must be a power of 2'); + } + if (newCapacity > this.maxCapacity) { + throw new Error('New capacity exceeds max capacity'); + } + + let newBuffer = new Uint8Array(newCapacity); + + if (this._length !== 0) { + if (this.start < this.end) { + newBuffer.set(this.buffer.subarray(this.start, this.end), 0); + } else { + let firstPart = this.buffer.subarray(this.start); + newBuffer.set(firstPart, 0); + newBuffer.set(this.buffer.subarray(0, this.end), firstPart.length); + } + } + + this.buffer = newBuffer; + this.start = 0; + this.end = this._length; + this.mask = newCapacity - 1; + } + /** * The number of bytes in the buffer. */ @@ -32,42 +62,33 @@ export class RingBuffer { return this._length; } - private resize(newCapacity: number): void { - let newBuffer = new Uint8Array(newCapacity); - let length = this._length; - - if (length === 0) { - this.buffer = newBuffer; - this.start = this.end = 0; - return; + at(index: number): number | undefined { + if (index < -this._length || index >= this._length) { + return undefined; } - if (this.start < this.end) { - newBuffer.set(this.buffer.subarray(this.start, this.end), 0); - } else { - let firstPart = this.buffer.subarray(this.start); - newBuffer.set(firstPart, 0); - newBuffer.set(this.buffer.subarray(0, this.end), firstPart.length); + if (index < 0) { + index = this._length + index; } - this.buffer = newBuffer; - this.start = 0; - this.end = length; + return this.buffer[(this.start + index) & this.mask]; } /** - * Appends a chunk of data to the buffer. If the buffer is full, it will be resized. + * Appends a chunk of data to the buffer. If the buffer is full, it will automatically + * resize to accomodate the new chunk. */ append(chunk: Uint8Array): void { if (chunk.length === 0) return; - if (chunk.length > this.capacity - this._length) { - let minCapacity = this._length + chunk.length; - if (minCapacity > this.maxCapacity) { - throw new Error('Buffer capacity exceeded'); + if (chunk.length + this._length > this.capacity) { + let newCapacity = this.capacity * 2; + while (newCapacity < this._length + chunk.length) { + newCapacity *= 2; } - let newCapacity = Math.min(Math.max(this.capacity * 2, minCapacity), this.maxCapacity); - this.resize(newCapacity); + this.capacity = newCapacity; + + return this.append(chunk); } let spaceToEnd = this.capacity - this.end; @@ -84,102 +105,102 @@ export class RingBuffer { } /** - * Removes and returns the next `size` bytes from the buffer. + * Returns the next `size` bytes from the buffer without removing them. */ - read(size: number): Uint8Array { + peek(size: number): Uint8Array { if (size < 0) { - throw new Error('Requested size must be non-negative'); + throw new Error('Cannot read a negative number of bytes'); } if (size > this._length) { - throw new Error('Requested size is larger than buffer length'); + throw new Error('Cannot read past the end of the buffer'); } - let result = new Uint8Array(size); - + let result: Uint8Array; if (this.start < this.end) { - result.set(this.buffer.subarray(this.start, this.start + size), 0); + result = this.buffer.subarray(this.start, this.start + size); } else { + result = new Uint8Array(size); let firstPart = Math.min(size, this.capacity - this.start); result.set(this.buffer.subarray(this.start, this.start + firstPart), 0); result.set(this.buffer.subarray(0, size - firstPart), firstPart); } - this.start = (this.start + size) % this.capacity; - this._length -= size; - return result; } + /** + * Removes and returns the next `size` bytes from the buffer. + */ + read(size: number): Uint8Array { + let chunk = this.peek(size); + this.skip(size); + return chunk; + } + /** * Removes the next `size` bytes from the buffer without returning them. */ skip(size: number): void { if (size < 0) { - throw new Error('Requested size must be non-negative'); + throw new Error('Cannot skip a negative number of bytes'); } if (size > this._length) { - throw new Error('Requested size is larger than buffer length'); + throw new Error('Cannot skip past the end of the buffer'); } - this.start = (this.start + size) % this.capacity; + this.start = (this.start + size) & this.mask; this._length -= size; } /** - * Returns the index of the first occurrence of `needle` in the buffer starting at `offset`. + * Computes the skip table for the Boyer-Moore-Horspool algorithm. This can be used to + * make indexOf searches more efficient when the needle is known in advance. */ - indexOf(needle: Uint8Array, offset = 0, skipTable = RingBuffer.computeSkipTable(needle)): number { - // boyer-moore-horspool algorithm - if (needle.length === 0 || needle.length > this._length - offset) { - return -1; - } - - let bufferLength = this.buffer.length; - let searchStart = (this.start + offset) % bufferLength; - let remaining = this._length - offset; - - while (remaining >= needle.length) { - let j = needle.length - 1; - let i = searchStart + j; - if (i >= bufferLength) { - i -= bufferLength; - } - - // Check characters from right to left - while (j >= 0 && this.buffer[i] === needle[j]) { - j--; - i = i === 0 ? bufferLength - 1 : i - 1; - } + static computeSkipTable(needle: string | Uint8Array): Uint8Array { + const table = new Uint8Array(256).fill(needle.length); + const lastIndex = needle.length - 1; - if (j < 0) { - // Match found - return offset; - } - - // Shift based on the skip table - let shift = skipTable[this.buffer[i]]; - searchStart += shift; - if (searchStart >= bufferLength) { - searchStart -= bufferLength; - } - offset += shift; - remaining -= shift; + for (let i = 0; i < lastIndex; i++) { + table[typeof needle === 'string' ? needle.charCodeAt(i) : needle[i]] = lastIndex - i; } - return -1; + return table; } /** - * Computes a skip table ahead of time to use later with `buffer.find(needle, skipTable)`. - * This can improve performance when searching for the same `needle` multiple times. + * Searches for the given value in the buffer using the Boyer-Moore-Horspool algorithm. + * Returns the index of the first occurrence if found, or -1 if not. */ - static computeSkipTable(needle: Uint8Array): Uint8Array { - let skipTable = new Uint8Array(256).fill(needle.length); + indexOf( + needle: string | Uint8Array, + offset = 0, + skipTable = RingBuffer.computeSkipTable(needle) + ): number { + if (needle.length === 0) return offset; + if (needle.length > this._length - offset) return -1; + + let needleArray = typeof needle === 'string' ? new TextEncoder().encode(needle) : needle; + let needleLength = needleArray.length; + let lastIndex = needleLength - 1; + + let i = (this.start + offset) & this.mask; + let j = offset; + + while (j < this._length - needleLength + 1) { + let k = lastIndex; + while (k >= 0 && this.buffer[(i + k) & this.mask] === needleArray[k]) { + k--; + } + + if (k < 0) { + return j; // Found a match + } - for (let i = 0; i < needle.length - 1; i++) { - skipTable[needle[i]] = needle.length - 1 - i; + let skip = skipTable[this.buffer[(i + lastIndex) & this.mask]]; + i = (i + skip) & this.mask; + j += skip; } - return skipTable; + return -1; // Not found } } From eea95712d20ea5b1a86d7a9883d1ea53576e4698 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 25 Jul 2024 22:54:39 -0600 Subject: [PATCH 081/730] Rename MultipartParseOptions => MultipartParserOptions --- src/index.ts | 4 ++-- src/lib/multipart.ts | 38 +++++++++++++++++++------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/index.ts b/src/index.ts index fbce68f8f31..cad2547d937 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,9 @@ export { isMultipartFormData, - MultipartParseError, - MultipartParseOptions, parseMultipartFormData, parseMultipartStream, + MultipartParseError, + MultipartParserOptions, MultipartParser, MultipartPart, } from './lib/multipart.js'; diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 579667309e3..d3cd90f89a1 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -10,19 +10,6 @@ export function isMultipartFormData(request: Request): boolean { return contentType != null && contentType.startsWith('multipart/form-data'); } -export class MultipartParseError extends Error { - constructor(message: string) { - super(message); - this.name = 'MultipartParseError'; - } -} - -export interface MultipartParseOptions { - maxBufferSize?: number; - maxHeaderSize?: number; - maxFileSize?: number; -} - /** * Parse a `multipart/form-data` request body and yield each part as a `MultipartPart` object. * @@ -58,7 +45,7 @@ export interface MultipartParseOptions { */ export async function* parseMultipartFormData( request: Request, - options: MultipartParseOptions = {} + options: MultipartParserOptions = {} ): AsyncGenerator { if (!isMultipartFormData(request)) { throw new MultipartParseError('Request is not multipart/form-data'); @@ -88,7 +75,7 @@ export async function* parseMultipartFormData( export async function* parseMultipartStream( stream: ReadableStream, boundary: string, - options: MultipartParseOptions = {} + options: MultipartParserOptions = {} ) { let parser = new MultipartParser(boundary, options); let reader = stream.getReader(); @@ -117,6 +104,19 @@ export async function* parseMultipartStream( const textDecoder = new TextDecoder(); const textEncoder = new TextEncoder(); +export class MultipartParseError extends Error { + constructor(message: string) { + super(message); + this.name = 'MultipartParseError'; + } +} + +export interface MultipartParserOptions { + maxBufferSize?: number; + maxHeaderSize?: number; + maxFileSize?: number; +} + /** * A parser for `multipart/form-data` streams. */ @@ -138,7 +138,7 @@ export class MultipartParser { maxBufferSize = Math.pow(2, 25), // 32 MB maxHeaderSize = 8 * 1024, // 8 KB maxFileSize = 10 * 1024 * 1024, // 10 MB - }: MultipartParseOptions = {} + }: MultipartParserOptions = {} ) { if ((maxBufferSize & (maxBufferSize - 1)) !== 0) { throw new Error('Max buffer size must be a power of 2'); @@ -241,11 +241,11 @@ function findDoubleCRLF(buffer: Uint8Array): number { * A part of a `multipart/form-data` message. */ export class MultipartPart { - private _rawHeader: Uint8Array; + private _headerBytes: Uint8Array; private _headers?: SuperHeaders; constructor(header: Uint8Array, public content: Uint8Array) { - this._rawHeader = header; + this._headerBytes = header; } /** @@ -253,7 +253,7 @@ export class MultipartPart { */ get headers(): SuperHeaders { if (!this._headers) { - this._headers = new SuperHeaders(textDecoder.decode(this._rawHeader)); + this._headers = new SuperHeaders(textDecoder.decode(this._headerBytes)); } return this._headers; From 735cbf72886c67f98f0419ac75bcdf391f6b1a6d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 25 Jul 2024 23:12:40 -0600 Subject: [PATCH 082/730] Update benchmark result in README --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f1f7c52a22c..117dff189c0 100644 --- a/README.md +++ b/README.md @@ -49,12 +49,12 @@ The results of running the benchmarks on my laptop: Platform: Darwin (23.5.0) CPU: Apple M2 Pro Node.js v20.15.1 -Date: 7/18/2024, 12:36:05 PM +Date: 7/25/2024, 11:10:47 PM ┌────────────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├────────────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ fetch-multipart-parser │ '0.02 ms ± 0.10' │ '1.95 ms ± 0.29' │ '0.13 ms ± 0.03' │ '29.52 ms ± 1.46' │ -│ busboy │ '0.03 ms ± 0.11' │ '4.10 ms ± 0.49' │ '0.17 ms ± 0.03' │ '43.38 ms ± 2.96' │ -│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.86 ms ± 0.67' │ '0.32 ms ± 0.04' │ '21.15 ms ± 1.63' │ +│ fetch-multipart-parser │ '0.02 ms ± 0.13' │ '2.70 ms ± 0.20' │ '0.08 ms ± 0.02' │ '27.80 ms ± 2.34' │ +│ busboy │ '0.03 ms ± 0.11' │ '4.22 ms ± 0.38' │ '0.23 ms ± 0.03' │ '46.78 ms ± 2.32' │ +│ @fastify/busboy │ '0.03 ms ± 0.08' │ '2.20 ms ± 0.37' │ '0.38 ms ± 0.04' │ '27.18 ms ± 2.08' │ └────────────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ ``` From 5259d5f003fb2c4cffac0e268cae2bf6b9bd95fc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 25 Jul 2024 23:15:44 -0600 Subject: [PATCH 083/730] Do not use ReadableStream.from --- src/lib/multipart.spec.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 7a97944d679..40fa42192c9 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -15,8 +15,14 @@ function* generateChunks(content: string, chunkSize = 16 * 1024): Generator { - // @ts-expect-error ReadableStream.from is not yet in the DOM types - return ReadableStream.from(generateChunks(content, chunkSize)); + return new ReadableStream({ + start(controller) { + for (let chunk of generateChunks(content, chunkSize)) { + controller.enqueue(chunk); + } + controller.close(); + }, + }); } function createMockRequest({ From 01acf02d02c9efcc01615ee78ceabb487a714546 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 25 Jul 2024 23:55:45 -0600 Subject: [PATCH 084/730] Add part.body stream --- src/lib/multipart.spec.ts | 18 +++++------ src/lib/multipart.ts | 64 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 14 deletions(-) diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 40fa42192c9..57db8639946 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -114,7 +114,7 @@ describe('parseMultipartFormData', async () => { assert.equal(parts.length, 1); assert.equal(parts[0].name, 'field1'); - assert.equal(parts[0].text, 'value1'); + assert.equal(await parts[0].text(), 'value1'); }); it('parses multiple parts correctly', async () => { @@ -130,9 +130,9 @@ describe('parseMultipartFormData', async () => { assert.equal(parts.length, 2); assert.equal(parts[0].name, 'field1'); - assert.equal(parts[0].text, 'value1'); + assert.equal(await parts[0].text(), 'value1'); assert.equal(parts[1].name, 'field2'); - assert.equal(parts[1].text, 'value2'); + assert.equal(await parts[1].text(), 'value2'); }); it('parses empty parts correctly', async () => { @@ -147,7 +147,7 @@ describe('parseMultipartFormData', async () => { assert.equal(parts.length, 1); assert.equal(parts[0].name, 'empty'); - assert.equal(parts[0].content.byteLength, 0); + assert.equal((await parts[0].bytes()).byteLength, 0); }); it('parses file uploads correctly', async () => { @@ -168,7 +168,7 @@ describe('parseMultipartFormData', async () => { assert.equal(parts[0].name, 'file1'); assert.equal(parts[0].filename, 'test.txt'); assert.equal(parts[0].mediaType, 'text/plain'); - assert.equal(parts[0].text, 'File content'); + assert.equal(await parts[0].text(), 'File content'); }); it('parses multiple fields and a file upload', async () => { @@ -189,13 +189,13 @@ describe('parseMultipartFormData', async () => { assert.equal(parts.length, 3); assert.equal(parts[0].name, 'field1'); - assert.equal(parts[0].text, 'value1'); + assert.equal(await parts[0].text(), 'value1'); assert.equal(parts[1].name, 'field2'); - assert.equal(parts[1].text, 'value2'); + assert.equal(await parts[1].text(), 'value2'); assert.equal(parts[2].name, 'file1'); assert.equal(parts[2].filename, 'test.txt'); assert.equal(parts[2].mediaType, 'text/plain'); - assert.equal(parts[2].text, 'File content'); + assert.equal(await parts[2].text(), 'File content'); }); it('throws when Content-Type is not multipart/form-data', async () => { @@ -272,7 +272,7 @@ describe('parseMultipartFormData', async () => { assert.equal(parts.length, 1); assert.equal(parts[0].headers.get('Invalid-Header'), null); - assert.equal(parts[0].text, 'Some content'); + assert.equal(await parts[0].text(), 'Some content'); }); it('throws error when final boundary is missing', async () => { diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index d3cd90f89a1..3817d8d4872 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -200,7 +200,14 @@ export class MultipartParser { ); } - parts.push(new MultipartPart(headerArray, contentArray)); + let body = new ReadableStream({ + start(controller) { + controller.enqueue(contentArray); + controller.close(); + }, + }); + + parts.push(new MultipartPart(headerArray, body)); this.buffer.skip(2 + this.boundaryLength); // Skip \r\n + boundary } else { @@ -243,11 +250,41 @@ function findDoubleCRLF(buffer: Uint8Array): number { export class MultipartPart { private _headerBytes: Uint8Array; private _headers?: SuperHeaders; + private _bodyUsed = false; - constructor(header: Uint8Array, public content: Uint8Array) { + constructor(header: Uint8Array, public readonly body: ReadableStream) { this._headerBytes = header; } + async arrayBuffer(): Promise { + return (await this.bytes()).buffer; + } + + get bodyUsed(): boolean { + return this._bodyUsed; + } + + async bytes(): Promise { + if (this._bodyUsed) { + throw new Error('Body is already consumed or is being consumed'); + } + + this._bodyUsed = true; + + let reader = this.body.getReader(); + let chunks: Uint8Array[] = []; + + while (true) { + const { done, value } = await reader.read(); + + if (done) { + return concatChunks(chunks); + } + + chunks.push(value); + } + } + /** * The headers associated with this part. */ @@ -283,9 +320,26 @@ export class MultipartPart { /** * The content of the part as a string. * - * Note: Do not use this for binary data, use `part.content` instead. + * Note: Do not use this for binary data, use `await part.bytes()` or stream `part.body` directly instead. */ - get text(): string { - return textDecoder.decode(this.content); + async text(): Promise { + return textDecoder.decode(await this.bytes()); + } +} + +function concatChunks(chunks: Uint8Array[]): Uint8Array { + if (chunks.length === 1) { + return chunks[0]; + } + + let length = chunks.reduce((sum, chunk) => sum + chunk.length, 0); + let result = new Uint8Array(length); + let offset = 0; + + for (let i = 0; i < chunks.length; ++i) { + result.set(chunks[i], offset); + offset += chunks[i].length; } + + return result; } From ad19e147bb3473304300357af103267de06c56e9 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 26 Jul 2024 15:19:57 -0700 Subject: [PATCH 085/730] Do not buffer entire files Instead, stream file contents as they arrive in the stream. This is useful for large files that would otherwise consume a lot of memory. This also eliminates the need to resize the buffer when it is full. Instead, use a fixed size buffer and provide a bufferSize option to control the size of the buffer. --- src/lib/multipart.spec.ts | 12 ++- src/lib/multipart.ts | 163 +++++++++++++++++++++--------------- src/lib/ring-buffer.spec.ts | 65 ++------------ src/lib/ring-buffer.ts | 59 ++++--------- 4 files changed, 122 insertions(+), 177 deletions(-) diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 57db8639946..85c2bbbd883 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -226,7 +226,7 @@ describe('parseMultipartFormData', async () => { body: [ `--${boundary}`, 'Content-Disposition: form-data; name="field1"', - 'X-Large-Header: ' + 'a'.repeat(1024 * 1024), // 1MB header + 'X-Large-Header: ' + 'a'.repeat(8 * 1024), // 8 KB header '', 'value1', `--${boundary}--`, @@ -234,7 +234,9 @@ describe('parseMultipartFormData', async () => { }); await assert.rejects(async () => { - await parseMultipartFormData(request, { maxHeaderSize: 1024 }).next(); + for await (let _ of parseMultipartFormData(request, { maxHeaderSize: 4 * 1024 })) { + // Consume all parts + } }, MultipartParseError); }); @@ -253,7 +255,9 @@ describe('parseMultipartFormData', async () => { }); await assert.rejects(async () => { - await parseMultipartFormData(request, { maxFileSize: 1024 * 1024 * 10 }).next(); + for await (let _ of parseMultipartFormData(request, { maxFileSize: 10 * 1024 * 1024 })) { + // Consume all parts + } }, MultipartParseError); }); @@ -290,7 +294,7 @@ describe('parseMultipartFormData', async () => { }); await assert.rejects(async () => { - for await (let part of parseMultipartFormData(request)) { + for await (let _ of parseMultipartFormData(request)) { // Consume all parts } }, MultipartParseError); diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 3817d8d4872..78061b6259d 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -101,6 +101,10 @@ export async function* parseMultipartStream( } } +const HYPHEN = 45; +const DOUBLE_NEWLINE = new Uint8Array([13, 10, 13, 10]); +const DOUBLE_NEWLINE_SKIP_TABLE = RingBuffer.computeSkipTable(DOUBLE_NEWLINE); + const textDecoder = new TextDecoder(); const textEncoder = new TextEncoder(); @@ -112,47 +116,62 @@ export class MultipartParseError extends Error { } export interface MultipartParserOptions { - maxBufferSize?: number; + bufferSize?: number; maxHeaderSize?: number; maxFileSize?: number; } +enum MultipartParserState { + Start = 0, + Header = 1, + Body = 2, + AfterBody = 3, + Done = 4, +} + /** * A parser for `multipart/form-data` streams. */ export class MultipartParser { public buffer: RingBuffer; - public done = false; private boundaryArray: Uint8Array; private boundaryLength: number; private boundarySkipTable: Uint8Array; - private boundarySearchOffset: number; - private initialBoundaryFound = false; private maxHeaderSize: number; private maxFileSize: number; + private state = MultipartParserState.Start; + private bodyController: ReadableStreamDefaultController | null = null; + private bodyLength = 0; + constructor( public boundary: string, { - maxBufferSize = Math.pow(2, 25), // 32 MB + bufferSize = Math.pow(2, 16), // 64 KB maxHeaderSize = 8 * 1024, // 8 KB maxFileSize = 10 * 1024 * 1024, // 10 MB }: MultipartParserOptions = {} ) { - if ((maxBufferSize & (maxBufferSize - 1)) !== 0) { - throw new Error('Max buffer size must be a power of 2'); + if ((bufferSize & (bufferSize - 1)) !== 0) { + throw new Error('bufferSize must be a power of 2'); + } + if (bufferSize <= maxHeaderSize) { + throw new Error('bufferSize must be greater than maxHeaderSize'); } this.boundaryArray = textEncoder.encode(`--${boundary}`); this.boundaryLength = this.boundaryArray.length; - this.boundarySearchOffset = 0; this.boundarySkipTable = RingBuffer.computeSkipTable(this.boundaryArray); - this.buffer = new RingBuffer(64 * 1024, maxBufferSize); + this.buffer = new RingBuffer(bufferSize); this.maxHeaderSize = maxHeaderSize; this.maxFileSize = maxFileSize; } + get done() { + return this.state === MultipartParserState.Done; + } + push(chunk: Uint8Array): MultipartPart[] { if (this.done) { throw new MultipartParseError('Cannot push, parser is done'); @@ -163,97 +182,112 @@ export class MultipartParser { let parts: MultipartPart[] = []; while (true) { - let nextBoundaryIndex = this.buffer.indexOf( - this.boundaryArray, - this.boundarySearchOffset, - this.boundarySkipTable - ); + if (this.state === MultipartParserState.Start) { + if (this.buffer.length < this.boundaryLength + 2) break; - if (nextBoundaryIndex === -1) { - // No boundary found, begin the boundary search on the next iteration from - // the start of the last potential boundary sequence - this.boundarySearchOffset = Math.max(0, this.buffer.length - this.boundaryLength); - break; - } else { - this.boundarySearchOffset = 0; - } + let boundaryIndex = this.buffer.indexOf(this.boundaryArray, 0, this.boundarySkipTable); + if (boundaryIndex !== 0) { + throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); + } - if (this.initialBoundaryFound) { - let partArray = this.buffer.read(nextBoundaryIndex - 2); // -2 to avoid \r\n before the boundary + this.buffer.skip(this.boundaryLength + 2); // Skip boundary + \r\n - let headerEndIndex = findDoubleCRLF(partArray); - if (headerEndIndex === -1) { - throw new MultipartParseError('Invalid part: missing header'); - } + this.state = MultipartParserState.Header; + } else if (this.state === MultipartParserState.Header) { + if (this.buffer.length < 4) break; - let headerArray = partArray.subarray(0, headerEndIndex); - if (headerArray.length > this.maxHeaderSize) { + let headerEndIndex = this.buffer.indexOf(DOUBLE_NEWLINE, 0, DOUBLE_NEWLINE_SKIP_TABLE); + if (headerEndIndex === -1) break; + if (headerEndIndex > this.maxHeaderSize) { throw new MultipartParseError( `Header size exceeds maximum allowed size of ${this.maxHeaderSize} bytes` ); } - let contentArray = partArray.subarray(headerEndIndex + 4); // +4 to skip \r\n\r\n after the header - if (contentArray.length > this.maxFileSize) { - throw new MultipartParseError( - `File size exceeds maximum allowed size of ${this.maxFileSize} bytes` - ); - } + let headerBytes = this.buffer.read(headerEndIndex); + this.buffer.skip(4); // Skip \r\n\r\n let body = new ReadableStream({ - start(controller) { - controller.enqueue(contentArray); - controller.close(); + start: (controller) => { + this.bodyController = controller; }, }); - parts.push(new MultipartPart(headerArray, body)); + parts.push(new MultipartPart(headerBytes, body)); + + this.state = MultipartParserState.Body; + } else if (this.state === MultipartParserState.Body) { + if (this.buffer.length < this.boundaryLength) break; + + let boundaryIndex = this.buffer.indexOf(this.boundaryArray, 0, this.boundarySkipTable); + + if (boundaryIndex === -1) { + // Write as much of the buffer as we can to the current body stream while still + // keeping enough to check if the last few bytes are part of the boundary. + this.writeBody(this.buffer.read(this.buffer.length - this.boundaryLength + 1)); + break; + } + + this.writeBody(this.buffer.read(boundaryIndex - 2)); // -2 to avoid \r\n before boundary + this.finishBody(); this.buffer.skip(2 + this.boundaryLength); // Skip \r\n + boundary - } else { - this.initialBoundaryFound = true; - this.buffer.skip(this.boundaryLength); // Skip the boundary - } - if (this.buffer.length > 1) { - // If the next two bytes are "--", it's the final boundary and we're done. - // Otherwise, it's the \r\n after the boundary and we can discard it. + this.state = MultipartParserState.AfterBody; + } else if (this.state === MultipartParserState.AfterBody) { + if (this.buffer.length < 2) break; + + // If the next two bytes are "--" then we're done; this is the closing boundary. Otherwise + // they're the \r\n after a boundary in the middle of the message and we can ignore them. let twoBytes = this.buffer.read(2); if (twoBytes[0] === HYPHEN && twoBytes[1] === HYPHEN) { - this.done = true; + this.state = MultipartParserState.Done; break; } + + this.state = MultipartParserState.Header; } } return parts; } -} -const HYPHEN = 45; -const CR = 13; -const LF = 10; + private writeBody(chunk: Uint8Array): void { + if (!this.bodyController) { + throw new Error('Body controller is not initialized'); + } -function findDoubleCRLF(buffer: Uint8Array): number { - for (let i = 0; i < buffer.length - 3; i++) { - if (buffer[i] === CR && buffer[i + 1] === LF && buffer[i + 2] === CR && buffer[i + 3] === LF) { - return i; + if (this.bodyLength + chunk.length > this.maxFileSize) { + throw new MultipartParseError( + `File size exceeds maximum allowed size of ${this.maxFileSize} bytes` + ); } + + this.bodyController.enqueue(chunk); + this.bodyLength += chunk.length; } - return -1; + private finishBody(): void { + if (!this.bodyController) { + throw new Error('Body controller is not initialized'); + } + + this.bodyController.close(); + this.bodyController = null; + this.bodyLength = 0; + } } /** * A part of a `multipart/form-data` message. */ export class MultipartPart { - private _headerBytes: Uint8Array; + private _header: Uint8Array; private _headers?: SuperHeaders; private _bodyUsed = false; constructor(header: Uint8Array, public readonly body: ReadableStream) { - this._headerBytes = header; + this._header = header; } async arrayBuffer(): Promise { @@ -276,11 +310,7 @@ export class MultipartPart { while (true) { const { done, value } = await reader.read(); - - if (done) { - return concatChunks(chunks); - } - + if (done) return concatChunks(chunks); chunks.push(value); } } @@ -289,10 +319,7 @@ export class MultipartPart { * The headers associated with this part. */ get headers(): SuperHeaders { - if (!this._headers) { - this._headers = new SuperHeaders(textDecoder.decode(this._headerBytes)); - } - + if (!this._headers) this._headers = new SuperHeaders(textDecoder.decode(this._header)); return this._headers; } diff --git a/src/lib/ring-buffer.spec.ts b/src/lib/ring-buffer.spec.ts index ad33d1c2c7d..a705d91c9c2 100644 --- a/src/lib/ring-buffer.spec.ts +++ b/src/lib/ring-buffer.spec.ts @@ -10,39 +10,6 @@ describe('RingBuffer', () => { assert.equal(buffer.capacity, 16); assert.equal(buffer.length, 0); }); - - it('throws an error when exceeding the maximum capacity', () => { - let buffer = new RingBuffer(8, 16); - buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); - assert.throws(() => buffer.append(new Uint8Array([9, 10, 11, 12, 13, 14, 15, 16, 17])), { - name: 'Error', - message: 'New capacity exceeds max capacity', - }); - }); - }); - - describe('capacity management', () => { - it('handles resizing the buffer when necessary', () => { - let buffer = new RingBuffer(8, 16); - buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); - buffer.append(new Uint8Array([9, 10, 11, 12, 13, 14, 15, 16])); - assert.equal(buffer.capacity, 16); - assert.equal(buffer.length, 16); - assert.deepEqual( - buffer.read(16), - new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) - ); - }); - - it('handles multiple resize operations', () => { - let buffer = new RingBuffer(2, 8); - buffer.append(new Uint8Array([1, 2])); - buffer.append(new Uint8Array([3, 4])); - buffer.append(new Uint8Array([5, 6])); - assert.equal(buffer.capacity, 8); - assert.equal(buffer.length, 6); - assert.deepEqual(buffer.read(6), new Uint8Array([1, 2, 3, 4, 5, 6])); - }); }); describe('at', () => { @@ -80,16 +47,8 @@ describe('RingBuffer', () => { assert.deepEqual(buffer.read(2), new Uint8Array([1, 2])); }); - it('handles appending data larger than initial capacity', () => { - let buffer = new RingBuffer(4, 8); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - assert.equal(buffer.capacity, 8); - assert.equal(buffer.length, 5); - assert.deepEqual(buffer.read(5), new Uint8Array([1, 2, 3, 4, 5])); - }); - it('handles appending data that exactly fills the remaining capacity', () => { - let buffer = new RingBuffer(8, 16); + let buffer = new RingBuffer(8); buffer.append(new Uint8Array([1, 2, 3])); assert.equal(buffer.length, 3); assert.equal(buffer.capacity, 8); @@ -98,31 +57,17 @@ describe('RingBuffer', () => { assert.equal(buffer.length, 8); assert.equal(buffer.capacity, 8); - buffer.append(new Uint8Array([9])); - assert.equal(buffer.length, 9); - assert.equal(buffer.capacity, 16); - - assert.deepEqual(buffer.read(9), new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9])); + assert.deepEqual(buffer.read(8), new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); }); it('handles appending data that causes multiple wraps', () => { - let buffer = new RingBuffer(8, 32); + let buffer = new RingBuffer(8); buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); assert.deepEqual(buffer.read(2), new Uint8Array([1, 2])); buffer.append(new Uint8Array([9, 10])); + assert.deepEqual(buffer.read(8), new Uint8Array([3, 4, 5, 6, 7, 8, 9, 10])); buffer.append(new Uint8Array([11, 12, 13, 14, 15, 16])); - assert.deepEqual( - buffer.read(14), - new Uint8Array([3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) - ); - }); - - it('handles circular behavior when appending', () => { - let buffer = new RingBuffer(8, 16); - buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); - buffer.append(new Uint8Array([9, 10])); - assert.equal(buffer.length, 10); - assert.deepEqual(buffer.read(8), new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); + assert.deepEqual(buffer.read(6), new Uint8Array([11, 12, 13, 14, 15, 16])); }); }); diff --git a/src/lib/ring-buffer.ts b/src/lib/ring-buffer.ts index 41ee2685f96..c1518eb47b2 100644 --- a/src/lib/ring-buffer.ts +++ b/src/lib/ring-buffer.ts @@ -1,5 +1,7 @@ /** - * A ring buffer that automatically resizes to accomodate more data when it is full. + * A fast ring (or "circular") buffer implementation that supports reusing a fixed-size buffer + * by overwriting the oldest data when the buffer is full. This is useful for buffering streaming + * data, such as reading from a file or network socket, before handing off the data to a consumer. */ export class RingBuffer implements RelativeIndexable { private buffer: Uint8Array; @@ -9,52 +11,24 @@ export class RingBuffer implements RelativeIndexable { private mask: number; /** - * Creates a new ring buffer with the given initial `capacity`, which must be a power of 2. - * The buffer will automatically resize to accomodate more data when it is full, up to the - * given `maxCapacity`. + * Creates a new RingBuffer with the given `capacity`, which must be a power of 2. */ - constructor(capacity: number, public readonly maxCapacity = capacity) { + constructor(capacity: number) { if ((capacity & (capacity - 1)) !== 0) { throw new Error('Initial capacity must be a power of 2'); } - if (maxCapacity < capacity) { - throw new Error('Max capacity must be greater than or equal to initial capacity'); - } this.buffer = new Uint8Array(capacity); this.mask = capacity - 1; } + /** + * The total number of bytes this buffer can hold. + */ get capacity(): number { return this.buffer.length; } - set capacity(newCapacity: number) { - if ((newCapacity & (newCapacity - 1)) !== 0) { - throw new Error('New capacity must be a power of 2'); - } - if (newCapacity > this.maxCapacity) { - throw new Error('New capacity exceeds max capacity'); - } - - let newBuffer = new Uint8Array(newCapacity); - - if (this._length !== 0) { - if (this.start < this.end) { - newBuffer.set(this.buffer.subarray(this.start, this.end), 0); - } else { - let firstPart = this.buffer.subarray(this.start); - newBuffer.set(firstPart, 0); - newBuffer.set(this.buffer.subarray(0, this.end), firstPart.length); - } - } - - this.buffer = newBuffer; - this.start = 0; - this.end = this._length; - this.mask = newCapacity - 1; - } - /** * The number of bytes in the buffer. */ @@ -75,20 +49,13 @@ export class RingBuffer implements RelativeIndexable { } /** - * Appends a chunk of data to the buffer. If the buffer is full, it will automatically - * resize to accomodate the new chunk. + * Appends a chunk of data to the buffer. */ append(chunk: Uint8Array): void { if (chunk.length === 0) return; if (chunk.length + this._length > this.capacity) { - let newCapacity = this.capacity * 2; - while (newCapacity < this._length + chunk.length) { - newCapacity *= 2; - } - this.capacity = newCapacity; - - return this.append(chunk); + throw new Error(`Cannot append to buffer, it is full`); } let spaceToEnd = this.capacity - this.end; @@ -138,7 +105,8 @@ export class RingBuffer implements RelativeIndexable { } /** - * Removes the next `size` bytes from the buffer without returning them. + * Removes the next `size` bytes from the buffer without returning them, effectively "skipping" + * them and discarding the data. */ skip(size: number): void { if (size < 0) { @@ -154,7 +122,8 @@ export class RingBuffer implements RelativeIndexable { /** * Computes the skip table for the Boyer-Moore-Horspool algorithm. This can be used to - * make indexOf searches more efficient when the needle is known in advance. + * precompute the 3rd argument to `indexOf` to make searches more efficient when the needle + * is known in advance. */ static computeSkipTable(needle: string | Uint8Array): Uint8Array { const table = new Uint8Array(256).fill(needle.length); From 5905149f8de4f78107ebcbcb64dbd9fa3a1a444f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 26 Jul 2024 16:05:40 -0700 Subject: [PATCH 086/730] Update benchmark --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 117dff189c0..b0fa2046513 100644 --- a/README.md +++ b/README.md @@ -49,12 +49,12 @@ The results of running the benchmarks on my laptop: Platform: Darwin (23.5.0) CPU: Apple M2 Pro Node.js v20.15.1 -Date: 7/25/2024, 11:10:47 PM +Date: 7/26/2024, 4:04:11 PM ┌────────────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├────────────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ fetch-multipart-parser │ '0.02 ms ± 0.13' │ '2.70 ms ± 0.20' │ '0.08 ms ± 0.02' │ '27.80 ms ± 2.34' │ -│ busboy │ '0.03 ms ± 0.11' │ '4.22 ms ± 0.38' │ '0.23 ms ± 0.03' │ '46.78 ms ± 2.32' │ -│ @fastify/busboy │ '0.03 ms ± 0.08' │ '2.20 ms ± 0.37' │ '0.38 ms ± 0.04' │ '27.18 ms ± 2.08' │ +│ fetch-multipart-parser │ '0.02 ms ± 0.13' │ '2.03 ms ± 0.75' │ '0.34 ms ± 0.15' │ '21.86 ms ± 2.24' │ +│ busboy │ '0.03 ms ± 0.09' │ '4.11 ms ± 0.20' │ '0.23 ms ± 0.03' │ '45.13 ms ± 3.22' │ +│ @fastify/busboy │ '0.03 ms ± 0.08' │ '2.05 ms ± 0.20' │ '0.38 ms ± 0.04' │ '27.88 ms ± 2.84' │ └────────────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ ``` From 6edf9401ecf992fa59083c98daca3baa15424b56 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 26 Jul 2024 16:21:16 -0700 Subject: [PATCH 087/730] Update example in README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b0fa2046513..1882f218e86 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ $ npm install fetch-multipart-parser ```typescript import { MultipartParseError, parseMultipartFormData } from 'fetch-multipart-parser'; -function handleMultipartRequest(request: Request): void { +async function handleMultipartRequest(request: Request): void { try { // The parser `yield`s each part as a MultipartPart as it becomes available. for await (let part of parseMultipartFormData(request)) { @@ -26,9 +26,9 @@ function handleMultipartRequest(request: Request): void { console.log(part.mediaType); if (/^text\//.test(part.mediaType)) { - console.log(new TextDecoder().decode(part.content)); + console.log(await part.text()); } else { - // part.content is binary data, save it to a file + // TODO: part.body is a ReadableStream, stream it to a file } } } catch (error) { From 3d05947e6f5e3b2f8e090ee4e597af27362dbffc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 27 Jul 2024 00:09:21 -0700 Subject: [PATCH 088/730] Add test for empty multipart messages --- src/lib/multipart.spec.ts | 71 +++++++++++++++++++-------------- src/lib/multipart.ts | 84 ++++++++++++++++++++++++++------------- 2 files changed, 98 insertions(+), 57 deletions(-) diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 85c2bbbd883..4f08a2b196f 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -47,37 +47,39 @@ type PartValue = content: string; }; -function createMultipartBody(boundary: string, parts: { [name: string]: PartValue }): string { +function createMultipartBody(boundary: string, parts?: { [name: string]: PartValue }): string { let lines = []; - for (let [name, part] of Object.entries(parts)) { - lines.push(`--${boundary}`); - - if (typeof part === 'string') { - let contentDisposition = new ContentDisposition(); - contentDisposition.type = 'form-data'; - contentDisposition.name = name; - lines.push(`Content-Disposition: ${contentDisposition}`); - lines.push(''); - lines.push(part); - } else { - let contentDisposition = new ContentDisposition(); - contentDisposition.type = 'form-data'; - contentDisposition.name = name; - contentDisposition.filename = part.filename; - contentDisposition.filenameSplat = part.filenameSplat; - - lines.push(`Content-Disposition: ${contentDisposition}`); - - if (part.mediaType) { - let contentType = new ContentType(); - contentType.mediaType = part.mediaType; - - lines.push(`Content-Type: ${contentType}`); + if (parts) { + for (let [name, part] of Object.entries(parts)) { + lines.push(`--${boundary}`); + + if (typeof part === 'string') { + let contentDisposition = new ContentDisposition(); + contentDisposition.type = 'form-data'; + contentDisposition.name = name; + lines.push(`Content-Disposition: ${contentDisposition}`); + lines.push(''); + lines.push(part); + } else { + let contentDisposition = new ContentDisposition(); + contentDisposition.type = 'form-data'; + contentDisposition.name = name; + contentDisposition.filename = part.filename; + contentDisposition.filenameSplat = part.filenameSplat; + + lines.push(`Content-Disposition: ${contentDisposition}`); + + if (part.mediaType) { + let contentType = new ContentType(); + contentType.mediaType = part.mediaType; + + lines.push(`Content-Type: ${contentType}`); + } + + lines.push(''); + lines.push(part.content); } - - lines.push(''); - lines.push(part.content); } } @@ -88,7 +90,7 @@ function createMultipartBody(boundary: string, parts: { [name: string]: PartValu function createMultipartMockRequest( boundary: string, - parts: { [name: string]: PartValue } + parts?: { [name: string]: PartValue } ): Request { let headers = new SuperHeaders(); headers.contentType.mediaType = 'multipart/form-data'; @@ -102,6 +104,17 @@ function createMultipartMockRequest( describe('parseMultipartFormData', async () => { let boundary = 'boundary123'; + it('parses an empty multipart message', async () => { + let request = createMultipartMockRequest(boundary); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 0); + }); + it('parses a simple multipart form', async () => { let request = createMultipartMockRequest(boundary, { field1: 'value1', diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 78061b6259d..1bb94376569 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -123,9 +123,9 @@ export interface MultipartParserOptions { enum MultipartParserState { Start = 0, - Header = 1, - Body = 2, - AfterBody = 3, + AfterBoundary = 1, + Header = 2, + Body = 3, Done = 4, } @@ -183,17 +183,33 @@ export class MultipartParser { while (true) { if (this.state === MultipartParserState.Start) { - if (this.buffer.length < this.boundaryLength + 2) break; + if (this.buffer.length < this.boundaryLength) break; let boundaryIndex = this.buffer.indexOf(this.boundaryArray, 0, this.boundarySkipTable); if (boundaryIndex !== 0) { throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); } - this.buffer.skip(this.boundaryLength + 2); // Skip boundary + \r\n + this.buffer.skip(this.boundaryLength); + + this.state = MultipartParserState.AfterBoundary; + } + + if (this.state === MultipartParserState.AfterBoundary) { + if (this.buffer.length < 2) break; + + // If the next two bytes are "--" then we're done; this is the closing boundary. Otherwise + // they're the \r\n after a boundary in the middle of the message and we can ignore them. + let twoBytes = this.buffer.read(2); + if (twoBytes[0] === HYPHEN && twoBytes[1] === HYPHEN) { + this.state = MultipartParserState.Done; + break; + } this.state = MultipartParserState.Header; - } else if (this.state === MultipartParserState.Header) { + } + + if (this.state === MultipartParserState.Header) { if (this.buffer.length < 4) break; let headerEndIndex = this.buffer.indexOf(DOUBLE_NEWLINE, 0, DOUBLE_NEWLINE_SKIP_TABLE); @@ -216,7 +232,9 @@ export class MultipartParser { parts.push(new MultipartPart(headerBytes, body)); this.state = MultipartParserState.Body; - } else if (this.state === MultipartParserState.Body) { + } + + if (this.state === MultipartParserState.Body) { if (this.buffer.length < this.boundaryLength) break; let boundaryIndex = this.buffer.indexOf(this.boundaryArray, 0, this.boundarySkipTable); @@ -233,19 +251,7 @@ export class MultipartParser { this.buffer.skip(2 + this.boundaryLength); // Skip \r\n + boundary - this.state = MultipartParserState.AfterBody; - } else if (this.state === MultipartParserState.AfterBody) { - if (this.buffer.length < 2) break; - - // If the next two bytes are "--" then we're done; this is the closing boundary. Otherwise - // they're the \r\n after a boundary in the middle of the message and we can ignore them. - let twoBytes = this.buffer.read(2); - if (twoBytes[0] === HYPHEN && twoBytes[1] === HYPHEN) { - this.state = MultipartParserState.Done; - break; - } - - this.state = MultipartParserState.Header; + this.state = MultipartParserState.AfterBoundary; } } @@ -290,14 +296,23 @@ export class MultipartPart { this._header = header; } + /** + * The content of this part as an `ArrayBuffer`. + */ async arrayBuffer(): Promise { return (await this.bytes()).buffer; } + /** + * Whether the body of this part has been consumed. + */ get bodyUsed(): boolean { return this._bodyUsed; } + /** + * The content of this part as a `Uint8Array`. + */ async bytes(): Promise { if (this._bodyUsed) { throw new Error('Body is already consumed or is being consumed'); @@ -305,14 +320,7 @@ export class MultipartPart { this._bodyUsed = true; - let reader = this.body.getReader(); - let chunks: Uint8Array[] = []; - - while (true) { - const { done, value } = await reader.read(); - if (done) return concatChunks(chunks); - chunks.push(value); - } + return bufferStream(this.body); } /** @@ -354,6 +362,26 @@ export class MultipartPart { } } +async function bufferStream(stream: ReadableStream): Promise { + let reader = stream.getReader(); + + try { + let chunks: Uint8Array[] = []; + + while (true) { + const { done, value } = await reader.read(); + + if (done) { + return concatChunks(chunks); + } + + chunks.push(value); + } + } finally { + reader.releaseLock(); + } +} + function concatChunks(chunks: Uint8Array[]): Uint8Array { if (chunks.length === 1) { return chunks[0]; From 6dc7591a25b18d21859656ac34a832e706e07fb8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 27 Jul 2024 00:24:23 -0700 Subject: [PATCH 089/730] Update benchmark --- README.md | 8 ++++---- src/lib/multipart.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1882f218e86..375426e1835 100644 --- a/README.md +++ b/README.md @@ -49,12 +49,12 @@ The results of running the benchmarks on my laptop: Platform: Darwin (23.5.0) CPU: Apple M2 Pro Node.js v20.15.1 -Date: 7/26/2024, 4:04:11 PM +Date: 7/27/2024, 12:11:40 AM ┌────────────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├────────────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ fetch-multipart-parser │ '0.02 ms ± 0.13' │ '2.03 ms ± 0.75' │ '0.34 ms ± 0.15' │ '21.86 ms ± 2.24' │ -│ busboy │ '0.03 ms ± 0.09' │ '4.11 ms ± 0.20' │ '0.23 ms ± 0.03' │ '45.13 ms ± 3.22' │ -│ @fastify/busboy │ '0.03 ms ± 0.08' │ '2.05 ms ± 0.20' │ '0.38 ms ± 0.04' │ '27.88 ms ± 2.84' │ +│ fetch-multipart-parser │ '0.03 ms ± 0.13' │ '1.91 ms ± 0.36' │ '0.35 ms ± 0.17' │ '21.70 ms ± 1.51' │ +│ busboy │ '0.03 ms ± 0.09' │ '4.17 ms ± 0.16' │ '0.23 ms ± 0.03' │ '46.71 ms ± 3.37' │ +│ @fastify/busboy │ '0.03 ms ± 0.09' │ '2.10 ms ± 0.19' │ '0.38 ms ± 0.04' │ '28.56 ms ± 2.38' │ └────────────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ ``` diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 1bb94376569..4ac5a81642c 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -76,7 +76,7 @@ export async function* parseMultipartStream( stream: ReadableStream, boundary: string, options: MultipartParserOptions = {} -) { +): AsyncGenerator { let parser = new MultipartParser(boundary, options); let reader = stream.getReader(); From 26665fac334b46276f963668726a55e7cd53c412 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 27 Jul 2024 00:30:05 -0700 Subject: [PATCH 090/730] Rename variable --- src/lib/multipart.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 4ac5a81642c..96f3e26ce41 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -220,7 +220,7 @@ export class MultipartParser { ); } - let headerBytes = this.buffer.read(headerEndIndex); + let header = this.buffer.read(headerEndIndex); this.buffer.skip(4); // Skip \r\n\r\n let body = new ReadableStream({ @@ -229,7 +229,7 @@ export class MultipartParser { }, }); - parts.push(new MultipartPart(headerBytes, body)); + parts.push(new MultipartPart(header, body)); this.state = MultipartParserState.Body; } From 3c6ccfa631d56a427d851a150cd24be1240acb52 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 27 Jul 2024 00:32:58 -0700 Subject: [PATCH 091/730] Remove maxBufferSize option --- bench/parsers/fetch-multipart-parser.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/bench/parsers/fetch-multipart-parser.ts b/bench/parsers/fetch-multipart-parser.ts index 9c0f77d6f33..8a772ddf4d3 100644 --- a/bench/parsers/fetch-multipart-parser.ts +++ b/bench/parsers/fetch-multipart-parser.ts @@ -19,11 +19,7 @@ export async function parse(message: MultipartMessage): Promise { let start = performance.now(); - let options = { - maxBufferSize: Math.pow(2, 26), - maxFileSize: Infinity, - }; - for await (let _ of parseMultipartFormData(request, options)) { + for await (let _ of parseMultipartFormData(request, { maxFileSize: Infinity })) { // Do nothing } From 7ef573f5af8ccc8ae8e28b778e060ecbf7d7ea67 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 27 Jul 2024 07:33:39 -0700 Subject: [PATCH 092/730] Move start check out of inner loop --- src/lib/multipart.ts | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 96f3e26ce41..9dd0728e6aa 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -133,11 +133,10 @@ enum MultipartParserState { * A parser for `multipart/form-data` streams. */ export class MultipartParser { - public buffer: RingBuffer; - private boundaryArray: Uint8Array; private boundaryLength: number; private boundarySkipTable: Uint8Array; + private buffer: RingBuffer; private maxHeaderSize: number; private maxFileSize: number; @@ -181,20 +180,20 @@ export class MultipartParser { let parts: MultipartPart[] = []; - while (true) { - if (this.state === MultipartParserState.Start) { - if (this.buffer.length < this.boundaryLength) break; + if (this.state === MultipartParserState.Start) { + if (this.buffer.length < this.boundaryLength) return parts; - let boundaryIndex = this.buffer.indexOf(this.boundaryArray, 0, this.boundarySkipTable); - if (boundaryIndex !== 0) { - throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); - } + let boundaryIndex = this.buffer.indexOf(this.boundaryArray, 0, this.boundarySkipTable); + if (boundaryIndex !== 0) { + throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); + } - this.buffer.skip(this.boundaryLength); + this.buffer.skip(this.boundaryLength); - this.state = MultipartParserState.AfterBoundary; - } + this.state = MultipartParserState.AfterBoundary; + } + while (true) { if (this.state === MultipartParserState.AfterBoundary) { if (this.buffer.length < 2) break; From 9e6233c2a8ea28c31acb5e40c205b2bb53765df7 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 27 Jul 2024 14:39:22 -0700 Subject: [PATCH 093/730] Remove unnecessary checks --- src/lib/multipart.ts | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 9dd0728e6aa..09ee2b3a836 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -246,7 +246,7 @@ export class MultipartParser { } this.writeBody(this.buffer.read(boundaryIndex - 2)); // -2 to avoid \r\n before boundary - this.finishBody(); + this.closeBody(); this.buffer.skip(2 + this.boundaryLength); // Skip \r\n + boundary @@ -258,26 +258,18 @@ export class MultipartParser { } private writeBody(chunk: Uint8Array): void { - if (!this.bodyController) { - throw new Error('Body controller is not initialized'); - } - if (this.bodyLength + chunk.length > this.maxFileSize) { throw new MultipartParseError( `File size exceeds maximum allowed size of ${this.maxFileSize} bytes` ); } - this.bodyController.enqueue(chunk); + this.bodyController!.enqueue(chunk); this.bodyLength += chunk.length; } - private finishBody(): void { - if (!this.bodyController) { - throw new Error('Body controller is not initialized'); - } - - this.bodyController.close(); + private closeBody(): void { + this.bodyController!.close(); this.bodyController = null; this.bodyLength = 0; } From dd099c5a5374b2f63e8180c44b03bc6aa9070877 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 27 Jul 2024 15:18:07 -0700 Subject: [PATCH 094/730] Use Yaml format --- .prettierrc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.prettierrc b/.prettierrc index 0aac4a10c5e..f018274ffc2 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,6 +1,4 @@ -{ - "printWidth": 100, - "singleQuote": true, - "semi": true, - "useTabs": false -} +printWidth: 100 +semi: true +singleQuote: true +useTabs: false From 4f0b347a3b9d3d745c88fe7b40ca3276af1f7794 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 27 Jul 2024 18:34:14 -0700 Subject: [PATCH 095/730] Always return a new buffer from RingBuffer#peek --- src/lib/ring-buffer.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lib/ring-buffer.ts b/src/lib/ring-buffer.ts index c1518eb47b2..315a0783bcd 100644 --- a/src/lib/ring-buffer.ts +++ b/src/lib/ring-buffer.ts @@ -82,16 +82,16 @@ export class RingBuffer implements RelativeIndexable { throw new Error('Cannot read past the end of the buffer'); } - let result: Uint8Array; if (this.start < this.end) { - result = this.buffer.subarray(this.start, this.start + size); - } else { - result = new Uint8Array(size); - let firstPart = Math.min(size, this.capacity - this.start); - result.set(this.buffer.subarray(this.start, this.start + firstPart), 0); - result.set(this.buffer.subarray(0, size - firstPart), firstPart); + return this.buffer.slice(this.start, this.start + size); } + let result = new Uint8Array(size); + + let firstPart = Math.min(size, this.capacity - this.start); + result.set(this.buffer.subarray(this.start, this.start + firstPart), 0); + result.set(this.buffer.subarray(0, size - firstPart), firstPart); + return result; } @@ -146,7 +146,7 @@ export class RingBuffer implements RelativeIndexable { skipTable = RingBuffer.computeSkipTable(needle) ): number { if (needle.length === 0) return offset; - if (needle.length > this._length - offset) return -1; + if (needle.length > this._length) return -1; let needleArray = typeof needle === 'string' ? new TextEncoder().encode(needle) : needle; let needleLength = needleArray.length; From d2bbdc1d19129d19316b613e5b03f31cb4bf18ec Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 27 Jul 2024 21:09:02 -0700 Subject: [PATCH 096/730] Inline buffer management --- README.md | 8 +- src/lib/multipart.spec.ts | 2 +- src/lib/multipart.ts | 194 ++++++++++++++++++++------- src/lib/ring-buffer.spec.ts | 256 ------------------------------------ src/lib/ring-buffer.ts | 175 ------------------------ 5 files changed, 152 insertions(+), 483 deletions(-) delete mode 100644 src/lib/ring-buffer.spec.ts delete mode 100644 src/lib/ring-buffer.ts diff --git a/README.md b/README.md index 375426e1835..4819a994fe9 100644 --- a/README.md +++ b/README.md @@ -49,12 +49,12 @@ The results of running the benchmarks on my laptop: Platform: Darwin (23.5.0) CPU: Apple M2 Pro Node.js v20.15.1 -Date: 7/27/2024, 12:11:40 AM +Date: 7/27/2024, 9:39:29 PM ┌────────────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├────────────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ fetch-multipart-parser │ '0.03 ms ± 0.13' │ '1.91 ms ± 0.36' │ '0.35 ms ± 0.17' │ '21.70 ms ± 1.51' │ -│ busboy │ '0.03 ms ± 0.09' │ '4.17 ms ± 0.16' │ '0.23 ms ± 0.03' │ '46.71 ms ± 3.37' │ -│ @fastify/busboy │ '0.03 ms ± 0.09' │ '2.10 ms ± 0.19' │ '0.38 ms ± 0.04' │ '28.56 ms ± 2.38' │ +│ fetch-multipart-parser │ '0.02 ms ± 0.13' │ '1.77 ms ± 0.07' │ '0.37 ms ± 0.13' │ '19.33 ms ± 1.20' │ +│ busboy │ '0.03 ms ± 0.09' │ '4.00 ms ± 0.18' │ '0.22 ms ± 0.03' │ '43.91 ms ± 2.58' │ +│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.89 ms ± 0.17' │ '0.38 ms ± 0.04' │ '26.66 ms ± 2.39' │ └────────────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ ``` diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 4f08a2b196f..ecfdf5d46c4 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -262,7 +262,7 @@ describe('parseMultipartFormData', async () => { `--${boundary}`, 'Content-Disposition: form-data; name="field1"', '', - 'a'.repeat(1024 * 1024 * 11), // 11MB content + 'a'.repeat(11 * 1024 * 1024), // 11 MB file `--${boundary}--`, ].join(CRLF), }); diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 09ee2b3a836..f6469a52099 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -1,7 +1,5 @@ import { SuperHeaders } from 'fetch-super-headers'; -import { RingBuffer } from './ring-buffer.js'; - /** * Returns true if the request is `multipart/form-data`. */ @@ -103,7 +101,8 @@ export async function* parseMultipartStream( const HYPHEN = 45; const DOUBLE_NEWLINE = new Uint8Array([13, 10, 13, 10]); -const DOUBLE_NEWLINE_SKIP_TABLE = RingBuffer.computeSkipTable(DOUBLE_NEWLINE); +const DOUBLE_NEWLINE_SKIP_TABLE = computeSkipTable(DOUBLE_NEWLINE); +const EMPTY_BUFFER = new Uint8Array(0); const textDecoder = new TextDecoder(); const textEncoder = new TextEncoder(); @@ -116,7 +115,6 @@ export class MultipartParseError extends Error { } export interface MultipartParserOptions { - bufferSize?: number; maxHeaderSize?: number; maxFileSize?: number; } @@ -136,33 +134,27 @@ export class MultipartParser { private boundaryArray: Uint8Array; private boundaryLength: number; private boundarySkipTable: Uint8Array; - private buffer: RingBuffer; private maxHeaderSize: number; private maxFileSize: number; private state = MultipartParserState.Start; + private buffer: Uint8Array = EMPTY_BUFFER; + private chunk: Uint8Array = EMPTY_BUFFER; + private length: number = 0; + private bodyController: ReadableStreamDefaultController | null = null; private bodyLength = 0; constructor( public boundary: string, { - bufferSize = Math.pow(2, 16), // 64 KB maxHeaderSize = 8 * 1024, // 8 KB maxFileSize = 10 * 1024 * 1024, // 10 MB }: MultipartParserOptions = {} ) { - if ((bufferSize & (bufferSize - 1)) !== 0) { - throw new Error('bufferSize must be a power of 2'); - } - if (bufferSize <= maxHeaderSize) { - throw new Error('bufferSize must be greater than maxHeaderSize'); - } - this.boundaryArray = textEncoder.encode(`--${boundary}`); this.boundaryLength = this.boundaryArray.length; - this.boundarySkipTable = RingBuffer.computeSkipTable(this.boundaryArray); - this.buffer = new RingBuffer(bufferSize); + this.boundarySkipTable = computeSkipTable(this.boundaryArray); this.maxHeaderSize = maxHeaderSize; this.maxFileSize = maxFileSize; } @@ -176,31 +168,45 @@ export class MultipartParser { throw new MultipartParseError('Cannot push, parser is done'); } - this.buffer.append(chunk); - - let parts: MultipartPart[] = []; + this.chunk = chunk; + this.length = this.buffer.length + this.chunk.length; if (this.state === MultipartParserState.Start) { - if (this.buffer.length < this.boundaryLength) return parts; + if (this.length < this.boundaryLength) { + this.save(); + return []; + } - let boundaryIndex = this.buffer.indexOf(this.boundaryArray, 0, this.boundarySkipTable); - if (boundaryIndex !== 0) { + let index = find(this.buffer, this.chunk, this.boundaryArray, this.boundarySkipTable); + if (index !== 0) { throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); } - this.buffer.skip(this.boundaryLength); + this.skip(this.boundaryLength); this.state = MultipartParserState.AfterBoundary; } + let parts: MultipartPart[] = []; + while (true) { if (this.state === MultipartParserState.AfterBoundary) { - if (this.buffer.length < 2) break; + if (this.length < 2) { + this.save(); + break; + } // If the next two bytes are "--" then we're done; this is the closing boundary. Otherwise // they're the \r\n after a boundary in the middle of the message and we can ignore them. - let twoBytes = this.buffer.read(2); - if (twoBytes[0] === HYPHEN && twoBytes[1] === HYPHEN) { + let twoBytes = this.read(2); + if ( + (twoBytes.length === 1 && twoBytes[0][0] === HYPHEN && twoBytes[0][1] === HYPHEN) || + (twoBytes[0][0] === HYPHEN && twoBytes[1][0] === HYPHEN) + ) { + // Discard any remaining data in the current buffer/chunk so we don't leak memory. + this.buffer = EMPTY_BUFFER; + this.chunk = EMPTY_BUFFER; + this.state = MultipartParserState.Done; break; } @@ -209,18 +215,21 @@ export class MultipartParser { } if (this.state === MultipartParserState.Header) { - if (this.buffer.length < 4) break; + if (this.length < 4) { + this.save(); + break; + } - let headerEndIndex = this.buffer.indexOf(DOUBLE_NEWLINE, 0, DOUBLE_NEWLINE_SKIP_TABLE); - if (headerEndIndex === -1) break; - if (headerEndIndex > this.maxHeaderSize) { + let index = find(this.buffer, this.chunk, DOUBLE_NEWLINE, DOUBLE_NEWLINE_SKIP_TABLE); + if (index === -1) break; + if (index > this.maxHeaderSize) { throw new MultipartParseError( `Header size exceeds maximum allowed size of ${this.maxHeaderSize} bytes` ); } - let header = this.buffer.read(headerEndIndex); - this.buffer.skip(4); // Skip \r\n\r\n + let header = concatChunks(this.read(index)); + this.skip(4); // Skip \r\n\r\n let body = new ReadableStream({ start: (controller) => { @@ -234,21 +243,24 @@ export class MultipartParser { } if (this.state === MultipartParserState.Body) { - if (this.buffer.length < this.boundaryLength) break; + if (this.length < this.boundaryLength) { + this.save(); + break; + } - let boundaryIndex = this.buffer.indexOf(this.boundaryArray, 0, this.boundarySkipTable); + let index = find(this.buffer, this.chunk, this.boundaryArray, this.boundarySkipTable); - if (boundaryIndex === -1) { + if (index === -1) { // Write as much of the buffer as we can to the current body stream while still // keeping enough to check if the last few bytes are part of the boundary. - this.writeBody(this.buffer.read(this.buffer.length - this.boundaryLength + 1)); + this.writeBody(this.read(this.length - this.boundaryLength + 1)); break; } - this.writeBody(this.buffer.read(boundaryIndex - 2)); // -2 to avoid \r\n before boundary + this.writeBody(this.read(index - 2)); // -2 to avoid \r\n before boundary this.closeBody(); - this.buffer.skip(2 + this.boundaryLength); // Skip \r\n + boundary + this.skip(2 + this.boundaryLength); // Skip \r\n + boundary this.state = MultipartParserState.AfterBoundary; } @@ -257,15 +269,61 @@ export class MultipartParser { return parts; } - private writeBody(chunk: Uint8Array): void { - if (this.bodyLength + chunk.length > this.maxFileSize) { - throw new MultipartParseError( - `File size exceeds maximum allowed size of ${this.maxFileSize} bytes` - ); + private read(size: number): Uint8Array[] { + this.length -= size; + + if (size > this.buffer.length) { + if (this.buffer.length > 0) { + let head = this.buffer; + this.buffer = EMPTY_BUFFER; + let tail = this.chunk.subarray(0, size - head.length); + this.chunk = this.chunk.subarray(size - head.length); + return [head, tail]; + } else { + let head = this.chunk.subarray(0, size); + this.chunk = this.chunk.subarray(size); + return [head]; + } + } else { + let head = this.buffer.subarray(0, size); + this.buffer = this.buffer.subarray(size); + return [head]; } + } + + private skip(size: number): void { + this.length -= size; + + if (size > this.buffer.length) { + this.chunk = this.chunk.subarray(size - this.buffer.length); + this.buffer = EMPTY_BUFFER; + } else { + this.buffer = this.buffer.subarray(size); + } + } - this.bodyController!.enqueue(chunk); - this.bodyLength += chunk.length; + private save(): void { + this.buffer = + this.buffer.length === 0 + ? this.chunk + : this.chunk.length === 0 + ? this.buffer + : concatChunks([this.buffer, this.chunk]); + } + + private writeBody(chunks: Uint8Array[]): void { + for (let i = 0; i < chunks.length; ++i) { + let chunk = chunks[i]; + + if (this.bodyLength + chunk.length > this.maxFileSize) { + throw new MultipartParseError( + `File size exceeds maximum allowed size of ${this.maxFileSize} bytes` + ); + } + + this.bodyController!.enqueue(chunk); + this.bodyLength += chunk.length; + } } private closeBody(): void { @@ -275,6 +333,50 @@ export class MultipartParser { } } +function find( + head: Uint8Array, + tail: Uint8Array, + pattern: Uint8Array, + skipTable = computeSkipTable(pattern) +): number { + let headLength = head.length; + let totalLength = headLength + tail.length; + let i = pattern.length - 1; + + function byteAt(index: number) { + return index < headLength ? head[index] : tail[index - headLength]; + } + + while (i < totalLength) { + let j = pattern.length - 1; + let k = i; + + while (j >= 0 && byteAt(k) === pattern[j]) { + j--; + k--; + } + + if (j === -1) { + return k + 1; + } + + i += skipTable[byteAt(i)] || pattern.length; + } + + return -1; +} + +function computeSkipTable(pattern: Uint8Array): Uint8Array { + let table = new Uint8Array(256).fill(pattern.length); + let lastIndex = pattern.length - 1; + + for (let i = 0; i < lastIndex; i++) { + table[pattern[i]] = lastIndex - i; + } + + return table; +} + /** * A part of a `multipart/form-data` message. */ @@ -374,9 +476,7 @@ async function bufferStream(stream: ReadableStream): Promise sum + chunk.length, 0); let result = new Uint8Array(length); diff --git a/src/lib/ring-buffer.spec.ts b/src/lib/ring-buffer.spec.ts deleted file mode 100644 index a705d91c9c2..00000000000 --- a/src/lib/ring-buffer.spec.ts +++ /dev/null @@ -1,256 +0,0 @@ -import * as assert from 'node:assert/strict'; -import { describe, it } from 'node:test'; - -import { RingBuffer } from './ring-buffer.js'; - -describe('RingBuffer', () => { - describe('constructor', () => { - it('handles initialization with the correct capacity', () => { - let buffer = new RingBuffer(16); - assert.equal(buffer.capacity, 16); - assert.equal(buffer.length, 0); - }); - }); - - describe('at', () => { - it('returns the value of a byte at a given index', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - assert.equal(buffer.at(0), 1); - assert.equal(buffer.at(1), 2); - assert.equal(buffer.at(2), 3); - assert.equal(buffer.at(3), 4); - assert.equal(buffer.at(4), 5); - assert.equal(buffer.at(5), undefined); - assert.equal(buffer.at(-1), 5); - assert.equal(buffer.at(-2), 4); - assert.equal(buffer.at(-3), 3); - assert.equal(buffer.at(-4), 2); - assert.equal(buffer.at(-5), 1); - assert.equal(buffer.at(-6), undefined); - }); - }); - - describe('append', () => { - it('handles appending data correctly', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3])); - assert.equal(buffer.length, 3); - assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); - }); - - it('handles appending an empty array', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2])); - buffer.append(new Uint8Array([])); - assert.equal(buffer.length, 2); - assert.deepEqual(buffer.read(2), new Uint8Array([1, 2])); - }); - - it('handles appending data that exactly fills the remaining capacity', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3])); - assert.equal(buffer.length, 3); - assert.equal(buffer.capacity, 8); - - buffer.append(new Uint8Array([4, 5, 6, 7, 8])); - assert.equal(buffer.length, 8); - assert.equal(buffer.capacity, 8); - - assert.deepEqual(buffer.read(8), new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); - }); - - it('handles appending data that causes multiple wraps', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); - assert.deepEqual(buffer.read(2), new Uint8Array([1, 2])); - buffer.append(new Uint8Array([9, 10])); - assert.deepEqual(buffer.read(8), new Uint8Array([3, 4, 5, 6, 7, 8, 9, 10])); - buffer.append(new Uint8Array([11, 12, 13, 14, 15, 16])); - assert.deepEqual(buffer.read(6), new Uint8Array([11, 12, 13, 14, 15, 16])); - }); - }); - - describe('read', () => { - it('handles reading data correctly', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - assert.equal(buffer.length, 5); - assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); - assert.equal(buffer.length, 2); - }); - - it('handles reading zero bytes', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3])); - assert.deepEqual(buffer.read(0), new Uint8Array([])); - assert.equal(buffer.length, 3); - }); - - it('handles reading all data and then appending', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3])); - buffer.read(3); - buffer.append(new Uint8Array([4, 5])); - assert.equal(buffer.length, 2); - assert.deepEqual(buffer.read(2), new Uint8Array([4, 5])); - }); - - it('handles circular behavior when reading', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6])); - assert.deepEqual(buffer.read(4), new Uint8Array([1, 2, 3, 4])); - buffer.append(new Uint8Array([7, 8, 9])); - assert.equal(buffer.length, 5); - assert.deepEqual(buffer.read(5), new Uint8Array([5, 6, 7, 8, 9])); - }); - - it('handles reading past the end of the internal buffer', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); - assert.deepEqual(buffer.read(4), new Uint8Array([1, 2, 3, 4])); - buffer.append(new Uint8Array([9, 10, 11, 12])); - assert.equal(buffer.length, 8); - assert.deepEqual(buffer.read(8), new Uint8Array([5, 6, 7, 8, 9, 10, 11, 12])); - assert.equal(buffer.length, 0); - }); - - it('throws an error when reading with negative size', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3])); - assert.throws(() => buffer.read(-1), { - name: 'Error', - message: 'Cannot read a negative number of bytes', - }); - }); - - it('throws an error when reading more data than available', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3])); - assert.equal(buffer.length, 3); - assert.throws(() => buffer.read(4), { - name: 'Error', - message: 'Cannot read past the end of the buffer', - }); - }); - }); - - describe('skip', () => { - it('handles skipping data correctly', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - buffer.skip(2); - assert.equal(buffer.length, 3); - assert.deepEqual(buffer.read(3), new Uint8Array([3, 4, 5])); - }); - - it('handles skipping with wrap-around', () => { - let buffer = new RingBuffer(4); - buffer.append(new Uint8Array([1, 2, 3, 4])); - buffer.skip(3); - buffer.append(new Uint8Array([5, 6])); - assert.equal(buffer.length, 3); - assert.deepEqual(buffer.read(3), new Uint8Array([4, 5, 6])); - }); - - it('handles skipping all data', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3, 4])); - buffer.skip(4); - assert.equal(buffer.length, 0); - buffer.append(new Uint8Array([5, 6])); - assert.deepEqual(buffer.read(2), new Uint8Array([5, 6])); - }); - - it('throws an error when skipping negative number of bytes', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3])); - assert.throws(() => buffer.skip(-1), { - name: 'Error', - message: 'Cannot skip a negative number of bytes', - }); - }); - - it('throws an error when skipping more bytes than available', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3])); - assert.throws(() => buffer.skip(4), { - name: 'Error', - message: 'Cannot skip past the end of the buffer', - }); - }); - - it('handles skipping zero bytes', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3])); - buffer.skip(0); - assert.equal(buffer.length, 3); - assert.deepEqual(buffer.read(3), new Uint8Array([1, 2, 3])); - }); - }); - - describe('indexOf', () => { - it('finds a simple pattern', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - assert.equal(buffer.indexOf(new Uint8Array([3, 4])), 2); - }); - - it('returns -1 when pattern is not found', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - assert.equal(buffer.indexOf(new Uint8Array([6])), -1); - }); - - it('handles wrap-around search', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])); - buffer.skip(6); - buffer.append(new Uint8Array([9, 10, 11, 12])); - assert.equal(buffer.indexOf(new Uint8Array([8, 9, 10])), 1); - }); - - it('finds pattern at the beginning', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - assert.equal(buffer.indexOf(new Uint8Array([1, 2])), 0); - }); - - it('finds pattern at the end', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - assert.equal(buffer.indexOf(new Uint8Array([4, 5])), 3); - }); - - it('handles empty needle', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3])); - assert.equal(buffer.indexOf(new Uint8Array([])), 0); - }); - - it('handles search with offset', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3, 1, 2, 3])); - assert.equal(buffer.indexOf(new Uint8Array([1, 2]), 2), 3); - }); - - it('handles string input', () => { - let buffer = new RingBuffer(16); - buffer.append(new TextEncoder().encode('Hello, world!')); - assert.equal(buffer.indexOf('world'), 7); - }); - - it('returns -1 when needle is longer than haystack', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3])); - assert.equal(buffer.indexOf(new Uint8Array([1, 2, 3, 4])), -1); - }); - - it('uses provided skip table', () => { - let buffer = new RingBuffer(8); - buffer.append(new Uint8Array([1, 2, 3, 4, 5])); - let skipTable = RingBuffer.computeSkipTable(new Uint8Array([3, 4])); - assert.equal(buffer.indexOf(new Uint8Array([3, 4]), 0, skipTable), 2); - }); - }); -}); diff --git a/src/lib/ring-buffer.ts b/src/lib/ring-buffer.ts deleted file mode 100644 index 315a0783bcd..00000000000 --- a/src/lib/ring-buffer.ts +++ /dev/null @@ -1,175 +0,0 @@ -/** - * A fast ring (or "circular") buffer implementation that supports reusing a fixed-size buffer - * by overwriting the oldest data when the buffer is full. This is useful for buffering streaming - * data, such as reading from a file or network socket, before handing off the data to a consumer. - */ -export class RingBuffer implements RelativeIndexable { - private buffer: Uint8Array; - private start = 0; - private end = 0; - private _length = 0; - private mask: number; - - /** - * Creates a new RingBuffer with the given `capacity`, which must be a power of 2. - */ - constructor(capacity: number) { - if ((capacity & (capacity - 1)) !== 0) { - throw new Error('Initial capacity must be a power of 2'); - } - - this.buffer = new Uint8Array(capacity); - this.mask = capacity - 1; - } - - /** - * The total number of bytes this buffer can hold. - */ - get capacity(): number { - return this.buffer.length; - } - - /** - * The number of bytes in the buffer. - */ - get length(): number { - return this._length; - } - - at(index: number): number | undefined { - if (index < -this._length || index >= this._length) { - return undefined; - } - - if (index < 0) { - index = this._length + index; - } - - return this.buffer[(this.start + index) & this.mask]; - } - - /** - * Appends a chunk of data to the buffer. - */ - append(chunk: Uint8Array): void { - if (chunk.length === 0) return; - - if (chunk.length + this._length > this.capacity) { - throw new Error(`Cannot append to buffer, it is full`); - } - - let spaceToEnd = this.capacity - this.end; - if (chunk.length <= spaceToEnd) { - this.buffer.set(chunk, this.end); - this.end += chunk.length; - } else { - this.buffer.set(chunk.subarray(0, spaceToEnd), this.end); - this.buffer.set(chunk.subarray(spaceToEnd), 0); - this.end = chunk.length - spaceToEnd; - } - - this._length += chunk.length; - } - - /** - * Returns the next `size` bytes from the buffer without removing them. - */ - peek(size: number): Uint8Array { - if (size < 0) { - throw new Error('Cannot read a negative number of bytes'); - } - if (size > this._length) { - throw new Error('Cannot read past the end of the buffer'); - } - - if (this.start < this.end) { - return this.buffer.slice(this.start, this.start + size); - } - - let result = new Uint8Array(size); - - let firstPart = Math.min(size, this.capacity - this.start); - result.set(this.buffer.subarray(this.start, this.start + firstPart), 0); - result.set(this.buffer.subarray(0, size - firstPart), firstPart); - - return result; - } - - /** - * Removes and returns the next `size` bytes from the buffer. - */ - read(size: number): Uint8Array { - let chunk = this.peek(size); - this.skip(size); - return chunk; - } - - /** - * Removes the next `size` bytes from the buffer without returning them, effectively "skipping" - * them and discarding the data. - */ - skip(size: number): void { - if (size < 0) { - throw new Error('Cannot skip a negative number of bytes'); - } - if (size > this._length) { - throw new Error('Cannot skip past the end of the buffer'); - } - - this.start = (this.start + size) & this.mask; - this._length -= size; - } - - /** - * Computes the skip table for the Boyer-Moore-Horspool algorithm. This can be used to - * precompute the 3rd argument to `indexOf` to make searches more efficient when the needle - * is known in advance. - */ - static computeSkipTable(needle: string | Uint8Array): Uint8Array { - const table = new Uint8Array(256).fill(needle.length); - const lastIndex = needle.length - 1; - - for (let i = 0; i < lastIndex; i++) { - table[typeof needle === 'string' ? needle.charCodeAt(i) : needle[i]] = lastIndex - i; - } - - return table; - } - - /** - * Searches for the given value in the buffer using the Boyer-Moore-Horspool algorithm. - * Returns the index of the first occurrence if found, or -1 if not. - */ - indexOf( - needle: string | Uint8Array, - offset = 0, - skipTable = RingBuffer.computeSkipTable(needle) - ): number { - if (needle.length === 0) return offset; - if (needle.length > this._length) return -1; - - let needleArray = typeof needle === 'string' ? new TextEncoder().encode(needle) : needle; - let needleLength = needleArray.length; - let lastIndex = needleLength - 1; - - let i = (this.start + offset) & this.mask; - let j = offset; - - while (j < this._length - needleLength + 1) { - let k = lastIndex; - while (k >= 0 && this.buffer[(i + k) & this.mask] === needleArray[k]) { - k--; - } - - if (k < 0) { - return j; // Found a match - } - - let skip = skipTable[this.buffer[(i + lastIndex) & this.mask]]; - i = (i + skip) & this.mask; - j += skip; - } - - return -1; // Not found - } -} From 6c156a8975e8c056ebd03b4912513c32b46bfdf6 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 28 Jul 2024 08:18:22 -0700 Subject: [PATCH 097/730] Save buffer when streaming large files --- README.md | 8 ++++---- src/lib/multipart.ts | 14 ++++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4819a994fe9..16b9d2e446b 100644 --- a/README.md +++ b/README.md @@ -49,12 +49,12 @@ The results of running the benchmarks on my laptop: Platform: Darwin (23.5.0) CPU: Apple M2 Pro Node.js v20.15.1 -Date: 7/27/2024, 9:39:29 PM +Date: 7/28/2024, 8:16:46 AM ┌────────────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├────────────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ fetch-multipart-parser │ '0.02 ms ± 0.13' │ '1.77 ms ± 0.07' │ '0.37 ms ± 0.13' │ '19.33 ms ± 1.20' │ -│ busboy │ '0.03 ms ± 0.09' │ '4.00 ms ± 0.18' │ '0.22 ms ± 0.03' │ '43.91 ms ± 2.58' │ -│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.89 ms ± 0.17' │ '0.38 ms ± 0.04' │ '26.66 ms ± 2.39' │ +│ fetch-multipart-parser │ '0.02 ms ± 0.13' │ '1.81 ms ± 0.10' │ '0.37 ms ± 0.14' │ '19.59 ms ± 1.25' │ +│ busboy │ '0.03 ms ± 0.09' │ '3.95 ms ± 0.19' │ '0.22 ms ± 0.02' │ '46.38 ms ± 2.98' │ +│ @fastify/busboy │ '0.03 ms ± 0.08' │ '1.94 ms ± 0.21' │ '0.38 ms ± 0.04' │ '26.46 ms ± 2.31' │ └────────────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ ``` diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index f6469a52099..2f93f9a237a 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -254,6 +254,7 @@ export class MultipartParser { // Write as much of the buffer as we can to the current body stream while still // keeping enough to check if the last few bytes are part of the boundary. this.writeBody(this.read(this.length - this.boundaryLength + 1)); + this.save(); break; } @@ -303,12 +304,13 @@ export class MultipartParser { } private save(): void { - this.buffer = - this.buffer.length === 0 - ? this.chunk - : this.chunk.length === 0 - ? this.buffer - : concatChunks([this.buffer, this.chunk]); + if (this.chunk.length > 0) { + if (this.buffer.length > 0) { + this.buffer = concatChunks([this.buffer, this.chunk]); + } else { + this.buffer = this.chunk; + } + } } private writeBody(chunks: Uint8Array[]): void { From 7abfd114ef8ecf1141d02506c2f1bea912a2aed5 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 29 Jul 2024 01:39:05 -0700 Subject: [PATCH 098/730] Add test for parsing a large file upload --- src/fixtures/Tesla-Roadster.jpg | Bin 0 -> 91897 bytes src/lib/multipart.spec.ts | 45 +++++++++++++++++++-------- src/lib/multipart.ts | 53 ++++++++------------------------ src/lib/utils.ts | 52 +++++++++++++++++++++++++++++++ src/test-utils.ts | 10 ++++++ 5 files changed, 106 insertions(+), 54 deletions(-) create mode 100644 src/fixtures/Tesla-Roadster.jpg create mode 100644 src/lib/utils.ts create mode 100644 src/test-utils.ts diff --git a/src/fixtures/Tesla-Roadster.jpg b/src/fixtures/Tesla-Roadster.jpg new file mode 100644 index 0000000000000000000000000000000000000000..03243d39b9e515eede32b440341c2f833234cf1f GIT binary patch literal 91897 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 u0_@<0_s#0xjnH}#_ z81+*tG@pP58|qwBdo+I{t1n2lYj0`E?h7(rkM z$?5LeTQ!=zp5DA$!`~ZV&`cx!C$eNbRXL0hS%(ein!O$@;WDR72_^o`2 z!CHT~ux_fUgm0#EiyVFYSb%GLFLf%;p6pGZoleqgr8=>O;8^GfBvs%x1p4%t?0M+!hRMO0A;bkq2+}50Dff?wW=yqcyk4N4|a51*$Ow=7b zEFd~Yf^-D(UpVb=w8}H>Fw=^N8xu%?w%g2OpJ#gV`p%W@im61>*34csIFFB-&pE!4 zCRTliUD92dMqDMGpp8K`%b4a7;oJKzb~W+UF~PuE$C~(FeXUV5uKDDB$+#rjK0!2l zZncv&?5dTo4Z_kKZU&Z2_`VC5PN&_+Yf%AnGc9v$`5-~ID5Wkj)I#QiVgdJo?OzEU zty&!6?Gl_{7ragHs?^!LPD)yrO$^y#%siG8bEa3hRnC2B1s^E;Vp{r9D`j<9jjXsW z!~#wWKRRK!jq*)3O+6tL&;s{jIW z3gcmC5T(0l(KH221-gYI%&}wN4!$DT(laLU+oB1xbhoN04ts~lYHCvf%obiB;;7DHOKGKzqbByJn3zKt@ zSkLJO(uu}FG>vanoO|7WqUS7F_rHPd|CID8S)z_kK$3e`EFS7CTm(!Z)u_ znp&tGX>pF;3Jt9%_=R`m`93Ez!RC$oAg^n~hSsOZ+`!(B5c=jo&gLysf*U5T& zY6s4I(FI52K5IXBkCS})S7XXg+22W}AN3EQaRc47j`jCbGwk=Jae^b0X0ZIh?!W&4 zlD%=YANL9>vLCm3z3T zJi?f$zQ0v@E6F*Y5%axo*@sEw(vBxv<*9Gx0>hK+!=;UOdm>^#1hF5@eNH9^iBk`6 z%&#df?3w%{<&n@`w@(k=Y>M`t#^e70@-B`xHANg@(|cGyA*YaG@v{1aJCRbx@0hH- z8}4ah*JI{EM(hFZtaE=1g2UFztl*ZMY%gfj1Aj1A)GiEov)IRfPzUO$%d&P%z=?Kk zGq11RxAI)y4*N-c4vUCg;?I~FQ43h&MgTr%8?2f3l^d=JX&=<Ld7ag7iwKH|(ag z-&Q%z^u3l9Z`pT8Y6sm^)xbD37P+Iqg;oPYoSE}`{fXeYvXJggZc3BQ*=#PqJLJ8_ zuk2Rt#YeWA{W8UGR+Z0H{gQO53z~CHIQ%l#9ebMGrtODZ$N#;u3rZq1( zT=;`K)%vc7^rDX9qhnNnHFG204>nz3?wbVIXQz}qkp;embDT}WMVg{F8Y>GkGJD>?yh|{8yS#?!XqbeHNy~2$A`9Lgy@1 z(#@27owB6EOy^XikY%+odk$qOa`jk7}iN~~~iSLsmzoO09D@9KWK(h_|mB^Vl zRinow;zCAl0alRM{_v^P7Y#(sHgRH$iGRf-h~x#8J?wV){E{^c1LJaK7G7wDqumF@ zrgX0Y%nb`6)$p|Yt#glYNtKl{W$f+)$!SEE%`qg0;(721VZ=0g&km3};4!`0sk%zb zd!U~b%7wDqV!8Maif7U==II_gjg6R{0&m!H-uQ}TdlNF;!*iemFyr2V?J>0bv4h~cPuVoX z;&=)tW^Dem$?i&JQb# ^+=QqrnPE-qCktx~A;s>ihVqUc&scxOE8s0OPp# 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 literal 0 HcmV?d00001 diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index ecfdf5d46c4..20c1a0b8075 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -3,22 +3,20 @@ import { describe, it } from 'node:test'; import { ContentDisposition, ContentType, SuperHeaders } from 'fetch-super-headers'; +import { readFixture } from '../test-utils.js'; import { MultipartParseError, parseMultipartFormData } from './multipart.js'; +import { binaryToString } from './utils.js'; + +const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); const CRLF = '\r\n'; -function* generateChunks(content: string, chunkSize = 16 * 1024): Generator { +function createReadableStream(content: string, chunkSize = 16 * 1024): ReadableStream { let encoder = new TextEncoder(); - for (let i = 0; i < content.length; i += chunkSize) { - yield encoder.encode(content.slice(i, i + chunkSize)); - } -} - -function createReadableStream(content: string, chunkSize?: number): ReadableStream { return new ReadableStream({ start(controller) { - for (let chunk of generateChunks(content, chunkSize)) { - controller.enqueue(chunk); + for (let i = 0; i < content.length; i += chunkSize) { + controller.enqueue(encoder.encode(content.slice(i, i + chunkSize))); } controller.close(); }, @@ -44,7 +42,7 @@ type PartValue = filename?: string; filenameSplat?: string; mediaType?: string; - content: string; + content: string | Uint8Array; }; function createMultipartBody(boundary: string, parts?: { [name: string]: PartValue }): string { @@ -78,7 +76,7 @@ function createMultipartBody(boundary: string, parts?: { [name: string]: PartVal } lines.push(''); - lines.push(part.content); + lines.push(typeof part.content === 'string' ? part.content : binaryToString(part.content)); } } } @@ -211,6 +209,27 @@ describe('parseMultipartFormData', async () => { assert.equal(await parts[2].text(), 'File content'); }); + it('parses large file uploads correctly', async () => { + let request = createMultipartMockRequest(boundary, { + file1: { + filename: 'tesla.jpg', + mediaType: 'image/jpeg', + content: TeslaRoadster, + }, + }); + + let parts = []; + for await (let part of parseMultipartFormData(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'file1'); + assert.equal(parts[0].filename, 'tesla.jpg'); + assert.equal(parts[0].mediaType, 'image/jpeg'); + assert.deepEqual(await parts[0].bytes(), TeslaRoadster); + }); + it('throws when Content-Type is not multipart/form-data', async () => { let request = createMockRequest({ headers: { 'Content-Type': 'text/plain' }, @@ -239,7 +258,7 @@ describe('parseMultipartFormData', async () => { body: [ `--${boundary}`, 'Content-Disposition: form-data; name="field1"', - 'X-Large-Header: ' + 'a'.repeat(8 * 1024), // 8 KB header + 'X-Large-Header: ' + 'X'.repeat(6 * 1024), // 6 KB header '', 'value1', `--${boundary}--`, @@ -262,7 +281,7 @@ describe('parseMultipartFormData', async () => { `--${boundary}`, 'Content-Disposition: form-data; name="field1"', '', - 'a'.repeat(11 * 1024 * 1024), // 11 MB file + 'X'.repeat(11 * 1024 * 1024), // 11 MB file `--${boundary}--`, ].join(CRLF), }); diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 2f93f9a237a..ef6d4413fba 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -1,5 +1,7 @@ import { SuperHeaders } from 'fetch-super-headers'; +import { concatChunks, decodeUtf8Stream, stringToBinary } from './utils.js'; + /** * Returns true if the request is `multipart/form-data`. */ @@ -409,13 +411,7 @@ export class MultipartPart { * The content of this part as a `Uint8Array`. */ async bytes(): Promise { - if (this._bodyUsed) { - throw new Error('Body is already consumed or is being consumed'); - } - - this._bodyUsed = true; - - return bufferStream(this.body); + return stringToBinary(await this.text()); } /** @@ -426,6 +422,10 @@ export class MultipartPart { return this._headers; } + get isFile(): boolean { + return this.filename !== null; + } + /** * The filename of the part, if it is a file upload. */ @@ -452,42 +452,13 @@ export class MultipartPart { * * Note: Do not use this for binary data, use `await part.bytes()` or stream `part.body` directly instead. */ - async text(): Promise { - return textDecoder.decode(await this.bytes()); - } -} - -async function bufferStream(stream: ReadableStream): Promise { - let reader = stream.getReader(); - - try { - let chunks: Uint8Array[] = []; - - while (true) { - const { done, value } = await reader.read(); - - if (done) { - return concatChunks(chunks); - } - - chunks.push(value); + text(): Promise { + if (this._bodyUsed) { + throw new Error('Body is already consumed or is being consumed'); } - } finally { - reader.releaseLock(); - } -} -function concatChunks(chunks: Uint8Array[]): Uint8Array { - if (chunks.length === 1) return chunks[0]; - - let length = chunks.reduce((sum, chunk) => sum + chunk.length, 0); - let result = new Uint8Array(length); - let offset = 0; + this._bodyUsed = true; - for (let i = 0; i < chunks.length; ++i) { - result.set(chunks[i], offset); - offset += chunks[i].length; + return decodeUtf8Stream(this.body); } - - return result; } diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 00000000000..1f34f229b26 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,52 @@ +export function concatChunks(chunks: Uint8Array[]): Uint8Array { + if (chunks.length === 1) return chunks[0]; + + let length = chunks.reduce((sum, chunk) => sum + chunk.length, 0); + let result = new Uint8Array(length); + let offset = 0; + + for (let i = 0; i < chunks.length; ++i) { + result.set(chunks[i], offset); + offset += chunks[i].length; + } + + return result; +} + +export async function decodeUtf8Stream(stream: ReadableStream): Promise { + let decoder = new TextDecoder('utf-8'); + let reader = stream.getReader(); + + try { + let string = ''; + + while (true) { + const { done, value } = await reader.read(); + + if (done) { + string += decoder.decode(); + return string; + } + + string += decoder.decode(value, { stream: true }); + } + } finally { + reader.releaseLock(); + } +} + +export function binaryToString(binary: Uint8Array): string { + let string = ''; + for (let i = 0; i < binary.length; ++i) { + string += String.fromCharCode(binary[i]); + } + return string; +} + +export function stringToBinary(string: string): Uint8Array { + let binary = new Uint8Array(string.length); + for (let i = 0; i < string.length; ++i) { + binary[i] = string.charCodeAt(i); + } + return binary; +} diff --git a/src/test-utils.ts b/src/test-utils.ts new file mode 100644 index 00000000000..d9b41521028 --- /dev/null +++ b/src/test-utils.ts @@ -0,0 +1,10 @@ +import * as path from 'node:path'; +import * as fs from 'node:fs'; + +const __dirname = path.dirname(new URL(import.meta.url).pathname); + +export function readFixture(name: string): Uint8Array { + let file = path.resolve(__dirname, `./fixtures/${name}`); + let buffer = fs.readFileSync(file); + return new Uint8Array(buffer); +} From 33f917146213b4a1b7c5218e3176417cd7819531 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 29 Jul 2024 09:22:12 -0700 Subject: [PATCH 099/730] Rename to multipart-parser --- README.md | 12 ++- bench/package.json | 2 +- ...ultipart-parser.ts => multipart-parser.ts} | 4 +- bench/runner.ts | 6 +- package.json | 14 +++- src/{test-utils.ts => fixtures/utils.ts} | 2 +- src/index.ts | 7 +- ...ipart.spec.ts => multipart-parser.spec.ts} | 77 +++++++++++++++---- src/lib/{multipart.ts => multipart-parser.ts} | 77 ++++++------------- tsconfig.lib.json | 2 +- tsconfig.spec.json | 2 +- 11 files changed, 117 insertions(+), 88 deletions(-) rename bench/parsers/{fetch-multipart-parser.ts => multipart-parser.ts} (79%) rename src/{test-utils.ts => fixtures/utils.ts} (81%) rename src/lib/{multipart.spec.ts => multipart-parser.spec.ts} (78%) rename src/lib/{multipart.ts => multipart-parser.ts} (83%) diff --git a/README.md b/README.md index 16b9d2e446b..c3e12ef5c3f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ -# fetch-multipart-parser +# multipart-parser -`fetch-multipart-parser` is a streaming multipart parser for JavaScript's fetch API. +`multipart-parser` is a fast, efficient parser for multipart streams. It can be used in any JavaScript environment (not just node) for a variety of use cases including: + +- Handling file uploads (`multipart/form-data` requests) +- Parsing `multipart/mixed` messages (email attachments, API responses, etc.) +- Parsing email messages with both plain text and HTML versions (`multipart/alternative`) ## Features @@ -9,13 +13,13 @@ This package is a streaming multipart parser for JavaScript's fetch API, making ## Installation ```sh -$ npm install fetch-multipart-parser +$ npm install @mjackson/multipart-parser ``` ## Usage ```typescript -import { MultipartParseError, parseMultipartFormData } from 'fetch-multipart-parser'; +import { MultipartParseError, parseMultipartFormData } from '@mjackson/multipart-parser'; async function handleMultipartRequest(request: Request): void { try { diff --git a/bench/package.json b/bench/package.json index 3ea1acc7840..846feb1fa2a 100644 --- a/bench/package.json +++ b/bench/package.json @@ -1,5 +1,5 @@ { - "name": "fetch-multipart-parser-bench", + "name": "multipart-parser-bench", "private": true, "type": "module", "dependencies": { diff --git a/bench/parsers/fetch-multipart-parser.ts b/bench/parsers/multipart-parser.ts similarity index 79% rename from bench/parsers/fetch-multipart-parser.ts rename to bench/parsers/multipart-parser.ts index 8a772ddf4d3..58e49381ac5 100644 --- a/bench/parsers/fetch-multipart-parser.ts +++ b/bench/parsers/multipart-parser.ts @@ -1,4 +1,4 @@ -import { parseMultipartFormData } from '../../dist/index.js'; +import { parseMultipartRequest } from '../../dist/index.js'; import { MultipartMessage } from '../messages.js'; @@ -19,7 +19,7 @@ export async function parse(message: MultipartMessage): Promise { let start = performance.now(); - for await (let _ of parseMultipartFormData(request, { maxFileSize: Infinity })) { + for await (let _ of parseMultipartRequest(request, { maxFileSize: Infinity })) { // Do nothing } diff --git a/bench/runner.ts b/bench/runner.ts index 6f4cb4276c9..0845bc227c3 100644 --- a/bench/runner.ts +++ b/bench/runner.ts @@ -3,7 +3,7 @@ import * as os from 'node:os'; import * as messages from './messages.js'; import * as busboy from './parsers/busboy.js'; import * as fastifyBusboy from './parsers/fastify-busboy.js'; -import * as fetchMultipartParser from './parsers/fetch-multipart-parser.js'; +import * as multipartParser from './parsers/multipart-parser.js'; const benchmarks = [ { name: '1 small file', message: messages.oneSmallFile }, @@ -50,8 +50,8 @@ interface BenchmarkResults { async function runBenchmarks(parserName?: string): Promise { let results: BenchmarkResults = {}; - if (parserName === 'fetch-multipart-parser' || parserName === undefined) { - results['fetch-multipart-parser'] = await runParserBenchmarks(fetchMultipartParser); + if (parserName === 'multipart-parser' || parserName === undefined) { + results['multipart-parser'] = await runParserBenchmarks(multipartParser); } if (parserName === 'busboy' || parserName === undefined) { results.busboy = await runParserBenchmarks(busboy); diff --git a/package.json b/package.json index 147f66352a4..166a9734355 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "fetch-multipart-parser", - "version": "0.4.0", - "description": "A multipart parser for fetch streams", + "name": "@mjackson/multipart-parser", + "version": "0.1.0", + "description": "A fast, efficient parser for multpart streams", "author": "Michael Jackson ", "license": "MIT", "files": [ @@ -26,5 +26,11 @@ "prepare": "npm run build", "prepublishOnly": "npm run test" }, - "packageManager": "pnpm@9.4.0" + "packageManager": "pnpm@9.4.0", + "keywords": [ + "multipart", + "parser", + "stream", + "http" + ] } diff --git a/src/test-utils.ts b/src/fixtures/utils.ts similarity index 81% rename from src/test-utils.ts rename to src/fixtures/utils.ts index d9b41521028..2e1ccd55fc8 100644 --- a/src/test-utils.ts +++ b/src/fixtures/utils.ts @@ -4,7 +4,7 @@ import * as fs from 'node:fs'; const __dirname = path.dirname(new URL(import.meta.url).pathname); export function readFixture(name: string): Uint8Array { - let file = path.resolve(__dirname, `./fixtures/${name}`); + let file = path.resolve(__dirname, `./${name}`); let buffer = fs.readFileSync(file); return new Uint8Array(buffer); } diff --git a/src/index.ts b/src/index.ts index cad2547d937..4c4a39c2b6b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,10 @@ export { - isMultipartFormData, - parseMultipartFormData, + getMultipartBoundary, + isMultipartRequest, + parseMultipartRequest, parseMultipartStream, MultipartParseError, MultipartParserOptions, MultipartParser, MultipartPart, -} from './lib/multipart.js'; +} from './lib/multipart-parser.js'; diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart-parser.spec.ts similarity index 78% rename from src/lib/multipart.spec.ts rename to src/lib/multipart-parser.spec.ts index 20c1a0b8075..856c4ce5fe3 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart-parser.spec.ts @@ -3,8 +3,13 @@ import { describe, it } from 'node:test'; import { ContentDisposition, ContentType, SuperHeaders } from 'fetch-super-headers'; -import { readFixture } from '../test-utils.js'; -import { MultipartParseError, parseMultipartFormData } from './multipart.js'; +import { readFixture } from '../fixtures/utils.js'; +import { + isMultipartRequest, + parseMultipartRequest, + MultipartParseError, + getMultipartBoundary, +} from './multipart-parser.js'; import { binaryToString } from './utils.js'; const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); @@ -99,14 +104,54 @@ function createMultipartMockRequest( return createMockRequest({ headers, body }); } -describe('parseMultipartFormData', async () => { +describe('getMultipartBoundary', async () => { + it('returns the boundary from the Content-Type header', async () => { + assert.equal(getMultipartBoundary('multipart/form-data; boundary=boundary123'), 'boundary123'); + }); + + it('returns null when boundary is missing', async () => { + assert.equal(getMultipartBoundary('multipart/form-data'), null); + }); + + it('returns null when Content-Type header is not multipart', async () => { + assert.equal(getMultipartBoundary('text/plain'), null); + }); +}); + +describe('isMultipartRequest', async () => { + it('returns true for multipart/form-data requests', async () => { + let request = createMockRequest({ + headers: { 'Content-Type': 'multipart/form-data' }, + }); + + assert.ok(isMultipartRequest(request)); + }); + + it('returns true for multipart/mixed requests', async () => { + let request = createMockRequest({ + headers: { 'Content-Type': 'multipart/mixed' }, + }); + + assert.ok(isMultipartRequest(request)); + }); + + it('returns false for other content types', async () => { + let request = createMockRequest({ + headers: { 'Content-Type': 'text/plain' }, + }); + + assert.ok(!isMultipartRequest(request)); + }); +}); + +describe('parseMultipartRequest', async () => { let boundary = 'boundary123'; it('parses an empty multipart message', async () => { let request = createMultipartMockRequest(boundary); let parts = []; - for await (let part of parseMultipartFormData(request)) { + for await (let part of parseMultipartRequest(request)) { parts.push(part); } @@ -119,7 +164,7 @@ describe('parseMultipartFormData', async () => { }); let parts = []; - for await (let part of parseMultipartFormData(request)) { + for await (let part of parseMultipartRequest(request)) { parts.push(part); } @@ -135,7 +180,7 @@ describe('parseMultipartFormData', async () => { }); let parts = []; - for await (let part of parseMultipartFormData(request)) { + for await (let part of parseMultipartRequest(request)) { parts.push(part); } @@ -152,7 +197,7 @@ describe('parseMultipartFormData', async () => { }); let parts = []; - for await (let part of parseMultipartFormData(request)) { + for await (let part of parseMultipartRequest(request)) { parts.push(part); } @@ -171,7 +216,7 @@ describe('parseMultipartFormData', async () => { }); let parts = []; - for await (let part of parseMultipartFormData(request)) { + for await (let part of parseMultipartRequest(request)) { parts.push(part); } @@ -194,7 +239,7 @@ describe('parseMultipartFormData', async () => { }); let parts = []; - for await (let part of parseMultipartFormData(request)) { + for await (let part of parseMultipartRequest(request)) { parts.push(part); } @@ -219,7 +264,7 @@ describe('parseMultipartFormData', async () => { }); let parts = []; - for await (let part of parseMultipartFormData(request)) { + for await (let part of parseMultipartRequest(request)) { parts.push(part); } @@ -236,7 +281,7 @@ describe('parseMultipartFormData', async () => { }); await assert.rejects(async () => { - await parseMultipartFormData(request).next(); + await parseMultipartRequest(request).next(); }, MultipartParseError); }); @@ -246,7 +291,7 @@ describe('parseMultipartFormData', async () => { }); await assert.rejects(async () => { - await parseMultipartFormData(request).next(); + await parseMultipartRequest(request).next(); }, MultipartParseError); }); @@ -266,7 +311,7 @@ describe('parseMultipartFormData', async () => { }); await assert.rejects(async () => { - for await (let _ of parseMultipartFormData(request, { maxHeaderSize: 4 * 1024 })) { + for await (let _ of parseMultipartRequest(request, { maxHeaderSize: 4 * 1024 })) { // Consume all parts } }, MultipartParseError); @@ -287,7 +332,7 @@ describe('parseMultipartFormData', async () => { }); await assert.rejects(async () => { - for await (let _ of parseMultipartFormData(request, { maxFileSize: 10 * 1024 * 1024 })) { + for await (let _ of parseMultipartRequest(request, { maxFileSize: 10 * 1024 * 1024 })) { // Consume all parts } }, MultipartParseError); @@ -302,7 +347,7 @@ describe('parseMultipartFormData', async () => { }); let parts = []; - for await (let part of parseMultipartFormData(request)) { + for await (let part of parseMultipartRequest(request)) { parts.push(part); } @@ -326,7 +371,7 @@ describe('parseMultipartFormData', async () => { }); await assert.rejects(async () => { - for await (let _ of parseMultipartFormData(request)) { + for await (let _ of parseMultipartRequest(request)) { // Consume all parts } }, MultipartParseError); diff --git a/src/lib/multipart.ts b/src/lib/multipart-parser.ts similarity index 83% rename from src/lib/multipart.ts rename to src/lib/multipart-parser.ts index ef6d4413fba..946a8840c91 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart-parser.ts @@ -3,79 +3,53 @@ import { SuperHeaders } from 'fetch-super-headers'; import { concatChunks, decodeUtf8Stream, stringToBinary } from './utils.js'; /** - * Returns true if the request is `multipart/form-data`. + * Extracts the boundary string from a `multipart/*` content type. */ -export function isMultipartFormData(request: Request): boolean { +export function getMultipartBoundary(contentType: string): string | null { + let match = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(contentType); + return match ? match[1] || match[2] : null; +} + +/** + * Returns true if the given request contains multipart data. + */ +export function isMultipartRequest(request: Request): boolean { let contentType = request.headers.get('Content-Type'); - return contentType != null && contentType.startsWith('multipart/form-data'); + return contentType != null && /^multipart\//i.test(contentType); } /** - * Parse a `multipart/form-data` request body and yield each part as a `MultipartPart` object. - * - * Throw `MultipartParseError` if the parse fails for some reason. - * - * Example: - * - * ```typescript - * import { MultipartParseError, parseMultipartFormData } from 'fetch-multipart-parser'; - * - * function handleMultipartRequest(request: Request): void { - * try { - * for await (let part of parseMultipartFormData(request)) { - * console.log(part.name); - * console.log(part.filename); - * console.log(part.mediaType); - * - * if (/^text\//.test(part.mediaType)) { - * console.log(new TextDecoder().decode(part.content)); - * } else { - * // part.content is binary data, save it to a file - * } - * } - * } catch (error) { - * if (error instanceof MultipartParseError) { - * console.error('Failed to parse multipart/form-data:', error.message); - * } else { - * console.error('An unexpected error occurred:', error); - * } - * } - * } - * ``` + * Parse a multipart `Request` and yield each part as a `MultipartPart` object. */ -export async function* parseMultipartFormData( +export async function* parseMultipartRequest( request: Request, - options: MultipartParserOptions = {} + options?: MultipartParserOptions ): AsyncGenerator { - if (!isMultipartFormData(request)) { - throw new MultipartParseError('Request is not multipart/form-data'); + if (!isMultipartRequest(request)) { + throw new MultipartParseError('Request is not a multipart request'); } if (!request.body) { throw new MultipartParseError('Request body is empty'); } - let boundaryMatch = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(request.headers.get('Content-Type')!); - if (!boundaryMatch) { + let boundary = getMultipartBoundary(request.headers.get('Content-Type')!); + if (!boundary) { throw new MultipartParseError('Invalid Content-Type header: missing boundary'); } - let boundary = boundaryMatch[1] || boundaryMatch[2]; // handle quoted and unquoted boundaries - yield* parseMultipartStream(request.body, boundary, options); } /** * Parse a multipart stream and yield each part as a `MultipartPart` object. * - * Throw `MultipartParseError` if the parse fails for some reason. - * - * Note: This is a low-level API that requires manually handling the stream and boundary. For most common use cases, - * consider using `parseMultipartFormData(request)` instead. + * Note: This is a low-level API that requires manual handling of the stream and boundary. For most + * common cases, consider using `parseMultipartRequest(request)` instead. */ export async function* parseMultipartStream( stream: ReadableStream, boundary: string, - options: MultipartParserOptions = {} + options?: MultipartParserOptions ): AsyncGenerator { let parser = new MultipartParser(boundary, options); let reader = stream.getReader(); @@ -422,6 +396,9 @@ export class MultipartPart { return this._headers; } + /** + * True if this part originated from a file upload. + */ get isFile(): boolean { return this.filename !== null; } @@ -453,12 +430,8 @@ export class MultipartPart { * Note: Do not use this for binary data, use `await part.bytes()` or stream `part.body` directly instead. */ text(): Promise { - if (this._bodyUsed) { - throw new Error('Body is already consumed or is being consumed'); - } - + if (this._bodyUsed) throw new Error('Body is already consumed or is being consumed'); this._bodyUsed = true; - return decodeUtf8Stream(this.body); } } diff --git a/tsconfig.lib.json b/tsconfig.lib.json index 8e712f7d6c8..835ff13c105 100644 --- a/tsconfig.lib.json +++ b/tsconfig.lib.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts"], + "exclude": ["src/**/*.spec.ts", "src/fixtures/**/*.ts"], "compilerOptions": { "composite": true, "rootDir": "src" diff --git a/tsconfig.spec.json b/tsconfig.spec.json index 79d1e4a027a..b4737bca4c5 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -1,6 +1,6 @@ { "extends": "./tsconfig.json", - "include": ["src/**/*.ts"], + "include": ["src/**/*.spec.ts", "src/fixtures/**/*.ts"], "compilerOptions": { "composite": true, "types": ["node"] From 9f719b52e0873f499a90464cb4ca410924406da9 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 29 Jul 2024 09:53:19 -0700 Subject: [PATCH 100/730] Update README --- README.md | 38 ++++++++++++++++++++++---------------- package.json | 2 +- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index c3e12ef5c3f..73ad7b322b6 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,6 @@ - Parsing `multipart/mixed` messages (email attachments, API responses, etc.) - Parsing email messages with both plain text and HTML versions (`multipart/alternative`) -## Features - -This package is a streaming multipart parser for JavaScript's fetch API, making it easy to parse incoming `Request` bodies that are generated by `` in the browser. - ## Installation ```sh @@ -18,13 +14,15 @@ $ npm install @mjackson/multipart-parser ## Usage +If you're building a server you can use `multipart-parser` to handle file uploads. + ```typescript -import { MultipartParseError, parseMultipartFormData } from '@mjackson/multipart-parser'; +import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser'; async function handleMultipartRequest(request: Request): void { try { - // The parser `yield`s each part as a MultipartPart as it becomes available. - for await (let part of parseMultipartFormData(request)) { + // The parser `yield`s each MultipartPart as it becomes available. + for await (let part of parseMultipartRequest(request)) { console.log(part.name); console.log(part.filename); console.log(part.mediaType); @@ -37,7 +35,7 @@ async function handleMultipartRequest(request: Request): void { } } catch (error) { if (error instanceof MultipartParseError) { - console.error('Failed to parse multipart/form-data:', error.message); + console.error('Failed to parse multipart request:', error.message); } else { console.error('An unexpected error occurred:', error); } @@ -47,18 +45,26 @@ async function handleMultipartRequest(request: Request): void { ## Benchmark +`multipart-parser` is designed to be as efficient as possible, only operating on streams of data and never buffering in common usage. This design yields exceptional performance when handling multipart payloads of any size. For large payloads, `multipart-parser` is as fast or faster than `busboy`. + +To run the benchmarks yourself: + +```sh +$ pnpm run bench +``` + The results of running the benchmarks on my laptop: ``` Platform: Darwin (23.5.0) CPU: Apple M2 Pro Node.js v20.15.1 -Date: 7/28/2024, 8:16:46 AM -┌────────────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ -│ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ -├────────────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ fetch-multipart-parser │ '0.02 ms ± 0.13' │ '1.81 ms ± 0.10' │ '0.37 ms ± 0.14' │ '19.59 ms ± 1.25' │ -│ busboy │ '0.03 ms ± 0.09' │ '3.95 ms ± 0.19' │ '0.22 ms ± 0.02' │ '46.38 ms ± 2.98' │ -│ @fastify/busboy │ '0.03 ms ± 0.08' │ '1.94 ms ± 0.21' │ '0.38 ms ± 0.04' │ '26.46 ms ± 2.31' │ -└────────────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ +Date: 7/29/2024, 9:28:36 AM +┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ +│ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ +├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ +│ multipart-parser │ '0.02 ms ± 0.13' │ '1.86 ms ± 0.53' │ '0.37 ms ± 0.13' │ '19.49 ms ± 1.89' │ +│ busboy │ '0.03 ms ± 0.09' │ '3.97 ms ± 0.41' │ '0.22 ms ± 0.02' │ '45.94 ms ± 2.37' │ +│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.90 ms ± 0.16' │ '0.38 ms ± 0.04' │ '26.73 ms ± 2.48' │ +└──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ ``` diff --git a/package.json b/package.json index 166a9734355..127468048c7 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "typescript": "^5.5.3" }, "scripts": { - "bench": "node --import tsimp/import ./bench/runner.ts", + "bench": "(cd bench && pnpm install); node --import tsimp/import ./bench/runner.ts", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", "prepare": "npm run build", From 15d191f1bff412b9a57376f4708ebc0e9d0ec813 Mon Sep 17 00:00:00 2001 From: Jacob Ebey Date: Mon, 29 Jul 2024 12:49:54 -0700 Subject: [PATCH 101/730] chore: eliminate or operator in find function This improves performance by ~42% for large files. --- src/lib/multipart-parser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/multipart-parser.ts b/src/lib/multipart-parser.ts index 946a8840c91..501763fd7aa 100644 --- a/src/lib/multipart-parser.ts +++ b/src/lib/multipart-parser.ts @@ -338,7 +338,7 @@ function find( return k + 1; } - i += skipTable[byteAt(i)] || pattern.length; + i += skipTable[byteAt(i)]; } return -1; From c0f84a996f1f4715dc53481f8a0cd1b88578b369 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 29 Jul 2024 13:46:50 -0700 Subject: [PATCH 102/730] Add readStream util for reading streams --- src/lib/multipart-parser.ts | 51 ++++++++++++++++++++----------------- src/lib/utils.ts | 14 +++------- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/lib/multipart-parser.ts b/src/lib/multipart-parser.ts index 501763fd7aa..d64b410d7e2 100644 --- a/src/lib/multipart-parser.ts +++ b/src/lib/multipart-parser.ts @@ -1,6 +1,6 @@ import { SuperHeaders } from 'fetch-super-headers'; -import { concatChunks, decodeUtf8Stream, stringToBinary } from './utils.js'; +import { concatChunks, readStream, stringToBinary } from './utils.js'; /** * Extracts the boundary string from a `multipart/*` content type. @@ -52,26 +52,15 @@ export async function* parseMultipartStream( options?: MultipartParserOptions ): AsyncGenerator { let parser = new MultipartParser(boundary, options); - let reader = stream.getReader(); - try { - while (true) { - const { done, value } = await reader.read(); - - if (done) { - if (!parser.done) { - throw new MultipartParseError('Unexpected end of stream'); - } - - break; - } - - for (let part of parser.push(value)) { - yield part; - } + for await (let chunk of readStream(stream)) { + for (let part of parser.push(chunk)) { + yield part; } - } finally { - reader.releaseLock(); + } + + if (!parser.done) { + throw new MultipartParseError('Unexpected end of stream'); } } @@ -392,7 +381,10 @@ export class MultipartPart { * The headers associated with this part. */ get headers(): SuperHeaders { - if (!this._headers) this._headers = new SuperHeaders(textDecoder.decode(this._header)); + if (!this._headers) { + this._headers = new SuperHeaders(textDecoder.decode(this._header)); + } + return this._headers; } @@ -429,9 +421,22 @@ export class MultipartPart { * * Note: Do not use this for binary data, use `await part.bytes()` or stream `part.body` directly instead. */ - text(): Promise { - if (this._bodyUsed) throw new Error('Body is already consumed or is being consumed'); + async text(): Promise { + if (this._bodyUsed) { + throw new Error('Body is already consumed or is being consumed'); + } + this._bodyUsed = true; - return decodeUtf8Stream(this.body); + + let decoder = new TextDecoder('utf-8'); + + let string = ''; + for await (let chunk of readStream(this.body)) { + string += decoder.decode(chunk, { stream: true }); + } + + string += decoder.decode(); + + return string; } } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 1f34f229b26..1963da7a54a 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -13,22 +13,14 @@ export function concatChunks(chunks: Uint8Array[]): Uint8Array { return result; } -export async function decodeUtf8Stream(stream: ReadableStream): Promise { - let decoder = new TextDecoder('utf-8'); +export async function* readStream(stream: ReadableStream): AsyncGenerator { let reader = stream.getReader(); try { - let string = ''; - while (true) { const { done, value } = await reader.read(); - - if (done) { - string += decoder.decode(); - return string; - } - - string += decoder.decode(value, { stream: true }); + if (done) break; + yield value; } } finally { reader.releaseLock(); From f52cae2d403207146ca9b8eac452e1b2f056b81f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 29 Jul 2024 14:19:36 -0700 Subject: [PATCH 103/730] Update benchmark result --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 73ad7b322b6..ac7d9a09cb6 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ async function handleMultipartRequest(request: Request): void { ## Benchmark -`multipart-parser` is designed to be as efficient as possible, only operating on streams of data and never buffering in common usage. This design yields exceptional performance when handling multipart payloads of any size. For large payloads, `multipart-parser` is as fast or faster than `busboy`. +`multipart-parser` is designed to be as efficient as possible, only operating on streams of data and never buffering in common usage. This design yields exceptional performance when handling multipart payloads of any size. In most benchmarks, `multipart-parser` is as fast or faster than `busboy`. To run the benchmarks yourself: @@ -59,12 +59,12 @@ The results of running the benchmarks on my laptop: Platform: Darwin (23.5.0) CPU: Apple M2 Pro Node.js v20.15.1 -Date: 7/29/2024, 9:28:36 AM +Date: 7/29/2024, 2:15:40 PM ┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ multipart-parser │ '0.02 ms ± 0.13' │ '1.86 ms ± 0.53' │ '0.37 ms ± 0.13' │ '19.49 ms ± 1.89' │ -│ busboy │ '0.03 ms ± 0.09' │ '3.97 ms ± 0.41' │ '0.22 ms ± 0.02' │ '45.94 ms ± 2.37' │ -│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.90 ms ± 0.16' │ '0.38 ms ± 0.04' │ '26.73 ms ± 2.48' │ +│ multipart-parser │ '0.02 ms ± 0.15' │ '1.61 ms ± 0.07' │ '0.36 ms ± 0.13' │ '17.22 ms ± 1.03' │ +│ busboy │ '0.03 ms ± 0.09' │ '4.09 ms ± 0.21' │ '0.22 ms ± 0.03' │ '45.37 ms ± 2.76' │ +│ @fastify/busboy │ '0.03 ms ± 0.07' │ '2.33 ms ± 0.44' │ '0.40 ms ± 0.05' │ '27.02 ms ± 2.39' │ └──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ ``` From 078778a7c10254c7f38bae5ef5fdf3886383368e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 29 Jul 2024 14:23:00 -0700 Subject: [PATCH 104/730] Small tweaks --- src/lib/multipart-parser.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/lib/multipart-parser.ts b/src/lib/multipart-parser.ts index d64b410d7e2..499050b63a9 100644 --- a/src/lib/multipart-parser.ts +++ b/src/lib/multipart-parser.ts @@ -269,13 +269,8 @@ export class MultipartParser { } private save(): void { - if (this.chunk.length > 0) { - if (this.buffer.length > 0) { - this.buffer = concatChunks([this.buffer, this.chunk]); - } else { - this.buffer = this.chunk; - } - } + if (this.chunk.length === 0) return; + this.buffer = this.buffer.length > 0 ? concatChunks([this.buffer, this.chunk]) : this.chunk; } private writeBody(chunks: Uint8Array[]): void { @@ -337,7 +332,7 @@ function computeSkipTable(pattern: Uint8Array): Uint8Array { let table = new Uint8Array(256).fill(pattern.length); let lastIndex = pattern.length - 1; - for (let i = 0; i < lastIndex; i++) { + for (let i = 0; i < lastIndex; ++i) { table[pattern[i]] = lastIndex - i; } From 83f4bb501257c6ce3338d75dc9be93e14c280218 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 29 Jul 2024 19:00:54 -0700 Subject: [PATCH 105/730] Add clean script --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 127468048c7..89701082230 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "typescript": "^5.5.3" }, "scripts": { + "clean": "git clean -fdX .", "bench": "(cd bench && pnpm install); node --import tsimp/import ./bench/runner.ts", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", From 474170946fbfebd10d431b878ec7022760f10334 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 29 Jul 2024 19:06:43 -0700 Subject: [PATCH 106/730] Use pnpm workspaces --- bench/package.json | 1 + bench/parsers/multipart-parser.ts | 2 +- package.json | 2 +- pnpm-lock.yaml | 41 +++++++++++++++++++++++++++++++ pnpm-workspace.yaml | 2 ++ 5 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 pnpm-workspace.yaml diff --git a/bench/package.json b/bench/package.json index 846feb1fa2a..88a27c20e45 100644 --- a/bench/package.json +++ b/bench/package.json @@ -4,6 +4,7 @@ "type": "module", "dependencies": { "@fastify/busboy": "^3.0.0", + "@mjackson/multipart-parser": "workspace:*", "@types/busboy": "^1.5.4", "busboy": "^1.6.0" } diff --git a/bench/parsers/multipart-parser.ts b/bench/parsers/multipart-parser.ts index 58e49381ac5..704cf1f3c53 100644 --- a/bench/parsers/multipart-parser.ts +++ b/bench/parsers/multipart-parser.ts @@ -1,4 +1,4 @@ -import { parseMultipartRequest } from '../../dist/index.js'; +import { parseMultipartRequest } from '@mjackson/multipart-parser'; import { MultipartMessage } from '../messages.js'; diff --git a/package.json b/package.json index 89701082230..5b3d47d0f70 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "scripts": { "clean": "git clean -fdX .", - "bench": "(cd bench && pnpm install); node --import tsimp/import ./bench/runner.ts", + "bench": "node --import tsimp/import ./bench/runner.ts", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", "prepare": "npm run build", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7570fa95cbb..9b382372a15 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,8 +22,26 @@ importers: specifier: ^5.5.3 version: 5.5.3 + bench: + dependencies: + '@fastify/busboy': + specifier: ^3.0.0 + version: 3.0.0 + '@mjackson/multipart-parser': + specifier: workspace:* + version: link:.. + '@types/busboy': + specifier: ^1.5.4 + version: 1.5.4 + busboy: + specifier: ^1.6.0 + version: 1.6.0 + packages: + '@fastify/busboy@3.0.0': + resolution: {integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==} + '@isaacs/cached@1.0.1': resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} @@ -38,6 +56,9 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@types/busboy@1.5.4': + resolution: {integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==} + '@types/node@20.14.10': resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==} @@ -63,6 +84,10 @@ packages: brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -160,6 +185,10 @@ packages: socket-post-message@1.0.3: resolution: {integrity: sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==} + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -209,6 +238,8 @@ packages: snapshots: + '@fastify/busboy@3.0.0': {} + '@isaacs/cached@1.0.1': dependencies: '@isaacs/catcher': 1.0.4 @@ -227,6 +258,10 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@types/busboy@1.5.4': + dependencies: + '@types/node': 20.14.10 + '@types/node@20.14.10': dependencies: undici-types: 5.26.5 @@ -247,6 +282,10 @@ snapshots: dependencies: balanced-match: 1.0.2 + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -332,6 +371,8 @@ snapshots: socket-post-message@1.0.3: {} + streamsearch@1.1.0: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 00000000000..e3e11e26a95 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - 'bench' \ No newline at end of file From 10892db0b5ff5256c238c7967c656cd1a28b45f6 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 29 Jul 2024 19:07:03 -0700 Subject: [PATCH 107/730] Fix description --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5b3d47d0f70..9d805588389 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@mjackson/multipart-parser", "version": "0.1.0", - "description": "A fast, efficient parser for multpart streams", + "description": "A fast, efficient parser for multipart streams", "author": "Michael Jackson ", "license": "MIT", "files": [ From dd3e3dc2d9c9b9d8592128f619f3cf20bc24410f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 29 Jul 2024 19:15:34 -0700 Subject: [PATCH 108/730] Re-org test utils --- src/lib/multipart-parser.spec.ts | 96 +------------------ src/{fixtures/utils.ts => test/fixtures.ts} | 2 +- src/{ => test}/fixtures/Tesla-Roadster.jpg | Bin src/test/utils.ts | 99 ++++++++++++++++++++ tsconfig.lib.json | 2 +- tsconfig.spec.json | 2 +- 6 files changed, 104 insertions(+), 97 deletions(-) rename src/{fixtures/utils.ts => test/fixtures.ts} (81%) rename src/{ => test}/fixtures/Tesla-Roadster.jpg (100%) create mode 100644 src/test/utils.ts diff --git a/src/lib/multipart-parser.spec.ts b/src/lib/multipart-parser.spec.ts index 856c4ce5fe3..34457849477 100644 --- a/src/lib/multipart-parser.spec.ts +++ b/src/lib/multipart-parser.spec.ts @@ -1,109 +1,17 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { ContentDisposition, ContentType, SuperHeaders } from 'fetch-super-headers'; - -import { readFixture } from '../fixtures/utils.js'; +import { readFixture } from '../test/fixtures.js'; +import { CRLF, createMockRequest, createMultipartMockRequest } from '../test/utils.js'; import { isMultipartRequest, parseMultipartRequest, MultipartParseError, getMultipartBoundary, } from './multipart-parser.js'; -import { binaryToString } from './utils.js'; const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); -const CRLF = '\r\n'; - -function createReadableStream(content: string, chunkSize = 16 * 1024): ReadableStream { - let encoder = new TextEncoder(); - return new ReadableStream({ - start(controller) { - for (let i = 0; i < content.length; i += chunkSize) { - controller.enqueue(encoder.encode(content.slice(i, i + chunkSize))); - } - controller.close(); - }, - }); -} - -function createMockRequest({ - headers, - body = '', -}: { - headers?: Headers | HeadersInit; - body?: string | ReadableStream; -}): Request { - return { - headers: headers instanceof Headers ? headers : new Headers(headers), - body: typeof body === 'string' ? createReadableStream(body) : body, - } as unknown as Request; -} - -type PartValue = - | string - | { - filename?: string; - filenameSplat?: string; - mediaType?: string; - content: string | Uint8Array; - }; - -function createMultipartBody(boundary: string, parts?: { [name: string]: PartValue }): string { - let lines = []; - - if (parts) { - for (let [name, part] of Object.entries(parts)) { - lines.push(`--${boundary}`); - - if (typeof part === 'string') { - let contentDisposition = new ContentDisposition(); - contentDisposition.type = 'form-data'; - contentDisposition.name = name; - lines.push(`Content-Disposition: ${contentDisposition}`); - lines.push(''); - lines.push(part); - } else { - let contentDisposition = new ContentDisposition(); - contentDisposition.type = 'form-data'; - contentDisposition.name = name; - contentDisposition.filename = part.filename; - contentDisposition.filenameSplat = part.filenameSplat; - - lines.push(`Content-Disposition: ${contentDisposition}`); - - if (part.mediaType) { - let contentType = new ContentType(); - contentType.mediaType = part.mediaType; - - lines.push(`Content-Type: ${contentType}`); - } - - lines.push(''); - lines.push(typeof part.content === 'string' ? part.content : binaryToString(part.content)); - } - } - } - - lines.push(`--${boundary}--`); - - return lines.join(CRLF); -} - -function createMultipartMockRequest( - boundary: string, - parts?: { [name: string]: PartValue } -): Request { - let headers = new SuperHeaders(); - headers.contentType.mediaType = 'multipart/form-data'; - headers.contentType.boundary = boundary; - - let body = createMultipartBody(boundary, parts); - - return createMockRequest({ headers, body }); -} - describe('getMultipartBoundary', async () => { it('returns the boundary from the Content-Type header', async () => { assert.equal(getMultipartBoundary('multipart/form-data; boundary=boundary123'), 'boundary123'); diff --git a/src/fixtures/utils.ts b/src/test/fixtures.ts similarity index 81% rename from src/fixtures/utils.ts rename to src/test/fixtures.ts index 2e1ccd55fc8..d9b41521028 100644 --- a/src/fixtures/utils.ts +++ b/src/test/fixtures.ts @@ -4,7 +4,7 @@ import * as fs from 'node:fs'; const __dirname = path.dirname(new URL(import.meta.url).pathname); export function readFixture(name: string): Uint8Array { - let file = path.resolve(__dirname, `./${name}`); + let file = path.resolve(__dirname, `./fixtures/${name}`); let buffer = fs.readFileSync(file); return new Uint8Array(buffer); } diff --git a/src/fixtures/Tesla-Roadster.jpg b/src/test/fixtures/Tesla-Roadster.jpg similarity index 100% rename from src/fixtures/Tesla-Roadster.jpg rename to src/test/fixtures/Tesla-Roadster.jpg diff --git a/src/test/utils.ts b/src/test/utils.ts new file mode 100644 index 00000000000..1adef245b3d --- /dev/null +++ b/src/test/utils.ts @@ -0,0 +1,99 @@ +import { ContentDisposition, ContentType, SuperHeaders } from 'fetch-super-headers'; + +import { binaryToString } from '../lib/utils.js'; + +export const CRLF = '\r\n'; + +export function createReadableStream( + content: string, + chunkSize = 16 * 1024 +): ReadableStream { + let encoder = new TextEncoder(); + return new ReadableStream({ + start(controller) { + for (let i = 0; i < content.length; i += chunkSize) { + controller.enqueue(encoder.encode(content.slice(i, i + chunkSize))); + } + controller.close(); + }, + }); +} + +export function createMockRequest({ + headers, + body = '', +}: { + headers?: Headers | HeadersInit; + body?: string | ReadableStream; +}): Request { + return { + headers: headers instanceof Headers ? headers : new Headers(headers), + body: typeof body === 'string' ? createReadableStream(body) : body, + } as unknown as Request; +} + +type PartValue = + | string + | { + filename?: string; + filenameSplat?: string; + mediaType?: string; + content: string | Uint8Array; + }; + +export function createMultipartBody( + boundary: string, + parts?: { [name: string]: PartValue } +): string { + let lines = []; + + if (parts) { + for (let [name, part] of Object.entries(parts)) { + lines.push(`--${boundary}`); + + if (typeof part === 'string') { + let contentDisposition = new ContentDisposition(); + contentDisposition.type = 'form-data'; + contentDisposition.name = name; + lines.push(`Content-Disposition: ${contentDisposition}`); + lines.push(''); + lines.push(part); + } else { + let contentDisposition = new ContentDisposition(); + contentDisposition.type = 'form-data'; + contentDisposition.name = name; + contentDisposition.filename = part.filename; + contentDisposition.filenameSplat = part.filenameSplat; + + lines.push(`Content-Disposition: ${contentDisposition}`); + + if (part.mediaType) { + let contentType = new ContentType(); + contentType.mediaType = part.mediaType; + + lines.push(`Content-Type: ${contentType}`); + } + + lines.push(''); + lines.push(typeof part.content === 'string' ? part.content : binaryToString(part.content)); + } + } + } + + lines.push(`--${boundary}--`); + + return lines.join(CRLF); +} + +export function createMultipartMockRequest( + boundary: string, + parts?: { [name: string]: PartValue } +): Request { + let headers = new SuperHeaders(); + headers.contentType.mediaType = 'multipart/form-data'; + headers.contentType.boundary = boundary; + + let body = createMultipartBody(boundary, parts); + + return createMockRequest({ headers, body }); +} diff --git a/tsconfig.lib.json b/tsconfig.lib.json index 835ff13c105..c9819aa7ed5 100644 --- a/tsconfig.lib.json +++ b/tsconfig.lib.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts", "src/fixtures/**/*.ts"], + "exclude": ["src/**/*.spec.ts", "src/test/**/*.ts"], "compilerOptions": { "composite": true, "rootDir": "src" diff --git a/tsconfig.spec.json b/tsconfig.spec.json index b4737bca4c5..0dcc65f3ce6 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -1,6 +1,6 @@ { "extends": "./tsconfig.json", - "include": ["src/**/*.spec.ts", "src/fixtures/**/*.ts"], + "include": ["src/**/*.spec.ts", "src/test/**/*.ts"], "compilerOptions": { "composite": true, "types": ["node"] From 505e03606b6b184ada6929fb6b6379532ba784a5 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 29 Jul 2024 19:34:13 -0700 Subject: [PATCH 109/730] Remove old lockfile --- bench/pnpm-lock.yaml | 61 -------------------------------------------- 1 file changed, 61 deletions(-) delete mode 100644 bench/pnpm-lock.yaml diff --git a/bench/pnpm-lock.yaml b/bench/pnpm-lock.yaml deleted file mode 100644 index a7e589cd8da..00000000000 --- a/bench/pnpm-lock.yaml +++ /dev/null @@ -1,61 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@fastify/busboy': - specifier: ^3.0.0 - version: 3.0.0 - '@types/busboy': - specifier: ^1.5.4 - version: 1.5.4 - busboy: - specifier: ^1.6.0 - version: 1.6.0 - -packages: - - '@fastify/busboy@3.0.0': - resolution: {integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==} - - '@types/busboy@1.5.4': - resolution: {integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==} - - '@types/node@20.14.11': - resolution: {integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==} - - busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} - - streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - -snapshots: - - '@fastify/busboy@3.0.0': {} - - '@types/busboy@1.5.4': - dependencies: - '@types/node': 20.14.11 - - '@types/node@20.14.11': - dependencies: - undici-types: 5.26.5 - - busboy@1.6.0: - dependencies: - streamsearch: 1.1.0 - - streamsearch@1.1.0: {} - - undici-types@5.26.5: {} From 97d996f4788b6ddab84820b467dc85ee22d6cc34 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 29 Jul 2024 19:45:50 -0700 Subject: [PATCH 110/730] Add test to demonstrate deadlocking bug :( --- src/lib/multipart-parser.spec.ts | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/lib/multipart-parser.spec.ts b/src/lib/multipart-parser.spec.ts index 34457849477..0a98474bdf8 100644 --- a/src/lib/multipart-parser.spec.ts +++ b/src/lib/multipart-parser.spec.ts @@ -52,7 +52,7 @@ describe('isMultipartRequest', async () => { }); }); -describe('parseMultipartRequest', async () => { +describe.only('parseMultipartRequest', async () => { let boundary = 'boundary123'; it('parses an empty multipart message', async () => { @@ -162,6 +162,31 @@ describe('parseMultipartRequest', async () => { assert.equal(await parts[2].text(), 'File content'); }); + it.only('allows buffering part contents while parsing', async () => { + let request = createMultipartMockRequest(boundary, { + file1: { + filename: 'tesla.jpg', + mediaType: 'image/jpeg', + content: TeslaRoadster, + }, + file2: { + filename: 'tesla.jpg', + mediaType: 'image/jpeg', + content: TeslaRoadster, + }, + }); + + let parts = []; + for await (let part of parseMultipartRequest(request)) { + parts.push({ + name: part.name, + content: await part.bytes(), + }); + } + + assert.equal(parts.length, 2); + }); + it('parses large file uploads correctly', async () => { let request = createMultipartMockRequest(boundary, { file1: { From 591ea4616584a505d5bde745f96615b12b653d61 Mon Sep 17 00:00:00 2001 From: Jacob Ebey Date: Tue, 30 Jul 2024 08:56:22 -0700 Subject: [PATCH 111/730] fix: avoid deadlock caused by a race from yielding sources --- src/lib/multipart-parser.ts | 56 ++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/src/lib/multipart-parser.ts b/src/lib/multipart-parser.ts index 499050b63a9..d0bb2c6d571 100644 --- a/src/lib/multipart-parser.ts +++ b/src/lib/multipart-parser.ts @@ -53,15 +53,43 @@ export async function* parseMultipartStream( ): AsyncGenerator { let parser = new MultipartParser(boundary, options); - for await (let chunk of readStream(stream)) { - for (let part of parser.push(chunk)) { + let done = false; + let resolveNextChunk!: () => void; + let nextChunkPromise: Promise | null; + let promise = (async () => { + try { + for await (let chunk of readStream(stream)) { + parser.push(chunk); + resolveNextChunk(); + } + } finally { + resolveNextChunk(); + done = true; + } + })(); + promise.catch(() => {}); + + while (!done) { + nextChunkPromise = new Promise((resolve) => { + resolveNextChunk = resolve; + }); + await nextChunkPromise; + let partsToYield = parser.parts; + parser.parts = []; + for (let part of partsToYield) { yield part; } } + for (let part of parser.parts) { + yield part; + } + if (!parser.done) { throw new MultipartParseError('Unexpected end of stream'); } + + await promise; } const HYPHEN = 45; @@ -105,11 +133,13 @@ export class MultipartParser { private state = MultipartParserState.Start; private buffer: Uint8Array = EMPTY_BUFFER; private chunk: Uint8Array = EMPTY_BUFFER; - private length: number = 0; + private length = 0; private bodyController: ReadableStreamDefaultController | null = null; private bodyLength = 0; + public parts: MultipartPart[] = []; + constructor( public boundary: string, { @@ -128,7 +158,7 @@ export class MultipartParser { return this.state === MultipartParserState.Done; } - push(chunk: Uint8Array): MultipartPart[] { + push(chunk: Uint8Array) { if (this.done) { throw new MultipartParseError('Cannot push, parser is done'); } @@ -152,8 +182,6 @@ export class MultipartParser { this.state = MultipartParserState.AfterBoundary; } - let parts: MultipartPart[] = []; - while (true) { if (this.state === MultipartParserState.AfterBoundary) { if (this.length < 2) { @@ -202,7 +230,7 @@ export class MultipartParser { }, }); - parts.push(new MultipartPart(header, body)); + this.parts.push(new MultipartPart(header, body)); this.state = MultipartParserState.Body; } @@ -231,8 +259,6 @@ export class MultipartParser { this.state = MultipartParserState.AfterBoundary; } } - - return parts; } private read(size: number): Uint8Array[] { @@ -245,16 +271,14 @@ export class MultipartParser { let tail = this.chunk.subarray(0, size - head.length); this.chunk = this.chunk.subarray(size - head.length); return [head, tail]; - } else { - let head = this.chunk.subarray(0, size); - this.chunk = this.chunk.subarray(size); - return [head]; } - } else { - let head = this.buffer.subarray(0, size); - this.buffer = this.buffer.subarray(size); + let head = this.chunk.subarray(0, size); + this.chunk = this.chunk.subarray(size); return [head]; } + let head = this.buffer.subarray(0, size); + this.buffer = this.buffer.subarray(size); + return [head]; } private skip(size: number): void { From 4133bf1b739117ecc263e9ad6be8c4cd23f825d3 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 30 Jul 2024 18:57:31 -0700 Subject: [PATCH 112/730] Keep parts in a local buffer instead of parser.parts --- src/lib/multipart-parser.spec.ts | 4 +-- src/lib/multipart-parser.ts | 59 +++++++++++++++----------------- src/lib/utils.ts | 7 ++-- 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/src/lib/multipart-parser.spec.ts b/src/lib/multipart-parser.spec.ts index 0a98474bdf8..958b9c51376 100644 --- a/src/lib/multipart-parser.spec.ts +++ b/src/lib/multipart-parser.spec.ts @@ -52,7 +52,7 @@ describe('isMultipartRequest', async () => { }); }); -describe.only('parseMultipartRequest', async () => { +describe('parseMultipartRequest', async () => { let boundary = 'boundary123'; it('parses an empty multipart message', async () => { @@ -162,7 +162,7 @@ describe.only('parseMultipartRequest', async () => { assert.equal(await parts[2].text(), 'File content'); }); - it.only('allows buffering part contents while parsing', async () => { + it('allows buffering part contents while parsing', async () => { let request = createMultipartMockRequest(boundary, { file1: { filename: 'tesla.jpg', diff --git a/src/lib/multipart-parser.ts b/src/lib/multipart-parser.ts index d0bb2c6d571..bc490ac8572 100644 --- a/src/lib/multipart-parser.ts +++ b/src/lib/multipart-parser.ts @@ -53,43 +53,36 @@ export async function* parseMultipartStream( ): AsyncGenerator { let parser = new MultipartParser(boundary, options); + // Since the top-level API is an async generator, we need to buffer parts + // until they're requested by the consumer. + let parts: MultipartPart[] = []; + let done = false; - let resolveNextChunk!: () => void; - let nextChunkPromise: Promise | null; - let promise = (async () => { - try { - for await (let chunk of readStream(stream)) { - parser.push(chunk); - resolveNextChunk(); - } - } finally { - resolveNextChunk(); - done = true; - } - })(); - promise.catch(() => {}); + let runTheLoop: () => void; + let promise = readStream(stream, (chunk) => { + parts.push(...parser.push(chunk)); + runTheLoop(); + }).finally(() => { + done = true; + runTheLoop(); + }); while (!done) { - nextChunkPromise = new Promise((resolve) => { - resolveNextChunk = resolve; + await new Promise((resolve) => { + runTheLoop = resolve; }); - await nextChunkPromise; - let partsToYield = parser.parts; - parser.parts = []; - for (let part of partsToYield) { - yield part; + + while (parts.length > 0) { + yield parts.shift()!; } } - for (let part of parser.parts) { - yield part; - } + // Throw any errors that occurred during parsing. + await promise; if (!parser.done) { throw new MultipartParseError('Unexpected end of stream'); } - - await promise; } const HYPHEN = 45; @@ -138,8 +131,6 @@ export class MultipartParser { private bodyController: ReadableStreamDefaultController | null = null; private bodyLength = 0; - public parts: MultipartPart[] = []; - constructor( public boundary: string, { @@ -158,7 +149,7 @@ export class MultipartParser { return this.state === MultipartParserState.Done; } - push(chunk: Uint8Array) { + push(chunk: Uint8Array): MultipartPart[] { if (this.done) { throw new MultipartParseError('Cannot push, parser is done'); } @@ -182,6 +173,8 @@ export class MultipartParser { this.state = MultipartParserState.AfterBoundary; } + let parts: MultipartPart[] = []; + while (true) { if (this.state === MultipartParserState.AfterBoundary) { if (this.length < 2) { @@ -230,7 +223,7 @@ export class MultipartParser { }, }); - this.parts.push(new MultipartPart(header, body)); + parts.push(new MultipartPart(header, body)); this.state = MultipartParserState.Body; } @@ -259,6 +252,8 @@ export class MultipartParser { this.state = MultipartParserState.AfterBoundary; } } + + return parts; } private read(size: number): Uint8Array[] { @@ -450,9 +445,9 @@ export class MultipartPart { let decoder = new TextDecoder('utf-8'); let string = ''; - for await (let chunk of readStream(this.body)) { + await readStream(this.body, (chunk) => { string += decoder.decode(chunk, { stream: true }); - } + }); string += decoder.decode(); diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 1963da7a54a..ec73721b558 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -13,14 +13,17 @@ export function concatChunks(chunks: Uint8Array[]): Uint8Array { return result; } -export async function* readStream(stream: ReadableStream): AsyncGenerator { +export async function readStream( + stream: ReadableStream, + callback: (chunk: T) => void +): Promise { let reader = stream.getReader(); try { while (true) { const { done, value } = await reader.read(); if (done) break; - yield value; + callback(value); } } finally { reader.releaseLock(); From fdf00130b117469e7b5b60d3384be2c6d65c2036 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 30 Jul 2024 19:04:49 -0700 Subject: [PATCH 113/730] Update benchmark --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ac7d9a09cb6..c9ee0c5a59d 100644 --- a/README.md +++ b/README.md @@ -57,14 +57,14 @@ The results of running the benchmarks on my laptop: ``` Platform: Darwin (23.5.0) -CPU: Apple M2 Pro -Node.js v20.15.1 -Date: 7/29/2024, 2:15:40 PM +CPU: Apple M1 Pro +Node.js v20.15.0 +Date: 7/30/2024, 7:01:45 PM ┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ multipart-parser │ '0.02 ms ± 0.15' │ '1.61 ms ± 0.07' │ '0.36 ms ± 0.13' │ '17.22 ms ± 1.03' │ -│ busboy │ '0.03 ms ± 0.09' │ '4.09 ms ± 0.21' │ '0.22 ms ± 0.03' │ '45.37 ms ± 2.76' │ -│ @fastify/busboy │ '0.03 ms ± 0.07' │ '2.33 ms ± 0.44' │ '0.40 ms ± 0.05' │ '27.02 ms ± 2.39' │ +│ multipart-parser │ '0.02 ms ± 0.10' │ '1.49 ms ± 0.06' │ '0.38 ms ± 0.17' │ '16.17 ms ± 1.66' │ +│ busboy │ '0.03 ms ± 0.09' │ '4.34 ms ± 0.21' │ '0.23 ms ± 0.03' │ '48.82 ms ± 1.30' │ +│ @fastify/busboy │ '0.03 ms ± 0.07' │ '2.13 ms ± 0.29' │ '0.40 ms ± 0.06' │ '26.67 ms ± 1.22' │ └──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ ``` From c4966062db01c5cbbfaaae62c142942c9dd9df17 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 30 Jul 2024 19:12:57 -0700 Subject: [PATCH 114/730] whitespace --- src/lib/multipart-parser.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/multipart-parser.ts b/src/lib/multipart-parser.ts index bc490ac8572..46c763283b2 100644 --- a/src/lib/multipart-parser.ts +++ b/src/lib/multipart-parser.ts @@ -267,10 +267,12 @@ export class MultipartParser { this.chunk = this.chunk.subarray(size - head.length); return [head, tail]; } + let head = this.chunk.subarray(0, size); this.chunk = this.chunk.subarray(size); return [head]; } + let head = this.buffer.subarray(0, size); this.buffer = this.buffer.subarray(size); return [head]; From dcfee93a632ce150eca6827cb00ff38e3001ea45 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 30 Jul 2024 22:39:09 -0700 Subject: [PATCH 115/730] Better comment --- src/lib/multipart-parser.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lib/multipart-parser.ts b/src/lib/multipart-parser.ts index 46c763283b2..feb640d7b8d 100644 --- a/src/lib/multipart-parser.ts +++ b/src/lib/multipart-parser.ts @@ -53,10 +53,13 @@ export async function* parseMultipartStream( ): AsyncGenerator { let parser = new MultipartParser(boundary, options); - // Since the top-level API is an async generator, we need to buffer parts - // until they're requested by the consumer. + // The async generator will suspend execution of this function until the next part + // is requested. This has the potential to cause a deadlock if the consumer tries + // to `await part.text()` while the parser is waiting for more bytes. To fix this, + // we read the stream in a promise and buffer parts until they're requested. When + // new parts become available or when we're done reading the stream, we manually + // run the loop to yield the buffered parts. let parts: MultipartPart[] = []; - let done = false; let runTheLoop: () => void; let promise = readStream(stream, (chunk) => { From deffb1587cbe282b6c6dda13e0714305e070016f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 29 Jul 2024 19:33:52 -0700 Subject: [PATCH 116/730] Add /node module --- README.md | 32 +++++++++ package.json | 6 +- pnpm-lock.yaml | 6 ++ src/lib/multipart-parser-node.spec.ts | 88 +++++++++++++++++++++++++ src/lib/multipart-parser-node.ts | 94 +++++++++++++++++++++++++++ src/lib/multipart-parser.ts | 2 +- src/node.ts | 5 ++ src/test/utils-node.ts | 33 ++++++++++ src/test/utils.ts | 3 +- 9 files changed, 266 insertions(+), 3 deletions(-) create mode 100644 src/lib/multipart-parser-node.spec.ts create mode 100644 src/lib/multipart-parser-node.ts create mode 100644 src/node.ts create mode 100644 src/test/utils-node.ts diff --git a/README.md b/README.md index c9ee0c5a59d..29b09703c49 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,38 @@ async function handleMultipartRequest(request: Request): void { } ``` +The main module (`import from "@mjackson/multipart-parser"`) assumes you're working with [the fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) (`Request`, `ReadableStream`, etc). Support for these interfaces was added to node.js by the [undici](https://github.com/nodejs/undici) project in [version 16.5.0](https://nodejs.org/en/blog/release/v16.5.0). + +If however you're building a server for node.js that still relies on slightly older APIs like `http.IncomingMessage`, `stream.Readable`, and `buffer.Buffer` (ala Express or `http.createServer`), `multipart-parser` ships with an additional module that works directly with these APIs. + +```typescript +import * as http from 'node:http'; + +import { MultipartParseError } from '@mjackson/multipart-parser'; +// Note: Import from multipart-parser/node for node-specific APIs +import { parseMultipartRequest } from '@mjackson/multipart-parser/node'; + +const server = http.createServer(async (req, res) => { + try { + for await (let part of parseMultipartRequest(req)) { + console.log(part.name); + console.log(part.filename); + console.log(part.mediaType); + + // ... + } + } catch (error) { + if (error instanceof MultipartParseError) { + console.error('Failed to parse multipart request:', error.message); + } else { + console.error('An unexpected error occurred:', error); + } + } +}); + +server.listen(8080); +``` + ## Benchmark `multipart-parser` is designed to be as efficient as possible, only operating on streams of data and never buffering in common usage. This design yields exceptional performance when handling multipart payloads of any size. In most benchmarks, `multipart-parser` is as fast or faster than `busboy`. diff --git a/package.json b/package.json index 9d805588389..cf92e1d431f 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,11 @@ "README.md" ], "type": "module", - "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js", + "./node": "./dist/node.js", + "./package.json": "./package.json" + }, "dependencies": { "fetch-super-headers": "^0.4.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9b382372a15..1d725761de9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -37,6 +37,12 @@ importers: specifier: ^1.6.0 version: 1.6.0 + examples/node-server: + dependencies: + '@mjackson/multipart-parser': + specifier: workspace:* + version: link:../.. + packages: '@fastify/busboy@3.0.0': diff --git a/src/lib/multipart-parser-node.spec.ts b/src/lib/multipart-parser-node.spec.ts new file mode 100644 index 00000000000..08dbb4c3d39 --- /dev/null +++ b/src/lib/multipart-parser-node.spec.ts @@ -0,0 +1,88 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { readFixture } from '../test/fixtures.js'; +import { createMultipartMockRequest } from '../test/utils-node.js'; +import { parseMultipartRequest } from './multipart-parser-node.js'; + +const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); + +describe('parseMultipartRequest (node)', () => { + let boundary = 'boundary123'; + + it('parses an empty multipart message', async () => { + let request = createMultipartMockRequest(boundary); + + let parts = []; + for await (let part of parseMultipartRequest(request)) { + parts.push(part); + } + + assert.equal(parts.length, 0); + }); + + it('parses a simple multipart form', async () => { + let request = createMultipartMockRequest(boundary, { + field1: 'value1', + }); + + let parts = []; + for await (let part of parseMultipartRequest(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'field1'); + assert.equal(await parts[0].text(), 'value1'); + }); + + it('parses large file uploads correctly', async () => { + let request = createMultipartMockRequest(boundary, { + file1: { + filename: 'tesla.jpg', + mediaType: 'image/jpeg', + content: TeslaRoadster, + }, + }); + + let parts = []; + for await (let part of parseMultipartRequest(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'file1'); + assert.equal(parts[0].filename, 'tesla.jpg'); + assert.equal(parts[0].mediaType, 'image/jpeg'); + assert.deepEqual(await parts[0].bytes(), TeslaRoadster); + }); + + it('allows buffering part contents while parsing', async () => { + let request = createMultipartMockRequest(boundary, { + file1: { + filename: 'tesla.jpg', + mediaType: 'image/jpeg', + content: TeslaRoadster, + }, + file2: { + filename: 'tesla.jpg', + mediaType: 'image/jpeg', + content: TeslaRoadster, + }, + }); + + let parts = []; + for await (let part of parseMultipartRequest(request)) { + parts.push({ + name: part.name, + content: await part.bytes(), + }); + } + + assert.equal(parts.length, 2); + assert.equal(parts[0].name, 'file1'); + assert.deepEqual(parts[0].content, TeslaRoadster); + assert.equal(parts[1].name, 'file2'); + assert.deepEqual(parts[1].content, TeslaRoadster); + }); +}); diff --git a/src/lib/multipart-parser-node.ts b/src/lib/multipart-parser-node.ts new file mode 100644 index 00000000000..d9f15d22fde --- /dev/null +++ b/src/lib/multipart-parser-node.ts @@ -0,0 +1,94 @@ +import * as http from 'node:http'; +import * as stream from 'node:stream'; + +import { + getMultipartBoundary, + MultipartParseError, + MultipartParserOptions, + MultipartParser, + MultipartPart, +} from './multipart-parser.js'; + +/** + * Returns true if the given request is a multipart request. + */ +export function isMultipartRequest(request: http.IncomingMessage): boolean { + let contentType = request.headers['content-type']; + return contentType != null && /^multipart\//i.test(contentType); +} + +/** + * Parse a multipart node.js request and yield each part as a `MultipartPart` object. + */ +export async function* parseMultipartRequest( + request: http.IncomingMessage, + options?: MultipartParserOptions +): AsyncGenerator { + if (!isMultipartRequest(request)) { + throw new MultipartParseError('Request is not a multipart request'); + } + + let boundary = getMultipartBoundary(request.headers['content-type']!); + if (!boundary) { + throw new MultipartParseError('Invalid Content-Type header: missing boundary'); + } + + yield* parseMultipartStream(request, boundary, options); +} + +/** + * Parse a multipart node.js `Readable` stream and yield each part as a `MultipartPart` object. + * + * Note: This is a low-level API that requires manual handling of the stream and boundary. For most + * common cases, consider using `parseMultipartRequest(request)` instead. + */ +export async function* parseMultipartStream( + stream: stream.Readable, + boundary: string, + options?: MultipartParserOptions +): AsyncGenerator { + let parser = new MultipartParser(boundary, options); + + // The async generator will suspend execution of this function until the next part + // is requested. This has the potential to cause a deadlock if the consumer tries + // to `await part.text()` while the parser is waiting for more bytes. To fix this, + // we read the stream in a promise and buffer parts until they're requested. When + // new parts become available or when we're done reading the stream, we manually + // run the loop to yield the buffered parts. + let parts: MultipartPart[] = []; + let done = false; + let runTheLoop: () => void; + let promise = readStream(stream, (chunk) => { + parts.push(...parser.push(chunk)); + runTheLoop(); + }).finally(() => { + done = true; + runTheLoop(); + }); + + while (!done) { + await new Promise((resolve) => { + runTheLoop = resolve; + }); + + while (parts.length > 0) { + yield parts.shift()!; + } + } + + // Throw any errors that occurred during the parse. + await promise; + + if (!parser.done) { + throw new MultipartParseError('Unexpected end of stream'); + } +} + +function readStream(stream: stream.Readable, callback: (chunk: Buffer) => void): Promise { + return new Promise((resolve, reject) => { + stream.on('data', callback); + stream.on('error', reject); + stream.on('end', resolve); + stream.resume(); + }); +} diff --git a/src/lib/multipart-parser.ts b/src/lib/multipart-parser.ts index feb640d7b8d..3634aedfdbf 100644 --- a/src/lib/multipart-parser.ts +++ b/src/lib/multipart-parser.ts @@ -80,7 +80,7 @@ export async function* parseMultipartStream( } } - // Throw any errors that occurred during parsing. + // Throw any errors that occurred during the parse. await promise; if (!parser.done) { diff --git a/src/node.ts b/src/node.ts new file mode 100644 index 00000000000..b567a7d666a --- /dev/null +++ b/src/node.ts @@ -0,0 +1,5 @@ +export { + isMultipartRequest, + parseMultipartRequest, + parseMultipartStream, +} from './lib/multipart-parser-node.js'; diff --git a/src/test/utils-node.ts b/src/test/utils-node.ts new file mode 100644 index 00000000000..683947aadc5 --- /dev/null +++ b/src/test/utils-node.ts @@ -0,0 +1,33 @@ +import * as http from 'node:http'; +import * as stream from 'node:stream'; + +import { PartValue, createMultipartBody } from './utils.js'; + +export function createReadable(content: string, chunkSize = 16 * 1024): stream.Readable { + let i = 0; + + return new stream.Readable({ + read() { + if (i < content.length) { + this.push(Buffer.from(content.slice(i, i + chunkSize))); + i += chunkSize; + } else { + this.push(null); + } + }, + }); +} + +export function createMultipartMockRequest( + boundary: string, + parts?: { [name: string]: PartValue } +): http.IncomingMessage { + let body = createMultipartBody(boundary, parts); + + let request = createReadable(body) as http.IncomingMessage; + request.headers = { + 'content-type': `multipart/form-data; boundary=${boundary}`, + }; + + return request; +} diff --git a/src/test/utils.ts b/src/test/utils.ts index 1adef245b3d..1ba32af7373 100644 --- a/src/test/utils.ts +++ b/src/test/utils.ts @@ -9,6 +9,7 @@ export function createReadableStream( chunkSize = 16 * 1024 ): ReadableStream { let encoder = new TextEncoder(); + return new ReadableStream({ start(controller) { for (let i = 0; i < content.length; i += chunkSize) { @@ -32,7 +33,7 @@ export function createMockRequest({ } as unknown as Request; } -type PartValue = +export type PartValue = | string | { filename?: string; From 26d68922a8097e30203ffda2909c13a4b9819023 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 29 Jul 2024 19:35:52 -0700 Subject: [PATCH 117/730] Add node server example --- examples/node-server/package.json | 11 +++++ examples/node-server/server.js | 72 ++++++++++++++++++++++++++++++ examples/node-server/tsconfig.json | 12 +++++ pnpm-workspace.yaml | 3 +- 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 examples/node-server/package.json create mode 100644 examples/node-server/server.js create mode 100644 examples/node-server/tsconfig.json diff --git a/examples/node-server/package.json b/examples/node-server/package.json new file mode 100644 index 00000000000..437460d6def --- /dev/null +++ b/examples/node-server/package.json @@ -0,0 +1,11 @@ +{ + "name": "multipart-parser-node-server-example", + "private": true, + "type": "module", + "dependencies": { + "@mjackson/multipart-parser": "workspace:*" + }, + "scripts": { + "start": "node server.js" + } +} diff --git a/examples/node-server/server.js b/examples/node-server/server.js new file mode 100644 index 00000000000..f62f75d6ea9 --- /dev/null +++ b/examples/node-server/server.js @@ -0,0 +1,72 @@ +import * as http from 'node:http'; + +import { MultipartParseError } from '@mjackson/multipart-parser'; +import { parseMultipartRequest } from '@mjackson/multipart-parser/node'; + +const server = http.createServer(async (req, res) => { + if (req.method === 'GET') { + res.writeHead(200, { + 'Content-Type': 'text/html', + }); + res.end(` + + + + multipart-parser Node Server Example + + +

multipart-parser Node Server Example

+ +

+

+

+ + + +`); + } else if (req.method === 'POST') { + try { + /** @type any[] */ + let parts = []; + + for await (let part of parseMultipartRequest(req)) { + if (part.isFile) { + let bytes = await part.bytes(); + parts.push({ + name: part.name, + filename: part.filename, + mediaType: part.mediaType, + size: bytes.byteLength, + }); + } else { + parts.push({ + name: part.name, + value: await part.text(), + }); + } + } + + res.writeHead(200, { + 'Content-Type': 'application/json', + }); + res.end(JSON.stringify({ parts }, null, 2)); + } catch (error) { + console.error(error); + + if (error instanceof MultipartParseError) { + res.writeHead(400); + res.end('Bad Request'); + } else { + res.writeHead(500); + res.end('Internal Server Error'); + } + } + } else { + res.writeHead(405); + res.end('Method Not Allowed'); + } +}); + +server.listen(3000, () => { + console.log('Server listening on http://localhost:3000'); +}); diff --git a/examples/node-server/tsconfig.json b/examples/node-server/tsconfig.json new file mode 100644 index 00000000000..2b13bc370b0 --- /dev/null +++ b/examples/node-server/tsconfig.json @@ -0,0 +1,12 @@ +{ + "include": ["server.js"], + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "types": ["node"], + "noEmit": true, + "strict": true + } +} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e3e11e26a95..cc1e5949236 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,2 +1,3 @@ packages: - - 'bench' \ No newline at end of file + - 'bench' + - 'examples/*' \ No newline at end of file From ab31636df822744c01377bd9c4852027c4de1bab Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 31 Jul 2024 01:00:15 -0700 Subject: [PATCH 118/730] Update README --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 29b09703c49..98b4ebdc6a6 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ async function handleMultipartRequest(request: Request): void { The main module (`import from "@mjackson/multipart-parser"`) assumes you're working with [the fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) (`Request`, `ReadableStream`, etc). Support for these interfaces was added to node.js by the [undici](https://github.com/nodejs/undici) project in [version 16.5.0](https://nodejs.org/en/blog/release/v16.5.0). -If however you're building a server for node.js that still relies on slightly older APIs like `http.IncomingMessage`, `stream.Readable`, and `buffer.Buffer` (ala Express or `http.createServer`), `multipart-parser` ships with an additional module that works directly with these APIs. +If however you're building a server for node.js that relies on node-specific APIs like `http.IncomingMessage`, `stream.Readable`, and `buffer.Buffer` (ala Express or `http.createServer`), `multipart-parser` ships with an additional module that works directly with these APIs. ```typescript import * as http from 'node:http'; @@ -75,6 +75,10 @@ const server = http.createServer(async (req, res) => { server.listen(8080); ``` +## Examples + +See [the node-server example](/examples/node-server) for a working demo of how you can handle file uploads in node.js. + ## Benchmark `multipart-parser` is designed to be as efficient as possible, only operating on streams of data and never buffering in common usage. This design yields exceptional performance when handling multipart payloads of any size. In most benchmarks, `multipart-parser` is as fast or faster than `busboy`. From 39d81f0b6020b0cae5283627bfe5e22790b4412c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 31 Jul 2024 01:03:05 -0700 Subject: [PATCH 119/730] Update README --- README.md | 7 +++++-- package.json | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 98b4ebdc6a6..95a175f3af6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # multipart-parser -`multipart-parser` is a fast, efficient parser for multipart streams. It can be used in any JavaScript environment (not just node) for a variety of use cases including: +`multipart-parser` is a fast, efficient parser for multipart streams. It can be used in any JavaScript environment (not just node.js) for a variety of use cases including: - Handling file uploads (`multipart/form-data` requests) - Parsing `multipart/mixed` messages (email attachments, API responses, etc.) @@ -25,7 +25,6 @@ async function handleMultipartRequest(request: Request): void { for await (let part of parseMultipartRequest(request)) { console.log(part.name); console.log(part.filename); - console.log(part.mediaType); if (/^text\//.test(part.mediaType)) { console.log(await part.text()); @@ -104,3 +103,7 @@ Date: 7/30/2024, 7:01:45 PM │ @fastify/busboy │ '0.03 ms ± 0.07' │ '2.13 ms ± 0.29' │ '0.40 ms ± 0.06' │ '26.67 ms ± 1.22' │ └──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ ``` + +## Credits + +Thanks to Jacob Ebey who gave me several code reviews on this project prior to publishing. diff --git a/package.json b/package.json index cf92e1d431f..c457b525a91 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.1.0", + "version": "0.0.0", "description": "A fast, efficient parser for multipart streams", "author": "Michael Jackson ", "license": "MIT", From d51bf15bfef624642404218bba337a533c7f6ae9 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 31 Jul 2024 01:05:17 -0700 Subject: [PATCH 120/730] 0.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c457b525a91..cf92e1d431f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.0.0", + "version": "0.1.0", "description": "A fast, efficient parser for multipart streams", "author": "Michael Jackson ", "license": "MIT", From e068ba8e90e3ba2d6d247f9a00931719d80223f6 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 31 Jul 2024 13:03:14 -0700 Subject: [PATCH 121/730] Fix `part.bytes()` and make it faster --- src/lib/multipart-parser.ts | 33 ++++++++++++------------- src/lib/utils.ts | 16 ------------- src/test/utils.ts | 48 ++++++++++++++++++++++++------------- 3 files changed, 46 insertions(+), 51 deletions(-) diff --git a/src/lib/multipart-parser.ts b/src/lib/multipart-parser.ts index 3634aedfdbf..e03124e53e3 100644 --- a/src/lib/multipart-parser.ts +++ b/src/lib/multipart-parser.ts @@ -1,6 +1,6 @@ import { SuperHeaders } from 'fetch-super-headers'; -import { concatChunks, readStream, stringToBinary } from './utils.js'; +import { concatChunks, readStream } from './utils.js'; /** * Extracts the boundary string from a `multipart/*` content type. @@ -393,7 +393,19 @@ export class MultipartPart { * The content of this part as a `Uint8Array`. */ async bytes(): Promise { - return stringToBinary(await this.text()); + if (this._bodyUsed) { + throw new Error('Body is already consumed or is being consumed'); + } + + this._bodyUsed = true; + + let chunks: Uint8Array[] = []; + + await readStream(this.body, (chunk) => { + chunks.push(chunk); + }); + + return concatChunks(chunks); } /** @@ -441,21 +453,6 @@ export class MultipartPart { * Note: Do not use this for binary data, use `await part.bytes()` or stream `part.body` directly instead. */ async text(): Promise { - if (this._bodyUsed) { - throw new Error('Body is already consumed or is being consumed'); - } - - this._bodyUsed = true; - - let decoder = new TextDecoder('utf-8'); - - let string = ''; - await readStream(this.body, (chunk) => { - string += decoder.decode(chunk, { stream: true }); - }); - - string += decoder.decode(); - - return string; + return new TextDecoder().decode(await this.bytes()); } } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index ec73721b558..3a33f69d419 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -29,19 +29,3 @@ export async function readStream( reader.releaseLock(); } } - -export function binaryToString(binary: Uint8Array): string { - let string = ''; - for (let i = 0; i < binary.length; ++i) { - string += String.fromCharCode(binary[i]); - } - return string; -} - -export function stringToBinary(string: string): Uint8Array { - let binary = new Uint8Array(string.length); - for (let i = 0; i < string.length; ++i) { - binary[i] = string.charCodeAt(i); - } - return binary; -} diff --git a/src/test/utils.ts b/src/test/utils.ts index 1ba32af7373..fbb3dd03423 100644 --- a/src/test/utils.ts +++ b/src/test/utils.ts @@ -1,11 +1,11 @@ import { ContentDisposition, ContentType, SuperHeaders } from 'fetch-super-headers'; -import { binaryToString } from '../lib/utils.js'; +import { concatChunks } from '../lib/utils.js'; export const CRLF = '\r\n'; export function createReadableStream( - content: string, + content: string | Uint8Array, chunkSize = 16 * 1024 ): ReadableStream { let encoder = new TextEncoder(); @@ -13,7 +13,11 @@ export function createReadableStream( return new ReadableStream({ start(controller) { for (let i = 0; i < content.length; i += chunkSize) { - controller.enqueue(encoder.encode(content.slice(i, i + chunkSize))); + controller.enqueue( + typeof content === 'string' + ? encoder.encode(content.slice(i, i + chunkSize)) + : content.subarray(i, i + chunkSize) + ); } controller.close(); }, @@ -25,11 +29,12 @@ export function createMockRequest({ body = '', }: { headers?: Headers | HeadersInit; - body?: string | ReadableStream; + body?: string | Uint8Array | ReadableStream; }): Request { return { headers: headers instanceof Headers ? headers : new Headers(headers), - body: typeof body === 'string' ? createReadableStream(body) : body, + body: + typeof body === 'string' || body instanceof Uint8Array ? createReadableStream(body) : body, } as unknown as Request; } @@ -45,20 +50,24 @@ export type PartValue = export function createMultipartBody( boundary: string, parts?: { [name: string]: PartValue } -): string { - let lines = []; +): Uint8Array { + let chunks: Uint8Array[] = []; + + function pushLine(value: string) { + chunks.push(new TextEncoder().encode(value + CRLF)); + } if (parts) { for (let [name, part] of Object.entries(parts)) { - lines.push(`--${boundary}`); + pushLine(`--${boundary}`); if (typeof part === 'string') { let contentDisposition = new ContentDisposition(); contentDisposition.type = 'form-data'; contentDisposition.name = name; - lines.push(`Content-Disposition: ${contentDisposition}`); - lines.push(''); - lines.push(part); + pushLine(`Content-Disposition: ${contentDisposition}`); + pushLine(''); + pushLine(part); } else { let contentDisposition = new ContentDisposition(); contentDisposition.type = 'form-data'; @@ -66,24 +75,29 @@ export function createMultipartBody( contentDisposition.filename = part.filename; contentDisposition.filenameSplat = part.filenameSplat; - lines.push(`Content-Disposition: ${contentDisposition}`); + pushLine(`Content-Disposition: ${contentDisposition}`); if (part.mediaType) { let contentType = new ContentType(); contentType.mediaType = part.mediaType; - lines.push(`Content-Type: ${contentType}`); + pushLine(`Content-Type: ${contentType}`); } - lines.push(''); - lines.push(typeof part.content === 'string' ? part.content : binaryToString(part.content)); + pushLine(''); + if (typeof part.content === 'string') { + pushLine(part.content); + } else { + chunks.push(part.content); + pushLine(''); + } } } } - lines.push(`--${boundary}--`); + pushLine(`--${boundary}--`); - return lines.join(CRLF); + return concatChunks(chunks); } export function createMultipartMockRequest( From e69f46745d4d93ef907f2f9dca58ddadc51d80a8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 31 Jul 2024 11:54:33 -0700 Subject: [PATCH 122/730] Stream file uploads to disk in node-server example --- examples/node-server/README.md | 3 ++ examples/node-server/package.json | 6 +++- examples/node-server/server.js | 47 +++++++++++++++++++++++++++++-- pnpm-lock.yaml | 18 ++++++++++++ 4 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 examples/node-server/README.md diff --git a/examples/node-server/README.md b/examples/node-server/README.md new file mode 100644 index 00000000000..b1c72fd89c7 --- /dev/null +++ b/examples/node-server/README.md @@ -0,0 +1,3 @@ +# multipart-parser Node Server Example + +This example is a simple node.js server that handles file uploads and streams them directly to a tmp file on disk. diff --git a/examples/node-server/package.json b/examples/node-server/package.json index 437460d6def..f2dcce4b746 100644 --- a/examples/node-server/package.json +++ b/examples/node-server/package.json @@ -3,9 +3,13 @@ "private": true, "type": "module", "dependencies": { - "@mjackson/multipart-parser": "workspace:*" + "@mjackson/multipart-parser": "workspace:*", + "tmp": "^0.2.3" }, "scripts": { "start": "node server.js" + }, + "devDependencies": { + "@types/tmp": "^0.2.6" } } diff --git a/examples/node-server/server.js b/examples/node-server/server.js index f62f75d6ea9..698b01ca4c1 100644 --- a/examples/node-server/server.js +++ b/examples/node-server/server.js @@ -1,4 +1,6 @@ +import * as fs from 'node:fs'; import * as http from 'node:http'; +import tmp from 'tmp'; import { MultipartParseError } from '@mjackson/multipart-parser'; import { parseMultipartRequest } from '@mjackson/multipart-parser/node'; @@ -26,17 +28,24 @@ const server = http.createServer(async (req, res) => { `); } else if (req.method === 'POST') { try { - /** @type any[] */ let parts = []; for await (let part of parseMultipartRequest(req)) { if (part.isFile) { - let bytes = await part.bytes(); + let tmpfile = tmp.fileSync(); + let byteLength = await writeFile(tmpfile.name, part.body); + + // Or, if you'd prefer to buffer you can do it like this: + // let bytes = await part.bytes(); + // fs.writeFileSync(tmpfile.name, bytes, 'binary'); + // let byteLength = bytes.byteLength; + parts.push({ name: part.name, filename: part.filename, mediaType: part.mediaType, - size: bytes.byteLength, + size: byteLength, + file: tmpfile.name, }); } else { parts.push({ @@ -70,3 +79,35 @@ const server = http.createServer(async (req, res) => { server.listen(3000, () => { console.log('Server listening on http://localhost:3000'); }); + +// Some lil' helpers + +/** @type (filename: string, stream: ReadableStream) => Promise */ +async function writeFile(filename, stream) { + let fileStream = fs.createWriteStream(filename); + let bytesWritten = 0; + + await readStream(stream, (chunk) => { + fileStream.write(chunk); + bytesWritten += chunk.byteLength; + }); + + fileStream.end(); + + return bytesWritten; +} + +/** @type (stream: ReadableStream, callback: (value: T) => void) => Promise */ +async function readStream(stream, callback) { + let reader = stream.getReader(); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + callback(value); + } + } finally { + reader.releaseLock(); + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1d725761de9..c4f3bd35641 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,6 +42,13 @@ importers: '@mjackson/multipart-parser': specifier: workspace:* version: link:../.. + tmp: + specifier: ^0.2.3 + version: 0.2.3 + devDependencies: + '@types/tmp': + specifier: ^0.2.6 + version: 0.2.6 packages: @@ -68,6 +75,9 @@ packages: '@types/node@20.14.10': resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==} + '@types/tmp@0.2.6': + resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -211,6 +221,10 @@ packages: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} + tmp@0.2.3: + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + engines: {node: '>=14.14'} + tsimp@2.0.11: resolution: {integrity: sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==} engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} @@ -272,6 +286,8 @@ snapshots: dependencies: undici-types: 5.26.5 + '@types/tmp@0.2.6': {} + ansi-regex@5.0.1: {} ansi-regex@6.0.1: {} @@ -399,6 +415,8 @@ snapshots: dependencies: ansi-regex: 6.0.1 + tmp@0.2.3: {} + tsimp@2.0.11(typescript@5.5.3): dependencies: '@isaacs/cached': 1.0.1 From 66a2570f3ac187eae1db67671647600a8c0f0437 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 31 Jul 2024 13:05:50 -0700 Subject: [PATCH 123/730] 0.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cf92e1d431f..3ee9de5dcbd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.1.0", + "version": "0.1.1", "description": "A fast, efficient parser for multipart streams", "author": "Michael Jackson ", "license": "MIT", From e26e2133b8ab12659ca26b688be1cb3e0d8631cd Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 31 Jul 2024 10:57:43 -0700 Subject: [PATCH 124/730] Add Cloudflare Workers example --- .gitignore | 1 + examples/cf-workers/README.md | 3 + examples/cf-workers/package.json | 18 + examples/cf-workers/src/index.ts | 77 ++ examples/cf-workers/tsconfig.json | 105 ++ examples/cf-workers/worker-configuration.d.ts | 6 + examples/cf-workers/wrangler.toml | 108 ++ pnpm-lock.yaml | 934 +++++++++++++++++- 8 files changed, 1229 insertions(+), 23 deletions(-) create mode 100644 examples/cf-workers/README.md create mode 100644 examples/cf-workers/package.json create mode 100644 examples/cf-workers/src/index.ts create mode 100644 examples/cf-workers/tsconfig.json create mode 100644 examples/cf-workers/worker-configuration.d.ts create mode 100644 examples/cf-workers/wrangler.toml diff --git a/.gitignore b/.gitignore index c9282d7e5e3..f45b2eb5ca9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .tsimp +.wrangler dist node_modules diff --git a/examples/cf-workers/README.md b/examples/cf-workers/README.md new file mode 100644 index 00000000000..0428b5d9dde --- /dev/null +++ b/examples/cf-workers/README.md @@ -0,0 +1,3 @@ +# multipart-parser CF Workers Example + +This is a demo of how you can upload a file directly to [a Cloudflare worker](https://developers.cloudflare.com/workers/) and store it in R2. diff --git a/examples/cf-workers/package.json b/examples/cf-workers/package.json new file mode 100644 index 00000000000..3385bfe02a2 --- /dev/null +++ b/examples/cf-workers/package.json @@ -0,0 +1,18 @@ +{ + "name": "multipart-parser-cf-workers-example", + "private": true, + "scripts": { + "deploy": "wrangler deploy", + "dev": "wrangler dev", + "start": "wrangler dev", + "cf-typegen": "wrangler types" + }, + "dependencies": { + "@mjackson/multipart-parser": "workspace:*" + }, + "devDependencies": { + "@cloudflare/workers-types": "^4.20240725.0", + "typescript": "^5.5.2", + "wrangler": "^3.60.3" + } +} diff --git a/examples/cf-workers/src/index.ts b/examples/cf-workers/src/index.ts new file mode 100644 index 00000000000..9c526e5ab82 --- /dev/null +++ b/examples/cf-workers/src/index.ts @@ -0,0 +1,77 @@ +import { parseMultipartRequest } from '@mjackson/multipart-parser'; + +export default { + async fetch(request, env): Promise { + if (request.method === 'GET') { + return new Response( + ` + + + + multipart-parser CF Workers Example + + +

multipart-parser CF Workers Example

+
+

+

+

+
+ + +`, + { + headers: { 'Content-Type': 'text/html' }, + } + ); + } + + if (request.method === 'POST') { + let bucket = env.MULTIPART_UPLOADS; + let parts = []; + + for await (let part of parseMultipartRequest(request)) { + if (part.isFile) { + let uniqueKey = `upload-${new Date().getTime()}-${Math.random() + .toString(36) + .slice(2, 8)}`; + + // Put the file in R2. + + // Ideally we could stream part.body directly, but Cloudflare's R2 + // API requires a FixedLengthStream and unfortunately we don't know + // the length of the stream at this point because browsers don't send + // Content-Length headers with file uploads. + // await bucket.put(uniqueKey, part.body); + + // So instead, we have to buffer the entire file in memory and then + // upload it to R2. + let bytes = await part.bytes(); + await bucket.put(uniqueKey, bytes, { + httpMetadata: { + contentType: part.headers.get('Content-Type')!, + }, + }); + + parts.push({ + name: part.name, + filename: part.filename, + mediaType: part.mediaType, + size: bytes.byteLength, + }); + } else { + parts.push({ + name: part.name, + value: await part.text(), + }); + } + } + + return new Response(JSON.stringify({ parts }, null, 2), { + headers: { 'Content-Type': 'application/json' }, + }); + } + + return new Response('Method Not Allowed', { status: 405 }); + }, +} satisfies ExportedHandler; diff --git a/examples/cf-workers/tsconfig.json b/examples/cf-workers/tsconfig.json new file mode 100644 index 00000000000..79207ab7ae9 --- /dev/null +++ b/examples/cf-workers/tsconfig.json @@ -0,0 +1,105 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Projects */ + // "incremental": true, /* Enable incremental compilation */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2021" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + "lib": ["es2021"] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, + "jsx": "react-jsx" /* Specify what JSX code is generated. */, + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ + // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + + /* Modules */ + "module": "es2022" /* Specify what module code is generated. */, + // "rootDir": "./", /* Specify the root folder within your source files. */ + "moduleResolution": "Bundler" /* Specify how TypeScript looks up a file from a given module specifier. */, + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ + "types": [ + "@cloudflare/workers-types/2023-07-01" + ] /* Specify type package names to be included without being referenced in a source file. */, + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + "resolveJsonModule": true /* Enable importing .json files */, + // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + "allowJs": true /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */, + "checkJs": false /* Enable error reporting in type-checked JavaScript files. */, + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + "noEmit": true /* Disable emitting files from a compilation. */, + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + "isolatedModules": true /* Ensure that each file can be safely transpiled without relying on other imports. */, + "allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */, + // "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + + /* Type Checking */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ + // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ + // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "exclude": ["test"], + "include": ["worker-configuration.d.ts", "src/**/*.ts"] +} diff --git a/examples/cf-workers/worker-configuration.d.ts b/examples/cf-workers/worker-configuration.d.ts new file mode 100644 index 00000000000..34721071f5c --- /dev/null +++ b/examples/cf-workers/worker-configuration.d.ts @@ -0,0 +1,6 @@ +// Generated by Wrangler on Wed Jul 31 2024 09:58:02 GMT-0700 (Pacific Daylight Time) +// by running `wrangler types` + +interface Env { + MULTIPART_UPLOADS: R2Bucket; +} diff --git a/examples/cf-workers/wrangler.toml b/examples/cf-workers/wrangler.toml new file mode 100644 index 00000000000..6427e1d1296 --- /dev/null +++ b/examples/cf-workers/wrangler.toml @@ -0,0 +1,108 @@ +#:schema node_modules/wrangler/config-schema.json +name = "cf-workers" +main = "src/index.ts" +compatibility_date = "2024-07-25" +# compatibility_flags = ["nodejs_compat"] + +# Automatically place your workloads in an optimal location to minimize latency. +# If you are running back-end logic in a Worker, running it closer to your back-end infrastructure +# rather than the end user may result in better performance. +# Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement +# [placement] +# mode = "smart" + +# Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) +# Docs: +# - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables +# Note: Use secrets to store sensitive data. +# - https://developers.cloudflare.com/workers/configuration/secrets/ +# [vars] +# MY_VARIABLE = "production_value" + +# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai +# [ai] +# binding = "AI" + +# Bind an Analytics Engine dataset. Use Analytics Engine to write analytics within your Pages Function. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets +# [[analytics_engine_datasets]] +# binding = "MY_DATASET" + +# Bind a headless browser instance running on Cloudflare's global network. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering +# [browser] +# binding = "MY_BROWSER" + +# Bind a D1 database. D1 is Cloudflare’s native serverless SQL database. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases +# [[d1_databases]] +# binding = "MY_DB" +# database_name = "my-database" +# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a dispatch namespace. Use Workers for Platforms to deploy serverless functions programmatically on behalf of your customers. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms +# [[dispatch_namespaces]] +# binding = "MY_DISPATCHER" +# namespace = "my-namespace" + +# Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model. +# Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects +# [[durable_objects.bindings]] +# name = "MY_DURABLE_OBJECT" +# class_name = "MyDurableObject" + +# Durable Object migrations. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations +# [[migrations]] +# tag = "v1" +# new_classes = ["MyDurableObject"] + +# Bind a Hyperdrive configuration. Use to accelerate access to your existing databases from Cloudflare Workers. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive +# [[hyperdrive]] +# binding = "MY_HYPERDRIVE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind a KV Namespace. Use KV as persistent storage for small key-value pairs. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces +# [[kv_namespaces]] +# binding = "MY_KV_NAMESPACE" +# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +# Bind an mTLS certificate. Use to present a client certificate when communicating with another service. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates +# [[mtls_certificates]] +# binding = "MY_CERTIFICATE" +# certificate_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + +# Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues +# [[queues.producers]] +# binding = "MY_QUEUE" +# queue = "my-queue" + +# Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues +# [[queues.consumers]] +# queue = "my-queue" + +# Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets +[[r2_buckets]] +binding = "MULTIPART_UPLOADS" +bucket_name = "multipart-uploads" + +# Bind another Worker service. Use this binding to call another Worker without network overhead. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings +# [[services]] +# binding = "MY_SERVICE" +# service = "my-service" + +# Bind a Vectorize index. Use to store and query vector embeddings for semantic search, classification and other vector search use-cases. +# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes +# [[vectorize]] +# binding = "MY_INDEX" +# index_name = "my-index" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c4f3bd35641..c714a7c0d6f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,13 +14,13 @@ importers: devDependencies: '@types/node': specifier: ^20.14.10 - version: 20.14.10 + version: 20.14.13 tsimp: specifier: ^2.0.11 - version: 2.0.11(typescript@5.5.3) + version: 2.0.11(typescript@5.5.4) typescript: specifier: ^5.5.3 - version: 5.5.3 + version: 5.5.4 bench: dependencies: @@ -37,6 +37,22 @@ importers: specifier: ^1.6.0 version: 1.6.0 + examples/cf-workers: + dependencies: + '@mjackson/multipart-parser': + specifier: workspace:* + version: link:../.. + devDependencies: + '@cloudflare/workers-types': + specifier: ^4.20240725.0 + version: 4.20240725.0 + typescript: + specifier: ^5.5.2 + version: 5.5.4 + wrangler: + specifier: ^3.60.3 + version: 3.67.1(@cloudflare/workers-types@4.20240725.0) + examples/node-server: dependencies: '@mjackson/multipart-parser': @@ -52,6 +68,193 @@ importers: packages: + '@cloudflare/kv-asset-handler@0.3.4': + resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} + engines: {node: '>=16.13'} + + '@cloudflare/workerd-darwin-64@1.20240718.0': + resolution: {integrity: sha512-BsPZcSCgoGnufog2GIgdPuiKicYTNyO/Dp++HbpLRH+yQdX3x4aWx83M+a0suTl1xv76dO4g9aw7SIB6OSgIyQ==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] + + '@cloudflare/workerd-darwin-arm64@1.20240718.0': + resolution: {integrity: sha512-nlr4gaOO5gcJerILJQph3+2rnas/nx/lYsuaot1ntHu4LAPBoQo1q/Pucj2cSIav4UiMzTbDmoDwPlls4Kteog==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] + + '@cloudflare/workerd-linux-64@1.20240718.0': + resolution: {integrity: sha512-LJ/k3y47pBcjax0ee4K+6ZRrSsqWlfU4lbU8Dn6u5tSC9yzwI4YFNXDrKWInB0vd7RT3w4Yqq1S6ZEbfRrqVUg==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] + + '@cloudflare/workerd-linux-arm64@1.20240718.0': + resolution: {integrity: sha512-zBEZvy88EcAMGRGfuVtS00Yl7lJdUM9sH7i651OoL+q0Plv9kphlCC0REQPwzxrEYT1qibSYtWcD9IxQGgx2/g==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] + + '@cloudflare/workerd-windows-64@1.20240718.0': + resolution: {integrity: sha512-YpCRvvT47XanFum7C3SedOZKK6BfVhqmwdAAVAQFyc4gsCdegZo0JkUkdloC/jwuWlbCACOG2HTADHOqyeolzQ==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] + + '@cloudflare/workers-types@4.20240725.0': + resolution: {integrity: sha512-L6T/Bg50zm9IIACQVQ0CdVcQL+2nLkRXdPz6BsXF3SlzgjyWR5ndVctAbfr/HLV7aKYxWnnEZsIORsTWb+FssA==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@esbuild-plugins/node-globals-polyfill@0.2.3': + resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} + peerDependencies: + esbuild: '*' + + '@esbuild-plugins/node-modules-polyfill@0.2.2': + resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} + peerDependencies: + esbuild: '*' + + '@esbuild/android-arm64@0.17.19': + resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.17.19': + resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.17.19': + resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.17.19': + resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.17.19': + resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.17.19': + resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.17.19': + resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.17.19': + resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.17.19': + resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.17.19': + resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.17.19': + resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.17.19': + resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.17.19': + resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.17.19': + resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.17.19': + resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.17.19': + resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.17.19': + resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.17.19': + resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.17.19': + resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.17.19': + resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.17.19': + resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.17.19': + resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + '@fastify/busboy@3.0.0': resolution: {integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==} @@ -65,6 +268,16 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -72,12 +285,24 @@ packages: '@types/busboy@1.5.4': resolution: {integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==} - '@types/node@20.14.10': - resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==} + '@types/node-forge@1.3.11': + resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} + + '@types/node@20.14.13': + resolution: {integrity: sha512-+bHoGiZb8UiQ0+WEtmph2IWQCjIqg8MDZMAV+ppRRhUZnquF5mQkP/9vpSwJClEiSM/C7fZZExPzfU0vJTyp8w==} '@types/tmp@0.2.6': resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} + acorn-walk@8.3.3: + resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} + engines: {node: '>=0.4.0'} + + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -94,16 +319,41 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + as-table@1.0.55: + resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + blake3-wasm@2.1.5: + resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} + capnp-ts@0.7.0: + resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -111,10 +361,36 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + + cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} + data-uri-to-buffer@2.0.2: + resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} + + date-fns@3.6.0: + resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + + debug@4.3.6: + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -124,31 +400,105 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + esbuild@0.17.19: + resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} + engines: {node: '>=12'} + hasBin: true + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + estree-walker@0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + + exit-hook@2.2.1: + resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} + engines: {node: '>=6'} + fetch-super-headers@0.4.1: resolution: {integrity: sha512-jXB/p3m6iMeDFhHpJ56BgqrvoDIiyueNPF39twy2N63DMcme0imKhGoEZH8AAbnplnggU9OdUs9eFFPZxPULFA==} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + foreground-child@3.2.1: resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} engines: {node: '>=14'} + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-source@2.0.12: + resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-core-module@2.15.0: + resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - jackspeak@3.4.2: - resolution: {integrity: sha512-qH3nOSj8q/8+Eg8LUPOq3C+6HWkpUioIjDsq1+D4zY91oZvpPttw8GwtF1nReRYKXl+1AORyFqtm2f5Q1SB6/Q==} - engines: {node: 14 >=14.21 || 16 >=16.20 || >=18} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + + miniflare@3.20240718.1: + resolution: {integrity: sha512-mn3MjGnpgYvarCRTfz4TQyVyY8yW0zz7f8LOAPVai78IGC/lcVcyskZcuIr7Zovb2i+IERmmsJAiEPeZHIIKbA==} + engines: {node: '>=16.13'} + hasBin: true + minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} @@ -162,6 +512,29 @@ packages: engines: {node: '>=10'} hasBin: true + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + mustache@4.2.0: + resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} + hasBin: true + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + node-fetch-native@1.6.4: + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + package-json-from-dist@1.0.0: resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} @@ -169,19 +542,60 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-to-regexp@6.2.2: + resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} - rimraf@5.0.9: - resolution: {integrity: sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==} - engines: {node: 14 >=14.20 || 16 >=16.20 || >=18} + printable-characters@1.0.42: + resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + resolve.exports@2.0.2: + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + + rollup-plugin-inject@3.0.2: + resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. + + rollup-plugin-node-polyfills@0.2.1: + resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} + + rollup-pluginutils@2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + + selfsigned@2.4.1: + resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} + engines: {node: '>=10'} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -201,6 +615,21 @@ packages: socket-post-message@1.0.3: resolution: {integrity: sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==} + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + + stacktracey@2.1.8: + resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} + + stoppable@1.1.0: + resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} + engines: {node: '>=4', npm: '>=6'} + streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} @@ -221,10 +650,18 @@ packages: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + tmp@0.2.3: resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} engines: {node: '>=14.14'} + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + tsimp@2.0.11: resolution: {integrity: sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==} engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} @@ -232,14 +669,27 @@ packages: peerDependencies: typescript: ^5.1.0 - typescript@5.5.3: - resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} engines: {node: '>=14.17'} hasBin: true + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici@5.28.4: + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} + engines: {node: '>=14.0'} + + unenv-nightly@1.10.0-1717606461.a117952: + resolution: {integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==} + walk-up-path@3.0.1: resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} @@ -248,6 +698,21 @@ packages: engines: {node: '>= 8'} hasBin: true + workerd@1.20240718.0: + resolution: {integrity: sha512-w7lOLRy0XecQTg/ujTLWBiJJuoQvzB3CdQ6/8Wgex3QxFhV9Pbnh3UbwIuUfMw3OCCPQc4o7y+1P+mISAgp6yg==} + engines: {node: '>=16'} + hasBin: true + + wrangler@3.67.1: + resolution: {integrity: sha512-lLVJxq/OZMfntvZ79WQJNC1OKfxOCs6PLfogqDBuPFEQ3L/Mwqvd9IZ0bB8ahrwUN/K3lSdDPXynk9HfcGZxVw==} + engines: {node: '>=16.17.0'} + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^4.20240718.0 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -256,8 +721,132 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xxhash-wasm@1.0.2: + resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} + + youch@3.3.3: + resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} + + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + snapshots: + '@cloudflare/kv-asset-handler@0.3.4': + dependencies: + mime: 3.0.0 + + '@cloudflare/workerd-darwin-64@1.20240718.0': + optional: true + + '@cloudflare/workerd-darwin-arm64@1.20240718.0': + optional: true + + '@cloudflare/workerd-linux-64@1.20240718.0': + optional: true + + '@cloudflare/workerd-linux-arm64@1.20240718.0': + optional: true + + '@cloudflare/workerd-windows-64@1.20240718.0': + optional: true + + '@cloudflare/workers-types@4.20240725.0': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': + dependencies: + esbuild: 0.17.19 + + '@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19)': + dependencies: + esbuild: 0.17.19 + escape-string-regexp: 4.0.0 + rollup-plugin-node-polyfills: 0.2.1 + + '@esbuild/android-arm64@0.17.19': + optional: true + + '@esbuild/android-arm@0.17.19': + optional: true + + '@esbuild/android-x64@0.17.19': + optional: true + + '@esbuild/darwin-arm64@0.17.19': + optional: true + + '@esbuild/darwin-x64@0.17.19': + optional: true + + '@esbuild/freebsd-arm64@0.17.19': + optional: true + + '@esbuild/freebsd-x64@0.17.19': + optional: true + + '@esbuild/linux-arm64@0.17.19': + optional: true + + '@esbuild/linux-arm@0.17.19': + optional: true + + '@esbuild/linux-ia32@0.17.19': + optional: true + + '@esbuild/linux-loong64@0.17.19': + optional: true + + '@esbuild/linux-mips64el@0.17.19': + optional: true + + '@esbuild/linux-ppc64@0.17.19': + optional: true + + '@esbuild/linux-riscv64@0.17.19': + optional: true + + '@esbuild/linux-s390x@0.17.19': + optional: true + + '@esbuild/linux-x64@0.17.19': + optional: true + + '@esbuild/netbsd-x64@0.17.19': + optional: true + + '@esbuild/openbsd-x64@0.17.19': + optional: true + + '@esbuild/sunos-x64@0.17.19': + optional: true + + '@esbuild/win32-arm64@0.17.19': + optional: true + + '@esbuild/win32-ia32@0.17.19': + optional: true + + '@esbuild/win32-x64@0.17.19': + optional: true + + '@fastify/busboy@2.1.1': {} + '@fastify/busboy@3.0.0': {} '@isaacs/cached@1.0.1': @@ -275,19 +864,38 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@pkgjs/parseargs@0.11.0': optional: true '@types/busboy@1.5.4': dependencies: - '@types/node': 20.14.10 + '@types/node': 20.14.13 - '@types/node@20.14.10': + '@types/node-forge@1.3.11': + dependencies: + '@types/node': 20.14.13 + + '@types/node@20.14.13': dependencies: undici-types: 5.26.5 '@types/tmp@0.2.6': {} + acorn-walk@8.3.3: + dependencies: + acorn: 8.12.1 + + acorn@8.12.1: {} + ansi-regex@5.0.1: {} ansi-regex@6.0.1: {} @@ -298,55 +906,176 @@ snapshots: ansi-styles@6.2.1: {} + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + as-table@1.0.55: + dependencies: + printable-characters: 1.0.42 + balanced-match@1.0.2: {} + binary-extensions@2.3.0: {} + + blake3-wasm@2.1.5: {} + brace-expansion@2.0.1: dependencies: balanced-match: 1.0.2 + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + busboy@1.6.0: dependencies: streamsearch: 1.1.0 + capnp-ts@0.7.0: + dependencies: + debug: 4.3.6 + tslib: 2.6.3 + transitivePeerDependencies: + - supports-color + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + color-convert@2.0.1: dependencies: color-name: 1.1.4 color-name@1.1.4: {} + consola@3.2.3: {} + + cookie@0.5.0: {} + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 + data-uri-to-buffer@2.0.2: {} + + date-fns@3.6.0: {} + + debug@4.3.6: + dependencies: + ms: 2.1.2 + + defu@6.1.4: {} + eastasianwidth@0.2.0: {} emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} + esbuild@0.17.19: + optionalDependencies: + '@esbuild/android-arm': 0.17.19 + '@esbuild/android-arm64': 0.17.19 + '@esbuild/android-x64': 0.17.19 + '@esbuild/darwin-arm64': 0.17.19 + '@esbuild/darwin-x64': 0.17.19 + '@esbuild/freebsd-arm64': 0.17.19 + '@esbuild/freebsd-x64': 0.17.19 + '@esbuild/linux-arm': 0.17.19 + '@esbuild/linux-arm64': 0.17.19 + '@esbuild/linux-ia32': 0.17.19 + '@esbuild/linux-loong64': 0.17.19 + '@esbuild/linux-mips64el': 0.17.19 + '@esbuild/linux-ppc64': 0.17.19 + '@esbuild/linux-riscv64': 0.17.19 + '@esbuild/linux-s390x': 0.17.19 + '@esbuild/linux-x64': 0.17.19 + '@esbuild/netbsd-x64': 0.17.19 + '@esbuild/openbsd-x64': 0.17.19 + '@esbuild/sunos-x64': 0.17.19 + '@esbuild/win32-arm64': 0.17.19 + '@esbuild/win32-ia32': 0.17.19 + '@esbuild/win32-x64': 0.17.19 + + escape-string-regexp@4.0.0: {} + + estree-walker@0.6.1: {} + + exit-hook@2.2.1: {} + fetch-super-headers@0.4.1: {} + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + foreground-child@3.2.1: dependencies: cross-spawn: 7.0.3 signal-exit: 4.1.0 + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-source@2.0.12: + dependencies: + data-uri-to-buffer: 2.0.2 + source-map: 0.6.1 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regexp@0.4.1: {} + glob@10.4.5: dependencies: foreground-child: 3.2.1 - jackspeak: 3.4.2 + jackspeak: 3.4.3 minimatch: 9.0.5 minipass: 7.1.2 package-json-from-dist: 1.0.0 path-scurry: 1.11.1 + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.15.0: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + isexe@2.0.0: {} - jackspeak@3.4.2: + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: @@ -354,6 +1083,31 @@ snapshots: lru-cache@10.4.3: {} + magic-string@0.25.9: + dependencies: + sourcemap-codec: 1.4.8 + + mime@3.0.0: {} + + miniflare@3.20240718.1: + dependencies: + '@cspotcode/source-map-support': 0.8.1 + acorn: 8.12.1 + acorn-walk: 8.3.3 + capnp-ts: 0.7.0 + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + stoppable: 1.1.0 + undici: 5.28.4 + workerd: 1.20240718.0 + ws: 8.18.0 + youch: 3.3.3 + zod: 3.23.8 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 @@ -362,21 +1116,74 @@ snapshots: mkdirp@3.0.1: {} + ms@2.1.2: {} + + mustache@4.2.0: {} + + nanoid@3.3.7: {} + + node-fetch-native@1.6.4: {} + + node-forge@1.3.1: {} + + normalize-path@3.0.0: {} + package-json-from-dist@1.0.0: {} path-key@3.1.1: {} + path-parse@1.0.7: {} + path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 minipass: 7.1.2 + path-to-regexp@6.2.2: {} + + pathe@1.1.2: {} + + picomatch@2.3.1: {} + pirates@4.0.6: {} - rimraf@5.0.9: + printable-characters@1.0.42: {} + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + resolve.exports@2.0.2: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.15.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + rimraf@5.0.10: dependencies: glob: 10.4.5 + rollup-plugin-inject@3.0.2: + dependencies: + estree-walker: 0.6.1 + magic-string: 0.25.9 + rollup-pluginutils: 2.8.2 + + rollup-plugin-node-polyfills@0.2.1: + dependencies: + rollup-plugin-inject: 3.0.2 + + rollup-pluginutils@2.8.2: + dependencies: + estree-walker: 0.6.1 + + selfsigned@2.4.1: + dependencies: + '@types/node-forge': 1.3.11 + node-forge: 1.3.1 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -387,12 +1194,23 @@ snapshots: sock-daemon@1.4.2: dependencies: - rimraf: 5.0.9 + rimraf: 5.0.10 signal-exit: 4.1.0 socket-post-message: 1.0.3 socket-post-message@1.0.3: {} + source-map@0.6.1: {} + + sourcemap-codec@1.4.8: {} + + stacktracey@2.1.8: + dependencies: + as-table: 1.0.55 + get-source: 2.0.12 + + stoppable@1.1.0: {} + streamsearch@1.1.0: {} string-width@4.2.3: @@ -415,31 +1233,89 @@ snapshots: dependencies: ansi-regex: 6.0.1 + supports-preserve-symlinks-flag@1.0.0: {} + tmp@0.2.3: {} - tsimp@2.0.11(typescript@5.5.3): + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tsimp@2.0.11(typescript@5.5.4): dependencies: '@isaacs/cached': 1.0.1 '@isaacs/catcher': 1.0.4 foreground-child: 3.2.1 mkdirp: 3.0.1 pirates: 4.0.6 - rimraf: 5.0.9 + rimraf: 5.0.10 signal-exit: 4.1.0 sock-daemon: 1.4.2 - typescript: 5.5.3 + typescript: 5.5.4 walk-up-path: 3.0.1 - typescript@5.5.3: {} + tslib@2.6.3: {} + + typescript@5.5.4: {} + + ufo@1.5.4: {} undici-types@5.26.5: {} + undici@5.28.4: + dependencies: + '@fastify/busboy': 2.1.1 + + unenv-nightly@1.10.0-1717606461.a117952: + dependencies: + consola: 3.2.3 + defu: 6.1.4 + mime: 3.0.0 + node-fetch-native: 1.6.4 + pathe: 1.1.2 + ufo: 1.5.4 + walk-up-path@3.0.1: {} which@2.0.2: dependencies: isexe: 2.0.0 + workerd@1.20240718.0: + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20240718.0 + '@cloudflare/workerd-darwin-arm64': 1.20240718.0 + '@cloudflare/workerd-linux-64': 1.20240718.0 + '@cloudflare/workerd-linux-arm64': 1.20240718.0 + '@cloudflare/workerd-windows-64': 1.20240718.0 + + wrangler@3.67.1(@cloudflare/workers-types@4.20240725.0): + dependencies: + '@cloudflare/kv-asset-handler': 0.3.4 + '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) + '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) + blake3-wasm: 2.1.5 + chokidar: 3.6.0 + date-fns: 3.6.0 + esbuild: 0.17.19 + miniflare: 3.20240718.1 + nanoid: 3.3.7 + path-to-regexp: 6.2.2 + resolve: 1.22.8 + resolve.exports: 2.0.2 + selfsigned: 2.4.1 + source-map: 0.6.1 + unenv: unenv-nightly@1.10.0-1717606461.a117952 + workerd: 1.20240718.0 + xxhash-wasm: 1.0.2 + optionalDependencies: + '@cloudflare/workers-types': 4.20240725.0 + fsevents: 2.3.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -451,3 +1327,15 @@ snapshots: ansi-styles: 6.2.1 string-width: 5.1.2 strip-ansi: 7.1.0 + + ws@8.18.0: {} + + xxhash-wasm@1.0.2: {} + + youch@3.3.3: + dependencies: + cookie: 0.5.0 + mustache: 4.2.0 + stacktracey: 2.1.8 + + zod@3.23.8: {} From e40c299019ac30609796c4d942b817ce4296b45a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 31 Jul 2024 13:33:18 -0700 Subject: [PATCH 125/730] Use for...of in a few more places --- src/lib/multipart-parser.ts | 4 +--- src/lib/utils.ts | 12 ++++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/lib/multipart-parser.ts b/src/lib/multipart-parser.ts index e03124e53e3..c48fbacb2eb 100644 --- a/src/lib/multipart-parser.ts +++ b/src/lib/multipart-parser.ts @@ -298,9 +298,7 @@ export class MultipartParser { } private writeBody(chunks: Uint8Array[]): void { - for (let i = 0; i < chunks.length; ++i) { - let chunk = chunks[i]; - + for (let chunk of chunks) { if (this.bodyLength + chunk.length > this.maxFileSize) { throw new MultipartParseError( `File size exceeds maximum allowed size of ${this.maxFileSize} bytes` diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 3a33f69d419..f853c8d6c7b 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,13 +1,17 @@ export function concatChunks(chunks: Uint8Array[]): Uint8Array { if (chunks.length === 1) return chunks[0]; - let length = chunks.reduce((sum, chunk) => sum + chunk.length, 0); + let length = 0; + for (let chunk of chunks) { + length += chunk.length; + } + let result = new Uint8Array(length); let offset = 0; - for (let i = 0; i < chunks.length; ++i) { - result.set(chunks[i], offset); - offset += chunks[i].length; + for (let chunk of chunks) { + result.set(chunk, offset); + offset += chunk.length; } return result; From 302e3a36c5ba1a85f47e71193a25d9bdd1c25a05 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 31 Jul 2024 13:39:33 -0700 Subject: [PATCH 126/730] Update benchmarks --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 95a175f3af6..e0580b482b2 100644 --- a/README.md +++ b/README.md @@ -92,15 +92,15 @@ The results of running the benchmarks on my laptop: ``` Platform: Darwin (23.5.0) -CPU: Apple M1 Pro -Node.js v20.15.0 -Date: 7/30/2024, 7:01:45 PM +CPU: Apple M2 Pro +Node.js v20.15.1 +Date: 7/31/2024, 1:38:33 PM ┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ multipart-parser │ '0.02 ms ± 0.10' │ '1.49 ms ± 0.06' │ '0.38 ms ± 0.17' │ '16.17 ms ± 1.66' │ -│ busboy │ '0.03 ms ± 0.09' │ '4.34 ms ± 0.21' │ '0.23 ms ± 0.03' │ '48.82 ms ± 1.30' │ -│ @fastify/busboy │ '0.03 ms ± 0.07' │ '2.13 ms ± 0.29' │ '0.40 ms ± 0.06' │ '26.67 ms ± 1.22' │ +│ multipart-parser │ '0.02 ms ± 0.11' │ '1.33 ms ± 0.08' │ '0.35 ms ± 0.13' │ '15.18 ms ± 1.83' │ +│ busboy │ '0.03 ms ± 0.09' │ '2.75 ms ± 0.32' │ '0.22 ms ± 0.03' │ '31.22 ms ± 1.37' │ +│ @fastify/busboy │ '0.04 ms ± 0.08' │ '2.01 ms ± 0.28' │ '0.39 ms ± 0.04' │ '26.68 ms ± 1.32' │ └──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ ``` From 955cf603c419452de44c232f822778ced5d39fd5 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 31 Jul 2024 16:20:04 -0700 Subject: [PATCH 127/730] Link examples in README --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e0580b482b2..b5e154605f5 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,10 @@ server.listen(8080); ## Examples -See [the node-server example](/examples/node-server) for a working demo of how you can handle file uploads in node.js. +The [`examples` directory](/examples) contains a few working examples of how you can use this library: + +- [`cf-workers`](/examples/cf-workers) shows how you can handle multipart uploads in a Cloudflare worker and store files in R2 +- [`node-server`](/examples/node-server) demonstrates handling multipart uploads and streaming files to disk ## Benchmark From 9d8cdf54067908b9b3085e6218feb7d7e4a4845f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 31 Jul 2024 16:31:32 -0700 Subject: [PATCH 128/730] Rename some files --- package.json | 4 ++-- .../{multipart-parser-node.spec.ts => multipart.node.spec.ts} | 4 ++-- src/lib/{multipart-parser-node.ts => multipart.node.ts} | 2 +- src/lib/{multipart-parser.spec.ts => multipart.spec.ts} | 2 +- src/lib/{multipart-parser.ts => multipart.ts} | 0 src/{node.ts => multipart-parser.node.ts} | 2 +- src/{index.ts => multipart-parser.ts} | 2 +- src/test/fixtures.ts | 2 +- src/test/{utils-node.ts => utils.node.ts} | 0 9 files changed, 9 insertions(+), 9 deletions(-) rename src/lib/{multipart-parser-node.spec.ts => multipart.node.spec.ts} (94%) rename src/lib/{multipart-parser-node.ts => multipart.node.ts} (98%) rename src/lib/{multipart-parser.spec.ts => multipart.spec.ts} (99%) rename src/lib/{multipart-parser.ts => multipart.ts} (100%) rename src/{node.ts => multipart-parser.node.ts} (66%) rename src/{index.ts => multipart-parser.ts} (84%) rename src/test/{utils-node.ts => utils.node.ts} (100%) diff --git a/package.json b/package.json index 3ee9de5dcbd..fc4b40a2514 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,8 @@ ], "type": "module", "exports": { - ".": "./dist/index.js", - "./node": "./dist/node.js", + ".": "./dist/multipart-parser.js", + "./node": "./dist/multipart-parser.node.js", "./package.json": "./package.json" }, "dependencies": { diff --git a/src/lib/multipart-parser-node.spec.ts b/src/lib/multipart.node.spec.ts similarity index 94% rename from src/lib/multipart-parser-node.spec.ts rename to src/lib/multipart.node.spec.ts index 08dbb4c3d39..46e489facd3 100644 --- a/src/lib/multipart-parser-node.spec.ts +++ b/src/lib/multipart.node.spec.ts @@ -2,8 +2,8 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; import { readFixture } from '../test/fixtures.js'; -import { createMultipartMockRequest } from '../test/utils-node.js'; -import { parseMultipartRequest } from './multipart-parser-node.js'; +import { createMultipartMockRequest } from '../test/utils.node.js'; +import { parseMultipartRequest } from './multipart.node.js'; const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); diff --git a/src/lib/multipart-parser-node.ts b/src/lib/multipart.node.ts similarity index 98% rename from src/lib/multipart-parser-node.ts rename to src/lib/multipart.node.ts index d9f15d22fde..fbd009b392b 100644 --- a/src/lib/multipart-parser-node.ts +++ b/src/lib/multipart.node.ts @@ -7,7 +7,7 @@ import { MultipartParserOptions, MultipartParser, MultipartPart, -} from './multipart-parser.js'; +} from './multipart.js'; /** * Returns true if the given request is a multipart request. diff --git a/src/lib/multipart-parser.spec.ts b/src/lib/multipart.spec.ts similarity index 99% rename from src/lib/multipart-parser.spec.ts rename to src/lib/multipart.spec.ts index 958b9c51376..40d4e2d8943 100644 --- a/src/lib/multipart-parser.spec.ts +++ b/src/lib/multipart.spec.ts @@ -8,7 +8,7 @@ import { parseMultipartRequest, MultipartParseError, getMultipartBoundary, -} from './multipart-parser.js'; +} from './multipart.js'; const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); diff --git a/src/lib/multipart-parser.ts b/src/lib/multipart.ts similarity index 100% rename from src/lib/multipart-parser.ts rename to src/lib/multipart.ts diff --git a/src/node.ts b/src/multipart-parser.node.ts similarity index 66% rename from src/node.ts rename to src/multipart-parser.node.ts index b567a7d666a..8d544f68a90 100644 --- a/src/node.ts +++ b/src/multipart-parser.node.ts @@ -2,4 +2,4 @@ export { isMultipartRequest, parseMultipartRequest, parseMultipartStream, -} from './lib/multipart-parser-node.js'; +} from './lib/multipart.node.js'; diff --git a/src/index.ts b/src/multipart-parser.ts similarity index 84% rename from src/index.ts rename to src/multipart-parser.ts index 4c4a39c2b6b..5d6eda24767 100644 --- a/src/index.ts +++ b/src/multipart-parser.ts @@ -7,4 +7,4 @@ export { MultipartParserOptions, MultipartParser, MultipartPart, -} from './lib/multipart-parser.js'; +} from './lib/multipart.js'; diff --git a/src/test/fixtures.ts b/src/test/fixtures.ts index d9b41521028..34de0e0c57a 100644 --- a/src/test/fixtures.ts +++ b/src/test/fixtures.ts @@ -1,5 +1,5 @@ -import * as path from 'node:path'; import * as fs from 'node:fs'; +import * as path from 'node:path'; const __dirname = path.dirname(new URL(import.meta.url).pathname); diff --git a/src/test/utils-node.ts b/src/test/utils.node.ts similarity index 100% rename from src/test/utils-node.ts rename to src/test/utils.node.ts From f1da049f60fe1bd6729d2d0f87035abf381155cb Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 31 Jul 2024 16:48:27 -0700 Subject: [PATCH 129/730] Add explicit return type --- src/lib/multipart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index c48fbacb2eb..bf79e2204cd 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -148,7 +148,7 @@ export class MultipartParser { this.maxFileSize = maxFileSize; } - get done() { + get done(): boolean { return this.state === MultipartParserState.Done; } From 15698f0133014280998ad26d8f6b1e38c57fd3af Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 1 Aug 2024 08:18:31 -0700 Subject: [PATCH 130/730] Use private fields --- src/lib/multipart.ts | 159 ++++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 79 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index bf79e2204cd..cec51275ede 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -120,19 +120,19 @@ enum MultipartParserState { * A parser for `multipart/form-data` streams. */ export class MultipartParser { - private boundaryArray: Uint8Array; - private boundaryLength: number; - private boundarySkipTable: Uint8Array; - private maxHeaderSize: number; - private maxFileSize: number; + #boundaryArray: Uint8Array; + #boundaryLength: number; + #boundarySkipTable: Uint8Array; + #maxHeaderSize: number; + #maxFileSize: number; - private state = MultipartParserState.Start; - private buffer: Uint8Array = EMPTY_BUFFER; - private chunk: Uint8Array = EMPTY_BUFFER; - private length = 0; + #state = MultipartParserState.Start; + #buffer: Uint8Array = EMPTY_BUFFER; + #chunk: Uint8Array = EMPTY_BUFFER; + #length = 0; - private bodyController: ReadableStreamDefaultController | null = null; - private bodyLength = 0; + #bodyController: ReadableStreamDefaultController | null = null; + #bodyLength = 0; constructor( public boundary: string, @@ -141,15 +141,15 @@ export class MultipartParser { maxFileSize = 10 * 1024 * 1024, // 10 MB }: MultipartParserOptions = {} ) { - this.boundaryArray = textEncoder.encode(`--${boundary}`); - this.boundaryLength = this.boundaryArray.length; - this.boundarySkipTable = computeSkipTable(this.boundaryArray); - this.maxHeaderSize = maxHeaderSize; - this.maxFileSize = maxFileSize; + this.#boundaryArray = textEncoder.encode(`--${boundary}`); + this.#boundaryLength = this.#boundaryArray.length; + this.#boundarySkipTable = computeSkipTable(this.#boundaryArray); + this.#maxHeaderSize = maxHeaderSize; + this.#maxFileSize = maxFileSize; } get done(): boolean { - return this.state === MultipartParserState.Done; + return this.#state === MultipartParserState.Done; } push(chunk: Uint8Array): MultipartPart[] { @@ -157,30 +157,30 @@ export class MultipartParser { throw new MultipartParseError('Cannot push, parser is done'); } - this.chunk = chunk; - this.length = this.buffer.length + this.chunk.length; + this.#chunk = chunk; + this.#length = this.#buffer.length + this.#chunk.length; - if (this.state === MultipartParserState.Start) { - if (this.length < this.boundaryLength) { + if (this.#state === MultipartParserState.Start) { + if (this.#length < this.#boundaryLength) { this.save(); return []; } - let index = find(this.buffer, this.chunk, this.boundaryArray, this.boundarySkipTable); + let index = find(this.#buffer, this.#chunk, this.#boundaryArray, this.#boundarySkipTable); if (index !== 0) { throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); } - this.skip(this.boundaryLength); + this.skip(this.#boundaryLength); - this.state = MultipartParserState.AfterBoundary; + this.#state = MultipartParserState.AfterBoundary; } let parts: MultipartPart[] = []; while (true) { - if (this.state === MultipartParserState.AfterBoundary) { - if (this.length < 2) { + if (this.#state === MultipartParserState.AfterBoundary) { + if (this.#length < 2) { this.save(); break; } @@ -193,27 +193,27 @@ export class MultipartParser { (twoBytes[0][0] === HYPHEN && twoBytes[1][0] === HYPHEN) ) { // Discard any remaining data in the current buffer/chunk so we don't leak memory. - this.buffer = EMPTY_BUFFER; - this.chunk = EMPTY_BUFFER; + this.#buffer = EMPTY_BUFFER; + this.#chunk = EMPTY_BUFFER; - this.state = MultipartParserState.Done; + this.#state = MultipartParserState.Done; break; } - this.state = MultipartParserState.Header; + this.#state = MultipartParserState.Header; } - if (this.state === MultipartParserState.Header) { - if (this.length < 4) { + if (this.#state === MultipartParserState.Header) { + if (this.#length < 4) { this.save(); break; } - let index = find(this.buffer, this.chunk, DOUBLE_NEWLINE, DOUBLE_NEWLINE_SKIP_TABLE); + let index = find(this.#buffer, this.#chunk, DOUBLE_NEWLINE, DOUBLE_NEWLINE_SKIP_TABLE); if (index === -1) break; - if (index > this.maxHeaderSize) { + if (index > this.#maxHeaderSize) { throw new MultipartParseError( - `Header size exceeds maximum allowed size of ${this.maxHeaderSize} bytes` + `Header size exceeds maximum allowed size of ${this.#maxHeaderSize} bytes` ); } @@ -222,27 +222,27 @@ export class MultipartParser { let body = new ReadableStream({ start: (controller) => { - this.bodyController = controller; + this.#bodyController = controller; }, }); parts.push(new MultipartPart(header, body)); - this.state = MultipartParserState.Body; + this.#state = MultipartParserState.Body; } - if (this.state === MultipartParserState.Body) { - if (this.length < this.boundaryLength) { + if (this.#state === MultipartParserState.Body) { + if (this.#length < this.#boundaryLength) { this.save(); break; } - let index = find(this.buffer, this.chunk, this.boundaryArray, this.boundarySkipTable); + let index = find(this.#buffer, this.#chunk, this.#boundaryArray, this.#boundarySkipTable); if (index === -1) { // Write as much of the buffer as we can to the current body stream while still // keeping enough to check if the last few bytes are part of the boundary. - this.writeBody(this.read(this.length - this.boundaryLength + 1)); + this.writeBody(this.read(this.#length - this.#boundaryLength + 1)); this.save(); break; } @@ -250,9 +250,9 @@ export class MultipartParser { this.writeBody(this.read(index - 2)); // -2 to avoid \r\n before boundary this.closeBody(); - this.skip(2 + this.boundaryLength); // Skip \r\n + boundary + this.skip(2 + this.#boundaryLength); // Skip \r\n + boundary - this.state = MultipartParserState.AfterBoundary; + this.#state = MultipartParserState.AfterBoundary; } } @@ -260,60 +260,61 @@ export class MultipartParser { } private read(size: number): Uint8Array[] { - this.length -= size; - - if (size > this.buffer.length) { - if (this.buffer.length > 0) { - let head = this.buffer; - this.buffer = EMPTY_BUFFER; - let tail = this.chunk.subarray(0, size - head.length); - this.chunk = this.chunk.subarray(size - head.length); + this.#length -= size; + + if (size > this.#buffer.length) { + if (this.#buffer.length > 0) { + let head = this.#buffer; + this.#buffer = EMPTY_BUFFER; + let tail = this.#chunk.subarray(0, size - head.length); + this.#chunk = this.#chunk.subarray(size - head.length); return [head, tail]; } - let head = this.chunk.subarray(0, size); - this.chunk = this.chunk.subarray(size); + let head = this.#chunk.subarray(0, size); + this.#chunk = this.#chunk.subarray(size); return [head]; } - let head = this.buffer.subarray(0, size); - this.buffer = this.buffer.subarray(size); + let head = this.#buffer.subarray(0, size); + this.#buffer = this.#buffer.subarray(size); return [head]; } private skip(size: number): void { - this.length -= size; + this.#length -= size; - if (size > this.buffer.length) { - this.chunk = this.chunk.subarray(size - this.buffer.length); - this.buffer = EMPTY_BUFFER; + if (size > this.#buffer.length) { + this.#chunk = this.#chunk.subarray(size - this.#buffer.length); + this.#buffer = EMPTY_BUFFER; } else { - this.buffer = this.buffer.subarray(size); + this.#buffer = this.#buffer.subarray(size); } } private save(): void { - if (this.chunk.length === 0) return; - this.buffer = this.buffer.length > 0 ? concatChunks([this.buffer, this.chunk]) : this.chunk; + if (this.#chunk.length === 0) return; + this.#buffer = + this.#buffer.length > 0 ? concatChunks([this.#buffer, this.#chunk]) : this.#chunk; } private writeBody(chunks: Uint8Array[]): void { for (let chunk of chunks) { - if (this.bodyLength + chunk.length > this.maxFileSize) { + if (this.#bodyLength + chunk.length > this.#maxFileSize) { throw new MultipartParseError( - `File size exceeds maximum allowed size of ${this.maxFileSize} bytes` + `File size exceeds maximum allowed size of ${this.#maxFileSize} bytes` ); } - this.bodyController!.enqueue(chunk); - this.bodyLength += chunk.length; + this.#bodyController!.enqueue(chunk); + this.#bodyLength += chunk.length; } } private closeBody(): void { - this.bodyController!.close(); - this.bodyController = null; - this.bodyLength = 0; + this.#bodyController!.close(); + this.#bodyController = null; + this.#bodyLength = 0; } } @@ -365,12 +366,12 @@ function computeSkipTable(pattern: Uint8Array): Uint8Array { * A part of a `multipart/form-data` message. */ export class MultipartPart { - private _header: Uint8Array; - private _headers?: SuperHeaders; - private _bodyUsed = false; + #header: Uint8Array; + #headers?: SuperHeaders; + #bodyUsed = false; constructor(header: Uint8Array, public readonly body: ReadableStream) { - this._header = header; + this.#header = header; } /** @@ -384,18 +385,18 @@ export class MultipartPart { * Whether the body of this part has been consumed. */ get bodyUsed(): boolean { - return this._bodyUsed; + return this.#bodyUsed; } /** * The content of this part as a `Uint8Array`. */ async bytes(): Promise { - if (this._bodyUsed) { + if (this.#bodyUsed) { throw new Error('Body is already consumed or is being consumed'); } - this._bodyUsed = true; + this.#bodyUsed = true; let chunks: Uint8Array[] = []; @@ -410,11 +411,11 @@ export class MultipartPart { * The headers associated with this part. */ get headers(): SuperHeaders { - if (!this._headers) { - this._headers = new SuperHeaders(textDecoder.decode(this._header)); + if (!this.#headers) { + this.#headers = new SuperHeaders(textDecoder.decode(this.#header)); } - return this._headers; + return this.#headers; } /** From e54b380ed63fd6cae96b3c8408ec4f55697f82c1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 1 Aug 2024 09:05:21 -0700 Subject: [PATCH 131/730] Return undefined instead of null for some MultipartPart fields --- src/lib/multipart.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index cec51275ede..8af22e070c4 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -7,7 +7,7 @@ import { concatChunks, readStream } from './utils.js'; */ export function getMultipartBoundary(contentType: string): string | null { let match = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(contentType); - return match ? match[1] || match[2] : null; + return match ? match[1] ?? match[2] : null; } /** @@ -422,28 +422,28 @@ export class MultipartPart { * True if this part originated from a file upload. */ get isFile(): boolean { - return this.filename !== null; + return this.filename !== undefined; } /** * The filename of the part, if it is a file upload. */ - get filename(): string | null { - return this.headers.contentDisposition.preferredFilename || null; + get filename(): string | undefined { + return this.headers.contentDisposition.preferredFilename; } /** * The media type of the part. */ - get mediaType(): string | null { - return this.headers.contentType.mediaType || null; + get mediaType(): string | undefined { + return this.headers.contentType.mediaType; } /** * The name of the part, usually the `name` of the field in the `
` that submitted the request. */ - get name(): string | null { - return this.headers.contentDisposition.name || null; + get name(): string | undefined { + return this.headers.contentDisposition.name; } /** From 4d61e87f77d8f13055aacd7690e2e9cba9f6f9c0 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 1 Aug 2024 12:18:15 -0700 Subject: [PATCH 132/730] Add Prettier --- package.json | 1 + pnpm-lock.yaml | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/package.json b/package.json index fc4b40a2514..ec695a0dde9 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ }, "devDependencies": { "@types/node": "^20.14.10", + "prettier": "^3.3.3", "tsimp": "^2.0.11", "typescript": "^5.5.3" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c714a7c0d6f..5f4915cc9b4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,6 +15,9 @@ importers: '@types/node': specifier: ^20.14.10 version: 20.14.13 + prettier: + specifier: ^3.3.3 + version: 3.3.3 tsimp: specifier: ^2.0.11 version: 2.0.11(typescript@5.5.4) @@ -563,6 +566,11 @@ packages: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + printable-characters@1.0.42: resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} @@ -1147,6 +1155,8 @@ snapshots: pirates@4.0.6: {} + prettier@3.3.3: {} + printable-characters@1.0.42: {} readdirp@3.6.0: From b4364b547c886014feb635e3d5ff564f9c72742a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 1 Aug 2024 12:22:50 -0700 Subject: [PATCH 133/730] Update some test code --- src/test/utils.ts | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/test/utils.ts b/src/test/utils.ts index fbb3dd03423..dcfead044c1 100644 --- a/src/test/utils.ts +++ b/src/test/utils.ts @@ -6,7 +6,7 @@ export const CRLF = '\r\n'; export function createReadableStream( content: string | Uint8Array, - chunkSize = 16 * 1024 + chunkSize = 64 * 1024, ): ReadableStream { let encoder = new TextEncoder(); @@ -16,7 +16,7 @@ export function createReadableStream( controller.enqueue( typeof content === 'string' ? encoder.encode(content.slice(i, i + chunkSize)) - : content.subarray(i, i + chunkSize) + : content.subarray(i, i + chunkSize), ); } controller.close(); @@ -49,12 +49,16 @@ export type PartValue = export function createMultipartBody( boundary: string, - parts?: { [name: string]: PartValue } + parts?: { [name: string]: PartValue }, ): Uint8Array { let chunks: Uint8Array[] = []; - function pushLine(value: string) { - chunks.push(new TextEncoder().encode(value + CRLF)); + function pushString(string: string) { + chunks.push(new TextEncoder().encode(string)); + } + + function pushLine(line = '') { + pushString(line + CRLF); } if (parts) { @@ -66,7 +70,7 @@ export function createMultipartBody( contentDisposition.type = 'form-data'; contentDisposition.name = name; pushLine(`Content-Disposition: ${contentDisposition}`); - pushLine(''); + pushLine(); pushLine(part); } else { let contentDisposition = new ContentDisposition(); @@ -84,25 +88,25 @@ export function createMultipartBody( pushLine(`Content-Type: ${contentType}`); } - pushLine(''); + pushLine(); if (typeof part.content === 'string') { pushLine(part.content); } else { chunks.push(part.content); - pushLine(''); + pushLine(); } } } } - pushLine(`--${boundary}--`); + pushString(`--${boundary}--`); return concatChunks(chunks); } export function createMultipartMockRequest( boundary: string, - parts?: { [name: string]: PartValue } + parts?: { [name: string]: PartValue }, ): Request { let headers = new SuperHeaders(); headers.contentType.mediaType = 'multipart/form-data'; From 86a6c653c8ab006e638290e1723300413afb8c82 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 1 Aug 2024 12:44:25 -0700 Subject: [PATCH 134/730] Use binary data in benchmarks --- bench/messages.ts | 45 +++++++++++++++++++++++++++++++-------------- bench/utils.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 bench/utils.ts diff --git a/bench/messages.ts b/bench/messages.ts index bb76f03858f..ce43600c962 100644 --- a/bench/messages.ts +++ b/bench/messages.ts @@ -1,24 +1,41 @@ +import { concatChunks, getRandomBytes } from './utils.js'; + +const NodeDefaultHighWaterMark = 65536; + export class MultipartMessage { - public content: string; + boundary: string; + content: Uint8Array; + + constructor(boundary: string, partSizes: number[]) { + this.boundary = boundary; + + let chunks: Uint8Array[] = []; + + function pushString(string: string): void { + chunks.push(new TextEncoder().encode(string)); + } + + function pushLine(line = ''): void { + pushString(line + '\r\n'); + } - constructor(public boundary: string, partSizes: number[]) { - let parts = []; for (let i = 0; i < partSizes.length; i++) { - parts.push(`--${boundary}`); - parts.push(`Content-Disposition: form-data; name="file${i}"; filename="file${i}.txt"`); - parts.push('Content-Type: text/plain'); - parts.push(''); - parts.push('x'.repeat(partSizes[i])); + pushLine(`--${boundary}`); + pushLine(`Content-Disposition: form-data; name="file${i}"; filename="file${i}.dat"`); + pushLine('Content-Type: application/octet-stream'); + pushLine(); + chunks.push(getRandomBytes(partSizes[i])); + pushLine(); } - parts.push(`--${boundary}--`); - this.content = parts.join('\r\n'); + pushString(`--${boundary}--`); + + this.content = concatChunks(chunks); } - *generateChunks(chunkSize = 16 * 1024): Generator { - let encoder = new TextEncoder(); + *generateChunks(chunkSize = NodeDefaultHighWaterMark): Generator { for (let i = 0; i < this.content.length; i += chunkSize) { - yield encoder.encode(this.content.slice(i, i + chunkSize)); + yield this.content.subarray(i, i + chunkSize); } } } @@ -34,7 +51,7 @@ export const oneLargeFile = new MultipartMessage('----WebKitFormBoundaryzv0Og5zW export const oneHundredSmallFiles = new MultipartMessage( '----WebKitFormBoundaryzv0Og5zWtGjvzP2A', - Array(100).fill(oneKb) + Array(100).fill(oneKb), ); export const fiveLargeFiles = new MultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [ diff --git a/bench/utils.ts b/bench/utils.ts new file mode 100644 index 00000000000..4a0ecb67155 --- /dev/null +++ b/bench/utils.ts @@ -0,0 +1,28 @@ +export function concatChunks(chunks: Uint8Array[]): Uint8Array { + if (chunks.length === 1) return chunks[0]; + + let length = 0; + for (let chunk of chunks) { + length += chunk.length; + } + + let result = new Uint8Array(length); + let offset = 0; + + for (let chunk of chunks) { + result.set(chunk, offset); + offset += chunk.length; + } + + return result; +} + +export function getRandomBytes(size: number): Uint8Array { + let chunks: Uint8Array[] = []; + + for (let i = 0; i < size; i += 65536) { + chunks.push(crypto.getRandomValues(new Uint8Array(Math.min(size - i, 65536)))); + } + + return concatChunks(chunks); +} From f14fbd9a6fbaa8f3a94e6e06a36eef4d9a6ffb6e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 1 Aug 2024 13:25:32 -0700 Subject: [PATCH 135/730] More regular JS Rely less on TS features for access and visibility. Also, added some more doc comments. --- src/lib/multipart.ts | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 8af22e070c4..9d951b7cf69 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -7,7 +7,7 @@ import { concatChunks, readStream } from './utils.js'; */ export function getMultipartBoundary(contentType: string): string | null { let match = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(contentType); - return match ? match[1] ?? match[2] : null; + return match ? (match[1] ?? match[2]) : null; } /** @@ -23,7 +23,7 @@ export function isMultipartRequest(request: Request): boolean { */ export async function* parseMultipartRequest( request: Request, - options?: MultipartParserOptions + options?: MultipartParserOptions, ): AsyncGenerator { if (!isMultipartRequest(request)) { throw new MultipartParseError('Request is not a multipart request'); @@ -49,7 +49,7 @@ export async function* parseMultipartRequest( export async function* parseMultipartStream( stream: ReadableStream, boundary: string, - options?: MultipartParserOptions + options?: MultipartParserOptions, ): AsyncGenerator { let parser = new MultipartParser(boundary, options); @@ -120,6 +120,8 @@ enum MultipartParserState { * A parser for `multipart/form-data` streams. */ export class MultipartParser { + boundary: string; + #boundaryArray: Uint8Array; #boundaryLength: number; #boundarySkipTable: Uint8Array; @@ -135,12 +137,13 @@ export class MultipartParser { #bodyLength = 0; constructor( - public boundary: string, + boundary: string, { maxHeaderSize = 8 * 1024, // 8 KB maxFileSize = 10 * 1024 * 1024, // 10 MB - }: MultipartParserOptions = {} + }: MultipartParserOptions = {}, ) { + this.boundary = boundary; this.#boundaryArray = textEncoder.encode(`--${boundary}`); this.#boundaryLength = this.#boundaryArray.length; this.#boundarySkipTable = computeSkipTable(this.#boundaryArray); @@ -213,7 +216,7 @@ export class MultipartParser { if (index === -1) break; if (index > this.#maxHeaderSize) { throw new MultipartParseError( - `Header size exceeds maximum allowed size of ${this.#maxHeaderSize} bytes` + `Header size exceeds maximum allowed size of ${this.#maxHeaderSize} bytes`, ); } @@ -302,7 +305,7 @@ export class MultipartParser { for (let chunk of chunks) { if (this.#bodyLength + chunk.length > this.#maxFileSize) { throw new MultipartParseError( - `File size exceeds maximum allowed size of ${this.#maxFileSize} bytes` + `File size exceeds maximum allowed size of ${this.#maxFileSize} bytes`, ); } @@ -322,7 +325,7 @@ function find( head: Uint8Array, tail: Uint8Array, pattern: Uint8Array, - skipTable = computeSkipTable(pattern) + skipTable = computeSkipTable(pattern), ): number { let headLength = head.length; let totalLength = headLength + tail.length; @@ -367,11 +370,14 @@ function computeSkipTable(pattern: Uint8Array): Uint8Array { */ export class MultipartPart { #header: Uint8Array; + #body: ReadableStream; + #headers?: SuperHeaders; #bodyUsed = false; - constructor(header: Uint8Array, public readonly body: ReadableStream) { + constructor(header: Uint8Array, body: ReadableStream) { this.#header = header; + this.#body = body; } /** @@ -381,6 +387,14 @@ export class MultipartPart { return (await this.bytes()).buffer; } + /** + * The body of this part as a `ReadableStream`. In `multipart/form-data` messages, this is useful + * for streaming the value of files that were uploaded using `` fields. + */ + get body(): ReadableStream { + return this.#body; + } + /** * Whether the body of this part has been consumed. */ @@ -389,7 +403,8 @@ export class MultipartPart { } /** - * The content of this part as a `Uint8Array`. + * The body of this part buffered into a single `Uint8Array`. In `multipart/form-data` messages, this is useful + * for reading the value of files that were uploaded using `` fields. */ async bytes(): Promise { if (this.#bodyUsed) { @@ -400,7 +415,7 @@ export class MultipartPart { let chunks: Uint8Array[] = []; - await readStream(this.body, (chunk) => { + await readStream(this.#body, (chunk) => { chunks.push(chunk); }); @@ -447,7 +462,8 @@ export class MultipartPart { } /** - * The content of the part as a string. + * The body of the part as a string. In `multipart/form-data` messages, this is useful for reading the value + * of parts that originated from `` fields. * * Note: Do not use this for binary data, use `await part.bytes()` or stream `part.body` directly instead. */ From 91f96f040c02c87ce996a5c99f70addc027505b7 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 1 Aug 2024 15:53:13 -0700 Subject: [PATCH 136/730] Inline text encoder and decoder --- src/lib/multipart.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 9d951b7cf69..3ee71a32201 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -93,9 +93,6 @@ const DOUBLE_NEWLINE = new Uint8Array([13, 10, 13, 10]); const DOUBLE_NEWLINE_SKIP_TABLE = computeSkipTable(DOUBLE_NEWLINE); const EMPTY_BUFFER = new Uint8Array(0); -const textDecoder = new TextDecoder(); -const textEncoder = new TextEncoder(); - export class MultipartParseError extends Error { constructor(message: string) { super(message); @@ -144,7 +141,7 @@ export class MultipartParser { }: MultipartParserOptions = {}, ) { this.boundary = boundary; - this.#boundaryArray = textEncoder.encode(`--${boundary}`); + this.#boundaryArray = new TextEncoder().encode(`--${boundary}`); this.#boundaryLength = this.#boundaryArray.length; this.#boundarySkipTable = computeSkipTable(this.#boundaryArray); this.#maxHeaderSize = maxHeaderSize; @@ -427,7 +424,7 @@ export class MultipartPart { */ get headers(): SuperHeaders { if (!this.#headers) { - this.#headers = new SuperHeaders(textDecoder.decode(this.#header)); + this.#headers = new SuperHeaders(new TextDecoder().decode(this.#header)); } return this.#headers; From f0e035f8da615a037fdf2f6179e8401e36d56121 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 1 Aug 2024 16:12:07 -0700 Subject: [PATCH 137/730] use findDoubleNewline --- src/lib/multipart.ts | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 3ee71a32201..f8951a9176e 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -89,8 +89,6 @@ export async function* parseMultipartStream( } const HYPHEN = 45; -const DOUBLE_NEWLINE = new Uint8Array([13, 10, 13, 10]); -const DOUBLE_NEWLINE_SKIP_TABLE = computeSkipTable(DOUBLE_NEWLINE); const EMPTY_BUFFER = new Uint8Array(0); export class MultipartParseError extends Error { @@ -209,15 +207,15 @@ export class MultipartParser { break; } - let index = find(this.#buffer, this.#chunk, DOUBLE_NEWLINE, DOUBLE_NEWLINE_SKIP_TABLE); - if (index === -1) break; - if (index > this.#maxHeaderSize) { + let headerEndIndex = findDoubleNewline(this.#buffer, this.#chunk); + if (headerEndIndex === -1) break; + if (headerEndIndex > this.#maxHeaderSize) { throw new MultipartParseError( `Header size exceeds maximum allowed size of ${this.#maxHeaderSize} bytes`, ); } - let header = concatChunks(this.read(index)); + let header = concatChunks(this.read(headerEndIndex)); this.skip(4); // Skip \r\n\r\n let body = new ReadableStream({ @@ -348,7 +346,7 @@ function find( i += skipTable[byteAt(i)]; } - return -1; + return -1; // Not found } function computeSkipTable(pattern: Uint8Array): Uint8Array { @@ -362,6 +360,33 @@ function computeSkipTable(pattern: Uint8Array): Uint8Array { return table; } +const CR = 13; // Carriage Return +const LF = 10; // Line Feed + +function findDoubleNewline(head: Uint8Array, tail: Uint8Array): number { + let headLength = head.length; + + function byteAt(index: number) { + return index < headLength ? head[index] : tail[index - headLength]; + } + + let end = headLength + tail.length - 3; + for (let i = 0; i < end; ++i) { + if (byteAt(i + 3) === LF) { + if (byteAt(i + 2) === CR && byteAt(i + 1) === LF && byteAt(i) === CR) { + return i; + } + i += 1; + } else if (byteAt(i + 3) === CR) { + i += 2; + } else { + i += 3; + } + } + + return -1; // Not found +} + /** * A part of a `multipart/form-data` message. */ From 8a4ed374b5cadd2f4bb40d8170549dc8e03d3529 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 1 Aug 2024 16:21:00 -0700 Subject: [PATCH 138/730] More doc comments, and use JS for private methods --- src/lib/multipart.ts | 45 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index f8951a9176e..392532aeaa4 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -19,7 +19,8 @@ export function isMultipartRequest(request: Request): boolean { } /** - * Parse a multipart `Request` and yield each part as a `MultipartPart` object. + * Parse a multipart [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and yield each part as + * a `MultipartPart` object. Useful in HTTP server contexts for handling incoming `multipart/*` requests. */ export async function* parseMultipartRequest( request: Request, @@ -41,7 +42,7 @@ export async function* parseMultipartRequest( } /** - * Parse a multipart stream and yield each part as a `MultipartPart` object. + * Parse a `multipart/*` message stream and yield each part as a `MultipartPart` object. * * Note: This is a low-level API that requires manual handling of the stream and boundary. For most * common cases, consider using `parseMultipartRequest(request)` instead. @@ -112,7 +113,7 @@ enum MultipartParserState { } /** - * A parser for `multipart/form-data` streams. + * A parser for `multipart/*` message streams. */ export class MultipartParser { boundary: string; @@ -160,7 +161,7 @@ export class MultipartParser { if (this.#state === MultipartParserState.Start) { if (this.#length < this.#boundaryLength) { - this.save(); + this.#save(); return []; } @@ -169,7 +170,7 @@ export class MultipartParser { throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); } - this.skip(this.#boundaryLength); + this.#skip(this.#boundaryLength); this.#state = MultipartParserState.AfterBoundary; } @@ -179,13 +180,13 @@ export class MultipartParser { while (true) { if (this.#state === MultipartParserState.AfterBoundary) { if (this.#length < 2) { - this.save(); + this.#save(); break; } // If the next two bytes are "--" then we're done; this is the closing boundary. Otherwise // they're the \r\n after a boundary in the middle of the message and we can ignore them. - let twoBytes = this.read(2); + let twoBytes = this.#read(2); if ( (twoBytes.length === 1 && twoBytes[0][0] === HYPHEN && twoBytes[0][1] === HYPHEN) || (twoBytes[0][0] === HYPHEN && twoBytes[1][0] === HYPHEN) @@ -203,7 +204,7 @@ export class MultipartParser { if (this.#state === MultipartParserState.Header) { if (this.#length < 4) { - this.save(); + this.#save(); break; } @@ -215,8 +216,8 @@ export class MultipartParser { ); } - let header = concatChunks(this.read(headerEndIndex)); - this.skip(4); // Skip \r\n\r\n + let header = concatChunks(this.#read(headerEndIndex)); + this.#skip(4); // Skip \r\n\r\n let body = new ReadableStream({ start: (controller) => { @@ -231,7 +232,7 @@ export class MultipartParser { if (this.#state === MultipartParserState.Body) { if (this.#length < this.#boundaryLength) { - this.save(); + this.#save(); break; } @@ -240,15 +241,15 @@ export class MultipartParser { if (index === -1) { // Write as much of the buffer as we can to the current body stream while still // keeping enough to check if the last few bytes are part of the boundary. - this.writeBody(this.read(this.#length - this.#boundaryLength + 1)); - this.save(); + this.#writeBody(this.#read(this.#length - this.#boundaryLength + 1)); + this.#save(); break; } - this.writeBody(this.read(index - 2)); // -2 to avoid \r\n before boundary - this.closeBody(); + this.#writeBody(this.#read(index - 2)); // -2 to avoid \r\n before boundary + this.#closeBody(); - this.skip(2 + this.#boundaryLength); // Skip \r\n + boundary + this.#skip(2 + this.#boundaryLength); // Skip \r\n + boundary this.#state = MultipartParserState.AfterBoundary; } @@ -257,7 +258,7 @@ export class MultipartParser { return parts; } - private read(size: number): Uint8Array[] { + #read(size: number): Uint8Array[] { this.#length -= size; if (size > this.#buffer.length) { @@ -279,7 +280,7 @@ export class MultipartParser { return [head]; } - private skip(size: number): void { + #skip(size: number): void { this.#length -= size; if (size > this.#buffer.length) { @@ -290,13 +291,13 @@ export class MultipartParser { } } - private save(): void { + #save(): void { if (this.#chunk.length === 0) return; this.#buffer = this.#buffer.length > 0 ? concatChunks([this.#buffer, this.#chunk]) : this.#chunk; } - private writeBody(chunks: Uint8Array[]): void { + #writeBody(chunks: Uint8Array[]): void { for (let chunk of chunks) { if (this.#bodyLength + chunk.length > this.#maxFileSize) { throw new MultipartParseError( @@ -309,7 +310,7 @@ export class MultipartParser { } } - private closeBody(): void { + #closeBody(): void { this.#bodyController!.close(); this.#bodyController = null; this.#bodyLength = 0; @@ -388,7 +389,7 @@ function findDoubleNewline(head: Uint8Array, tail: Uint8Array): number { } /** - * A part of a `multipart/form-data` message. + * A part of a `multipart/*` message. */ export class MultipartPart { #header: Uint8Array; From 412ca089adbfcd6f1e7b53aaf7cba94fb366dc09 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 1 Aug 2024 18:10:00 -0700 Subject: [PATCH 139/730] Run benchmarks in Bun and Deno too --- README.md | 61 +++++++-- bench/runner.ts | 17 ++- deno.json | 3 + deno.lock | 340 ++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +- 5 files changed, 414 insertions(+), 12 deletions(-) create mode 100644 deno.json create mode 100644 deno.lock diff --git a/README.md b/README.md index b5e154605f5..40118a32198 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,14 @@ - Parsing `multipart/mixed` messages (email attachments, API responses, etc.) - Parsing email messages with both plain text and HTML versions (`multipart/alternative`) +## Goals + +The goals of this project are: + +- Provide a JavaScript-y multipart parser that runs anywhere JavaScript runs +- Support the entire spectrum of `multipart/*` message types +- Be fast enough to get the job done quickly while using as little memory as possible + ## Installation ```sh @@ -85,26 +93,61 @@ The [`examples` directory](/examples) contains a few working examples of how you `multipart-parser` is designed to be as efficient as possible, only operating on streams of data and never buffering in common usage. This design yields exceptional performance when handling multipart payloads of any size. In most benchmarks, `multipart-parser` is as fast or faster than `busboy`. -To run the benchmarks yourself: - -```sh -$ pnpm run bench -``` +Important: Benchmarking can be tricky, and results vary greatly depending on platform, parameters, and other factors. So take these results with a grain of salt. The main point of this library is to be portable between JavaScript runtimes. To this end, we run the benchmarks on three major open source JavaScript runtimes: Node.js, Bun, and Deno. These benchmarks are only intended to show that multipart-parser is fast enough to get the job done wherever you run it. The results of running the benchmarks on my laptop: ``` +> @mjackson/multipart-parser@0.1.1 bench:node /Users/michael/Projects/multipart-parser +> node --import tsimp/import ./bench/runner.ts + Platform: Darwin (23.5.0) CPU: Apple M2 Pro +Date: 8/1/2024, 5:47:52 PM Node.js v20.15.1 -Date: 7/31/2024, 1:38:33 PM ┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ multipart-parser │ '0.02 ms ± 0.11' │ '1.33 ms ± 0.08' │ '0.35 ms ± 0.13' │ '15.18 ms ± 1.83' │ -│ busboy │ '0.03 ms ± 0.09' │ '2.75 ms ± 0.32' │ '0.22 ms ± 0.03' │ '31.22 ms ± 1.37' │ -│ @fastify/busboy │ '0.04 ms ± 0.08' │ '2.01 ms ± 0.28' │ '0.39 ms ± 0.04' │ '26.68 ms ± 1.32' │ +│ multipart-parser │ '0.02 ms ± 0.07' │ '1.48 ms ± 0.31' │ '0.35 ms ± 0.13' │ '15.14 ms ± 1.60' │ +│ busboy │ '0.03 ms ± 0.08' │ '4.26 ms ± 0.08' │ '0.25 ms ± 0.02' │ '43.25 ms ± 2.45' │ +│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.11 ms ± 0.06' │ '0.54 ms ± 0.62' │ '11.11 ms ± 1.17' │ └──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ + +> @mjackson/multipart-parser@0.1.1 bench:bun /Users/michael/Projects/multipart-parser +> bun run ./bench/runner.ts + +Platform: Darwin (23.5.0) +CPU: Apple M2 Pro +Date: 8/1/2024, 5:49:56 PM +Bun 1.1.21 +┌──────────────────┬────────────────┬────────────────┬─────────────────┬─────────────────┐ +│ │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ +├──────────────────┼────────────────┼────────────────┼─────────────────┼─────────────────┤ +│ multipart-parser │ 0.01 ms ± 0.07 │ 1.16 ms ± 0.17 │ 0.17 ms ± 0.10 │ 11.37 ms ± 1.25 │ +│ busboy │ 0.03 ms ± 0.14 │ 3.29 ms ± 0.10 │ 0.34 ms ± 0.15 │ 33.09 ms ± 2.06 │ +│ @fastify/busboy │ 0.03 ms ± 0.12 │ 6.92 ms ± 1.79 │ 0.58 ms ± 0.13 │ 67.20 ms ± 3.01 │ +└──────────────────┴────────────────┴────────────────┴─────────────────┴─────────────────┘ + +> @mjackson/multipart-parser@0.1.1 bench:deno /Users/michael/Projects/multipart-parser +> deno --unstable-sloppy-imports run --allow-sys ./bench/runner.ts + +Platform: Darwin (23.5.0) +CPU: Apple M2 Pro +Date: 8/1/2024, 5:52:49 PM +Deno 1.45.5 +┌──────────────────┬──────────────────┬───────────────────┬──────────────────┬────────────────────┐ +│ (idx) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ +├──────────────────┼──────────────────┼───────────────────┼──────────────────┼────────────────────┤ +│ multipart-parser │ "0.03 ms ± 0.27" │ "1.16 ms ± 0.99" │ "0.11 ms ± 0.46" │ "10.71 ms ± 0.98" │ +│ busboy │ "0.03 ms ± 0.26" │ "2.85 ms ± 0.99" │ "0.28 ms ± 0.70" │ "29.11 ms ± 2.57" │ +│ @fastify/busboy │ "0.05 ms ± 0.31" │ "11.38 ms ± 0.93" │ "0.73 ms ± 0.96" │ "115.56 ms ± 8.07" │ +└──────────────────┴──────────────────┴───────────────────┴──────────────────┴────────────────────┘ +``` + +I'd encourage you to run the benchmarks yourself. You'll probably get different results! + +```sh +$ pnpm run bench ``` ## Credits diff --git a/bench/runner.ts b/bench/runner.ts index 0845bc227c3..0fd924e4462 100644 --- a/bench/runner.ts +++ b/bench/runner.ts @@ -1,4 +1,5 @@ import * as os from 'node:os'; +import * as process from 'node:process'; import * as messages from './messages.js'; import * as busboy from './parsers/busboy.js'; @@ -25,7 +26,7 @@ interface Parser { async function runParserBenchmarks( parser: Parser, - times = 1000 + times = 1000, ): Promise<{ [testName: string]: string }> { let results: { [testName: string]: string } = {}; @@ -66,8 +67,20 @@ async function runBenchmarks(parserName?: string): Promise { function printResults(results: BenchmarkResults) { console.log(`Platform: ${os.type()} (${os.release()})`); console.log(`CPU: ${os.cpus()[0].model}`); - console.log(`Node.js ${process.version}`); console.log(`Date: ${new Date().toLocaleString()}`); + + // @ts-expect-error + const Bun = globalThis.Bun; + // @ts-expect-error + const Deno = globalThis.Deno; + if (typeof Bun !== 'undefined') { + console.log(`Bun ${Bun.version}`); + } else if (typeof Deno !== 'undefined') { + console.log(`Deno ${Deno.version.deno}`); + } else { + console.log(`Node.js ${process.version}`); + } + console.table(results); } diff --git a/deno.json b/deno.json new file mode 100644 index 00000000000..5317e28d918 --- /dev/null +++ b/deno.json @@ -0,0 +1,3 @@ +{ + "workspace": ["./bench"] +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 00000000000..0f1a48ad606 --- /dev/null +++ b/deno.lock @@ -0,0 +1,340 @@ +{ + "version": "3", + "packages": { + "specifiers": { + "npm:@fastify/busboy@^3.0.0": "npm:@fastify/busboy@3.0.0", + "npm:@types/busboy@^1.5.4": "npm:@types/busboy@1.5.4", + "npm:@types/node@^20.14.10": "npm:@types/node@20.14.13", + "npm:busboy@^1.6.0": "npm:busboy@1.6.0", + "npm:fetch-super-headers@^0.4.1": "npm:fetch-super-headers@0.4.1", + "npm:prettier@^3.3.3": "npm:prettier@3.3.3", + "npm:tsimp@^2.0.11": "npm:tsimp@2.0.11_typescript@5.5.4", + "npm:typescript@^5.5.3": "npm:typescript@5.5.4" + }, + "npm": { + "@fastify/busboy@3.0.0": { + "integrity": "sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==", + "dependencies": {} + }, + "@isaacs/cached@1.0.1": { + "integrity": "sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==", + "dependencies": { + "@isaacs/catcher": "@isaacs/catcher@1.0.4" + } + }, + "@isaacs/catcher@1.0.4": { + "integrity": "sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA==", + "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" + } + }, + "@pkgjs/parseargs@0.11.0": { + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dependencies": {} + }, + "@types/busboy@1.5.4": { + "integrity": "sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==", + "dependencies": { + "@types/node": "@types/node@18.16.19" + } + }, + "@types/node@18.16.19": { + "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==", + "dependencies": {} + }, + "@types/node@20.14.13": { + "integrity": "sha512-+bHoGiZb8UiQ0+WEtmph2IWQCjIqg8MDZMAV+ppRRhUZnquF5mQkP/9vpSwJClEiSM/C7fZZExPzfU0vJTyp8w==", + "dependencies": { + "undici-types": "undici-types@5.26.5" + } + }, + "ansi-regex@5.0.1": { + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dependencies": {} + }, + "ansi-regex@6.0.1": { + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dependencies": {} + }, + "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": {} + }, + "balanced-match@1.0.2": { + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dependencies": {} + }, + "brace-expansion@2.0.1": { + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "balanced-match@1.0.2" + } + }, + "busboy@1.6.0": { + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "streamsearch@1.1.0" + } + }, + "color-convert@2.0.1": { + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "color-name@1.1.4" + } + }, + "color-name@1.1.4": { + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dependencies": {} + }, + "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" + } + }, + "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": {} + }, + "fetch-super-headers@0.4.1": { + "integrity": "sha512-jXB/p3m6iMeDFhHpJ56BgqrvoDIiyueNPF39twy2N63DMcme0imKhGoEZH8AAbnplnggU9OdUs9eFFPZxPULFA==", + "dependencies": {} + }, + "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" + } + }, + "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" + } + }, + "is-fullwidth-code-point@3.0.0": { + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dependencies": {} + }, + "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" + } + }, + "lru-cache@10.4.3": { + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dependencies": {} + }, + "minimatch@9.0.5": { + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "brace-expansion@2.0.1" + } + }, + "minipass@7.1.2": { + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dependencies": {} + }, + "mkdirp@3.0.1": { + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dependencies": {} + }, + "package-json-from-dist@1.0.0": { + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dependencies": {} + }, + "path-key@3.1.1": { + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dependencies": {} + }, + "path-scurry@1.11.1": { + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dependencies": { + "lru-cache": "lru-cache@10.4.3", + "minipass": "minipass@7.1.2" + } + }, + "pirates@4.0.6": { + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dependencies": {} + }, + "prettier@3.3.3": { + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dependencies": {} + }, + "rimraf@5.0.10": { + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dependencies": { + "glob": "glob@10.4.5" + } + }, + "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": {} + }, + "signal-exit@4.1.0": { + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dependencies": {} + }, + "sock-daemon@1.4.2": { + "integrity": "sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg==", + "dependencies": { + "rimraf": "rimraf@5.0.10", + "signal-exit": "signal-exit@4.1.0", + "socket-post-message": "socket-post-message@1.0.3" + } + }, + "socket-post-message@1.0.3": { + "integrity": "sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==", + "dependencies": {} + }, + "streamsearch@1.1.0": { + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "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" + } + }, + "tsimp@2.0.11_typescript@5.5.4": { + "integrity": "sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==", + "dependencies": { + "@isaacs/cached": "@isaacs/cached@1.0.1", + "@isaacs/catcher": "@isaacs/catcher@1.0.4", + "foreground-child": "foreground-child@3.2.1", + "mkdirp": "mkdirp@3.0.1", + "pirates": "pirates@4.0.6", + "rimraf": "rimraf@5.0.10", + "signal-exit": "signal-exit@4.1.0", + "sock-daemon": "sock-daemon@1.4.2", + "typescript": "typescript@5.5.4", + "walk-up-path": "walk-up-path@3.0.1" + } + }, + "typescript@5.5.4": { + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dependencies": {} + }, + "undici-types@5.26.5": { + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dependencies": {} + }, + "walk-up-path@3.0.1": { + "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==", + "dependencies": {} + }, + "which@2.0.2": { + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "isexe@2.0.0" + } + }, + "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" + } + } + } + }, + "remote": {}, + "workspace": { + "packageJson": { + "dependencies": [ + "npm:@types/node@^20.14.10", + "npm:fetch-super-headers@^0.4.1", + "npm:prettier@^3.3.3", + "npm:tsimp@^2.0.11", + "npm:typescript@^5.5.3" + ] + }, + "members": { + "bench": { + "packageJson": { + "dependencies": [ + "npm:@fastify/busboy@^3.0.0", + "npm:@types/busboy@^1.5.4", + "npm:busboy@^1.6.0" + ] + } + } + } + } +} diff --git a/package.json b/package.json index ec695a0dde9..3745405055b 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,10 @@ }, "scripts": { "clean": "git clean -fdX .", - "bench": "node --import tsimp/import ./bench/runner.ts", + "bench": "pnpm run bench:node && pnpm run bench:bun && pnpm run bench:deno", + "bench:bun": "bun run ./bench/runner.ts", + "bench:deno": "deno --unstable-sloppy-imports run --allow-sys ./bench/runner.ts", + "bench:node": "node --import tsimp/import ./bench/runner.ts", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", "prepare": "npm run build", From 2911b2e22fb1daef59194e6df1078a6f29b82a31 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 2 Aug 2024 09:21:29 -0700 Subject: [PATCH 140/730] Update package description --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3745405055b..02cf6f08217 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@mjackson/multipart-parser", "version": "0.1.1", - "description": "A fast, efficient parser for multipart streams", + "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "license": "MIT", "files": [ From 72500731147c0bab3776e89ee9e47c0d2bff0a75 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 2 Aug 2024 09:21:49 -0700 Subject: [PATCH 141/730] Use PORT constant --- examples/node-server/server.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/node-server/server.js b/examples/node-server/server.js index 698b01ca4c1..48b97d3c1ed 100644 --- a/examples/node-server/server.js +++ b/examples/node-server/server.js @@ -5,6 +5,8 @@ import tmp from 'tmp'; import { MultipartParseError } from '@mjackson/multipart-parser'; import { parseMultipartRequest } from '@mjackson/multipart-parser/node'; +const PORT = 3000; + const server = http.createServer(async (req, res) => { if (req.method === 'GET') { res.writeHead(200, { @@ -76,8 +78,8 @@ const server = http.createServer(async (req, res) => { } }); -server.listen(3000, () => { - console.log('Server listening on http://localhost:3000'); +server.listen(PORT, () => { + console.log(`Server listening on http://localhost:${PORT} ...`); }); // Some lil' helpers From 9bfebec670543d6e64aea90fb7b12d6c971a1146 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 2 Aug 2024 11:13:05 -0700 Subject: [PATCH 142/730] Add MultipartParser#parse() method Also, parsers are now reusable via the `reset()` method. Also, renamed `parseMultipartStream()` to `parseMultipart()` because it now accepts a variety of data source types. --- README.md | 53 ++++++++----- bench/parsers/multipart-parser.ts | 22 ++---- src/lib/multipart.node.ts | 67 ++++------------ src/lib/multipart.ts | 125 ++++++++++++++++++++++-------- src/lib/utils.ts | 11 +-- src/multipart-parser.node.ts | 6 +- src/multipart-parser.ts | 2 +- 7 files changed, 153 insertions(+), 133 deletions(-) diff --git a/README.md b/README.md index 40118a32198..3032b1445e3 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,14 @@ $ npm install @mjackson/multipart-parser ## Usage -If you're building a server you can use `multipart-parser` to handle file uploads. +The most common use case for `multipart-parser` is handling file uploads when you're building a web server. For this case, the `parseMultipartRequest` function is your friend. It will automatically validate the request is `multipart/form-data`, extract the multipart boundary from the `Content-Type` header, parse all fields and files in the `request.body` stream, and `yield` each one to you as a `MultipartPart` object so you can save it to disk or upload it somewhere. ```typescript import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser'; async function handleMultipartRequest(request: Request): void { try { - // The parser `yield`s each MultipartPart as it becomes available. + // The parser `yield`s each MultipartPart as it becomes available for await (let part of parseMultipartRequest(request)) { console.log(part.name); console.log(part.filename); @@ -50,9 +50,9 @@ async function handleMultipartRequest(request: Request): void { } ``` -The main module (`import from "@mjackson/multipart-parser"`) assumes you're working with [the fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) (`Request`, `ReadableStream`, etc). Support for these interfaces was added to node.js by the [undici](https://github.com/nodejs/undici) project in [version 16.5.0](https://nodejs.org/en/blog/release/v16.5.0). +The main module (`import from "@mjackson/multipart-parser"`) assumes you're working with [the fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) (`Request`, `ReadableStream`, etc). Support for these interfaces was added to Node.js by the [undici](https://github.com/nodejs/undici) project in [version 16.5.0](https://nodejs.org/en/blog/release/v16.5.0). -If however you're building a server for node.js that relies on node-specific APIs like `http.IncomingMessage`, `stream.Readable`, and `buffer.Buffer` (ala Express or `http.createServer`), `multipart-parser` ships with an additional module that works directly with these APIs. +If however you're building a server for Node.js that relies on node-specific APIs like `http.IncomingMessage`, `stream.Readable`, and `buffer.Buffer` (ala Express or `http.createServer`), `multipart-parser` ships with an additional module that works directly with these APIs. ```typescript import * as http from 'node:http'; @@ -82,6 +82,24 @@ const server = http.createServer(async (req, res) => { server.listen(8080); ``` +## Low-level API + +If you're working directly with buffers and/or streams that are not necessarily part of an HTTP request, `multipart-parser` provides a `MultipartParser` API that you can use directly: + +```typescript +import { MultipartParser } from '@mjackson/multipart-parser'; + +// Get the data from some API, the filesystem, etc. +let multipartData = new Uint8Array(...); + +let boundary = '----WebKitFormBoundary56eac3x'; +let parser = new MultipartParser(boundary); + +await parser.parse(multipartData, (part) => { + // Do whatever you need... +}); +``` + ## Examples The [`examples` directory](/examples) contains a few working examples of how you can use this library: @@ -98,19 +116,16 @@ Important: Benchmarking can be tricky, and results vary greatly depending on pla The results of running the benchmarks on my laptop: ``` -> @mjackson/multipart-parser@0.1.1 bench:node /Users/michael/Projects/multipart-parser -> node --import tsimp/import ./bench/runner.ts - Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/1/2024, 5:47:52 PM +Date: 8/2/2024, 2:40:59 PM Node.js v20.15.1 ┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ multipart-parser │ '0.02 ms ± 0.07' │ '1.48 ms ± 0.31' │ '0.35 ms ± 0.13' │ '15.14 ms ± 1.60' │ -│ busboy │ '0.03 ms ± 0.08' │ '4.26 ms ± 0.08' │ '0.25 ms ± 0.02' │ '43.25 ms ± 2.45' │ -│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.11 ms ± 0.06' │ '0.54 ms ± 0.62' │ '11.11 ms ± 1.17' │ +│ multipart-parser │ '0.01 ms ± 0.03' │ '1.33 ms ± 0.07' │ '0.33 ms ± 0.14' │ '13.28 ms ± 0.33' │ +│ busboy │ '0.03 ms ± 0.07' │ '3.11 ms ± 1.26' │ '0.22 ms ± 0.03' │ '43.30 ms ± 2.25' │ +│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.12 ms ± 0.22' │ '0.39 ms ± 0.03' │ '11.28 ms ± 0.36' │ └──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ > @mjackson/multipart-parser@0.1.1 bench:bun /Users/michael/Projects/multipart-parser @@ -118,14 +133,14 @@ Node.js v20.15.1 Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/1/2024, 5:49:56 PM +Date: 8/2/2024, 2:43:05 PM Bun 1.1.21 ┌──────────────────┬────────────────┬────────────────┬─────────────────┬─────────────────┐ │ │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼────────────────┼────────────────┼─────────────────┼─────────────────┤ -│ multipart-parser │ 0.01 ms ± 0.07 │ 1.16 ms ± 0.17 │ 0.17 ms ± 0.10 │ 11.37 ms ± 1.25 │ -│ busboy │ 0.03 ms ± 0.14 │ 3.29 ms ± 0.10 │ 0.34 ms ± 0.15 │ 33.09 ms ± 2.06 │ -│ @fastify/busboy │ 0.03 ms ± 0.12 │ 6.92 ms ± 1.79 │ 0.58 ms ± 0.13 │ 67.20 ms ± 3.01 │ +│ multipart-parser │ 0.01 ms ± 0.05 │ 1.14 ms ± 0.16 │ 0.13 ms ± 0.07 │ 11.49 ms ± 1.61 │ +│ busboy │ 0.03 ms ± 0.13 │ 3.32 ms ± 0.13 │ 0.33 ms ± 0.14 │ 33.31 ms ± 3.08 │ +│ @fastify/busboy │ 0.03 ms ± 0.13 │ 6.71 ms ± 0.13 │ 0.60 ms ± 0.14 │ 67.62 ms ± 3.66 │ └──────────────────┴────────────────┴────────────────┴─────────────────┴─────────────────┘ > @mjackson/multipart-parser@0.1.1 bench:deno /Users/michael/Projects/multipart-parser @@ -133,14 +148,14 @@ Bun 1.1.21 Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/1/2024, 5:52:49 PM +Date: 8/2/2024, 2:45:58 PM Deno 1.45.5 ┌──────────────────┬──────────────────┬───────────────────┬──────────────────┬────────────────────┐ │ (idx) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼───────────────────┼──────────────────┼────────────────────┤ -│ multipart-parser │ "0.03 ms ± 0.27" │ "1.16 ms ± 0.99" │ "0.11 ms ± 0.46" │ "10.71 ms ± 0.98" │ -│ busboy │ "0.03 ms ± 0.26" │ "2.85 ms ± 0.99" │ "0.28 ms ± 0.70" │ "29.11 ms ± 2.57" │ -│ @fastify/busboy │ "0.05 ms ± 0.31" │ "11.38 ms ± 0.93" │ "0.73 ms ± 0.96" │ "115.56 ms ± 8.07" │ +│ multipart-parser │ "0.02 ms ± 0.20" │ "1.09 ms ± 1.00" │ "0.09 ms ± 0.42" │ "10.95 ms ± 1.81" │ +│ busboy │ "0.04 ms ± 0.28" │ "2.88 ms ± 0.99" │ "0.29 ms ± 0.70" │ "29.23 ms ± 2.58" │ +│ @fastify/busboy │ "0.04 ms ± 0.30" │ "11.55 ms ± 0.89" │ "0.74 ms ± 0.97" │ "115.39 ms ± 6.50" │ └──────────────────┴──────────────────┴───────────────────┴──────────────────┴────────────────────┘ ``` diff --git a/bench/parsers/multipart-parser.ts b/bench/parsers/multipart-parser.ts index 704cf1f3c53..a22af422286 100644 --- a/bench/parsers/multipart-parser.ts +++ b/bench/parsers/multipart-parser.ts @@ -1,27 +1,15 @@ -import { parseMultipartRequest } from '@mjackson/multipart-parser'; +import { MultipartParser } from '@mjackson/multipart-parser'; import { MultipartMessage } from '../messages.js'; export async function parse(message: MultipartMessage): Promise { - let request = { - headers: new Headers({ - 'Content-Type': `multipart/form-data; boundary=${message.boundary}`, - }), - body: new ReadableStream({ - start(controller) { - for (let chunk of message.generateChunks()) { - controller.enqueue(chunk); - } - controller.close(); - }, - }), - } as Request; - let start = performance.now(); - for await (let _ of parseMultipartRequest(request, { maxFileSize: Infinity })) { + let parser = new MultipartParser(message.boundary, { maxFileSize: Infinity }); + + await parser.parse(message.generateChunks(), (_) => { // Do nothing - } + }); return performance.now() - start; } diff --git a/src/lib/multipart.node.ts b/src/lib/multipart.node.ts index fbd009b392b..cbca13b2343 100644 --- a/src/lib/multipart.node.ts +++ b/src/lib/multipart.node.ts @@ -1,11 +1,11 @@ import * as http from 'node:http'; -import * as stream from 'node:stream'; +import { Readable } from 'node:stream'; import { getMultipartBoundary, + parseMultipart as parseMultipartWeb, MultipartParseError, MultipartParserOptions, - MultipartParser, MultipartPart, } from './multipart.js'; @@ -22,7 +22,7 @@ export function isMultipartRequest(request: http.IncomingMessage): boolean { */ export async function* parseMultipartRequest( request: http.IncomingMessage, - options?: MultipartParserOptions + options?: MultipartParserOptions, ): AsyncGenerator { if (!isMultipartRequest(request)) { throw new MultipartParseError('Request is not a multipart request'); @@ -33,62 +33,23 @@ export async function* parseMultipartRequest( throw new MultipartParseError('Invalid Content-Type header: missing boundary'); } - yield* parseMultipartStream(request, boundary, options); + yield* parseMultipart(request, boundary, options); } /** - * Parse a multipart node.js `Readable` stream and yield each part as a `MultipartPart` object. + * Parse a multipart Node.js `Buffer` or `Readable` stream and yield each part as a `MultipartPart` object. * - * Note: This is a low-level API that requires manual handling of the stream and boundary. For most - * common cases, consider using `parseMultipartRequest(request)` instead. + * Note: This is a low-level API that requires manual handling of the stream and boundary. If you're + * building a web server, consider using `parseMultipartRequest(request)` instead. */ -export async function* parseMultipartStream( - stream: stream.Readable, +export async function* parseMultipart( + data: Buffer | Iterable | Readable | AsyncIterable, boundary: string, - options?: MultipartParserOptions + options?: MultipartParserOptions, ): AsyncGenerator { - let parser = new MultipartParser(boundary, options); - - // The async generator will suspend execution of this function until the next part - // is requested. This has the potential to cause a deadlock if the consumer tries - // to `await part.text()` while the parser is waiting for more bytes. To fix this, - // we read the stream in a promise and buffer parts until they're requested. When - // new parts become available or when we're done reading the stream, we manually - // run the loop to yield the buffered parts. - let parts: MultipartPart[] = []; - let done = false; - let runTheLoop: () => void; - let promise = readStream(stream, (chunk) => { - parts.push(...parser.push(chunk)); - runTheLoop(); - }).finally(() => { - done = true; - runTheLoop(); - }); - - while (!done) { - await new Promise((resolve) => { - runTheLoop = resolve; - }); - - while (parts.length > 0) { - yield parts.shift()!; - } - } - - // Throw any errors that occurred during the parse. - await promise; - - if (!parser.done) { - throw new MultipartParseError('Unexpected end of stream'); + if (data instanceof Readable) { + yield* parseMultipartWeb(Readable.toWeb(data), boundary, options); + } else { + yield* parseMultipartWeb(data, boundary, options); } } - -function readStream(stream: stream.Readable, callback: (chunk: Buffer) => void): Promise { - return new Promise((resolve, reject) => { - stream.on('data', callback); - stream.on('error', reject); - stream.on('end', resolve); - stream.resume(); - }); -} diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 392532aeaa4..da02bf9d49b 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -1,6 +1,6 @@ import { SuperHeaders } from 'fetch-super-headers'; -import { concatChunks, readStream } from './utils.js'; +import { concatChunks, isIterable, readStream } from './utils.js'; /** * Extracts the boundary string from a `multipart/*` content type. @@ -38,55 +38,52 @@ export async function* parseMultipartRequest( throw new MultipartParseError('Invalid Content-Type header: missing boundary'); } - yield* parseMultipartStream(request.body, boundary, options); + yield* parseMultipart(request.body, boundary, options); } /** - * Parse a `multipart/*` message stream and yield each part as a `MultipartPart` object. + * Parse a `multipart/*` buffer or stream and yield each part it finds as a `MultipartPart` object. * - * Note: This is a low-level API that requires manual handling of the stream and boundary. For most - * common cases, consider using `parseMultipartRequest(request)` instead. + * Note: This is a low-level API that requires manual handling of the stream and boundary. If you're + * building a web server, consider using `parseMultipartRequest(request)` instead. */ -export async function* parseMultipartStream( - stream: ReadableStream, +export async function* parseMultipart( + data: Uint8Array | Iterable | ReadableStream | AsyncIterable, boundary: string, options?: MultipartParserOptions, ): AsyncGenerator { let parser = new MultipartParser(boundary, options); - // The async generator will suspend execution of this function until the next part - // is requested. This has the potential to cause a deadlock if the consumer tries - // to `await part.text()` while the parser is waiting for more bytes. To fix this, - // we read the stream in a promise and buffer parts until they're requested. When - // new parts become available or when we're done reading the stream, we manually - // run the loop to yield the buffered parts. let parts: MultipartPart[] = []; + let resolveNext: (() => void) | null = null; let done = false; - let runTheLoop: () => void; - let promise = readStream(stream, (chunk) => { - parts.push(...parser.push(chunk)); - runTheLoop(); - }).finally(() => { - done = true; - runTheLoop(); - }); - while (!done) { - await new Promise((resolve) => { - runTheLoop = resolve; + let parse = parser + .parse(data, (part) => { + parts.push(part); + if (resolveNext) { + resolveNext(); + resolveNext = null; + } + }) + .finally(() => { + done = true; + if (resolveNext) resolveNext(); }); + while (!done) { + if (parts.length === 0) { + await new Promise((resolve) => { + resolveNext = resolve; + }); + } + while (parts.length > 0) { yield parts.shift()!; } } - // Throw any errors that occurred during the parse. - await promise; - - if (!parser.done) { - throw new MultipartParseError('Unexpected end of stream'); - } + await parse; } const HYPHEN = 45; @@ -147,10 +144,61 @@ export class MultipartParser { this.#maxFileSize = maxFileSize; } + /** + * True if the parser has finished parsing the stream and found the closing multipart boundary. + */ get done(): boolean { return this.#state === MultipartParserState.Done; } + /** + * Parse a buffer or stream of multipart data and call the given handler for each part it contains. + * Resolves when the parse is done and all handlers are finished. + */ + async parse( + data: + | Uint8Array + | Iterable + | ReadableStream + | AsyncIterable, + handler: (part: MultipartPart) => void, + ): Promise { + this.reset(); + + let results = []; + + if (data instanceof Uint8Array) { + for (let part of this.push(data)) { + results.push(handler(part)); + } + } else if (isIterable(data)) { + for (let chunk of data) { + for (let part of this.push(chunk)) { + results.push(handler(part)); + } + } + } else { + if (data instanceof ReadableStream) { + data = readStream(data); + } + + for await (let chunk of data) { + for (let part of this.push(chunk)) { + results.push(handler(part)); + } + } + } + + if (!this.done) { + throw new MultipartParseError('Unexpected end of stream'); + } + + await Promise.all(results); + } + + /** + * Push a new chunk of data into the parser and return any parts it contains. + */ push(chunk: Uint8Array): MultipartPart[] { if (this.done) { throw new MultipartParseError('Cannot push, parser is done'); @@ -258,6 +306,18 @@ export class MultipartParser { return parts; } + /** + * Reset the internal state of the parser. + */ + reset(): void { + this.#state = MultipartParserState.Start; + this.#buffer = EMPTY_BUFFER; + this.#chunk = EMPTY_BUFFER; + this.#length = 0; + this.#bodyController = null; + this.#bodyLength = 0; + } + #read(size: number): Uint8Array[] { this.#length -= size; @@ -437,10 +497,9 @@ export class MultipartPart { this.#bodyUsed = true; let chunks: Uint8Array[] = []; - - await readStream(this.#body, (chunk) => { + for await (let chunk of readStream(this.#body)) { chunks.push(chunk); - }); + } return concatChunks(chunks); } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index f853c8d6c7b..0405a5eb564 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -17,17 +17,18 @@ export function concatChunks(chunks: Uint8Array[]): Uint8Array { return result; } -export async function readStream( - stream: ReadableStream, - callback: (chunk: T) => void -): Promise { +export function isIterable(value: unknown): value is Iterable { + return typeof value === 'object' && value != null && Symbol.iterator in value; +} + +export async function* readStream(stream: ReadableStream): AsyncGenerator { let reader = stream.getReader(); try { while (true) { const { done, value } = await reader.read(); if (done) break; - callback(value); + yield value; } } finally { reader.releaseLock(); diff --git a/src/multipart-parser.node.ts b/src/multipart-parser.node.ts index 8d544f68a90..4b80d285e0f 100644 --- a/src/multipart-parser.node.ts +++ b/src/multipart-parser.node.ts @@ -1,5 +1 @@ -export { - isMultipartRequest, - parseMultipartRequest, - parseMultipartStream, -} from './lib/multipart.node.js'; +export { isMultipartRequest, parseMultipartRequest, parseMultipart } from './lib/multipart.node.js'; diff --git a/src/multipart-parser.ts b/src/multipart-parser.ts index 5d6eda24767..57460076ffe 100644 --- a/src/multipart-parser.ts +++ b/src/multipart-parser.ts @@ -2,7 +2,7 @@ export { getMultipartBoundary, isMultipartRequest, parseMultipartRequest, - parseMultipartStream, + parseMultipart, MultipartParseError, MultipartParserOptions, MultipartParser, From f694cd0fcd1bde9b223fa5a2d6745c4440431da1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 2 Aug 2024 15:54:00 -0700 Subject: [PATCH 143/730] Update README --- README.md | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3032b1445e3..40db21a6a09 100644 --- a/README.md +++ b/README.md @@ -84,18 +84,36 @@ server.listen(8080); ## Low-level API -If you're working directly with buffers and/or streams that are not necessarily part of an HTTP request, `multipart-parser` provides a `MultipartParser` API that you can use directly: +If you're working directly with multipart boundaries and buffers/streams of multipart data that are not necessarily part of a request, `multipart-parser` provides a few lower-level APIs that you can use directly: ```typescript -import { MultipartParser } from '@mjackson/multipart-parser'; +import { parseMultipart } from '@mjackson/multipart-parser'; -// Get the data from some API, the filesystem, etc. -let multipartData = new Uint8Array(...); +// Get the data from some API, filesystem, etc. +let multipartData = new Uint8Array(); +// can also be a stream or any Iterable/AsyncIterable +// let multipartData = new ReadableStream(...); +// let multipartData = [new Uint8Array(...), new Uint8Array(...)]; let boundary = '----WebKitFormBoundary56eac3x'; + +for await (let part of parseMultipart(multipartData, boundary)) { + // Do whatever you want with the part... +} +``` + +If you'd prefer a callback-based API, instantiate your own `MultipartParser` and go for it: + +```typescript +import { MultipartParser } from '@mjackson/multipart-parser'; + +let multipartData = new Uint8Array(); +let boundary = '...'; + let parser = new MultipartParser(boundary); -await parser.parse(multipartData, (part) => { +// parse() will resolve once all your callbacks are done +await parser.parse(multipartData, async (part) => { // Do whatever you need... }); ``` From 22f9333c868c2aaa2f032af25ac33965b431c97c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 2 Aug 2024 21:22:57 -0700 Subject: [PATCH 144/730] Use find algorithm for finding header end --- src/lib/multipart.ts | 58 +++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index da02bf9d49b..21fb321f665 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -88,6 +88,8 @@ export async function* parseMultipart( const HYPHEN = 45; const EMPTY_BUFFER = new Uint8Array(0); +const DOUBLE_NEWLINE = new Uint8Array([13, 10, 13, 10]); +const DOUBLE_NEWLINE_SKIP_TABLE = computeSkipTable(DOUBLE_NEWLINE); export class MultipartParseError extends Error { constructor(message: string) { @@ -213,8 +215,13 @@ export class MultipartParser { return []; } - let index = find(this.#buffer, this.#chunk, this.#boundaryArray, this.#boundarySkipTable); - if (index !== 0) { + let boundaryIndex = find( + this.#buffer, + this.#chunk, + this.#boundaryArray, + this.#boundarySkipTable, + ); + if (boundaryIndex !== 0) { throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); } @@ -256,7 +263,12 @@ export class MultipartParser { break; } - let headerEndIndex = findDoubleNewline(this.#buffer, this.#chunk); + let headerEndIndex = find( + this.#buffer, + this.#chunk, + DOUBLE_NEWLINE, + DOUBLE_NEWLINE_SKIP_TABLE, + ); if (headerEndIndex === -1) break; if (headerEndIndex > this.#maxHeaderSize) { throw new MultipartParseError( @@ -284,9 +296,14 @@ export class MultipartParser { break; } - let index = find(this.#buffer, this.#chunk, this.#boundaryArray, this.#boundarySkipTable); + let boundaryIndex = find( + this.#buffer, + this.#chunk, + this.#boundaryArray, + this.#boundarySkipTable, + ); - if (index === -1) { + if (boundaryIndex === -1) { // Write as much of the buffer as we can to the current body stream while still // keeping enough to check if the last few bytes are part of the boundary. this.#writeBody(this.#read(this.#length - this.#boundaryLength + 1)); @@ -294,7 +311,9 @@ export class MultipartParser { break; } - this.#writeBody(this.#read(index - 2)); // -2 to avoid \r\n before boundary + if (boundaryIndex > 2) { + this.#writeBody(this.#read(boundaryIndex - 2)); // -2 to avoid \r\n before boundary + } this.#closeBody(); this.#skip(2 + this.#boundaryLength); // Skip \r\n + boundary @@ -421,33 +440,6 @@ function computeSkipTable(pattern: Uint8Array): Uint8Array { return table; } -const CR = 13; // Carriage Return -const LF = 10; // Line Feed - -function findDoubleNewline(head: Uint8Array, tail: Uint8Array): number { - let headLength = head.length; - - function byteAt(index: number) { - return index < headLength ? head[index] : tail[index - headLength]; - } - - let end = headLength + tail.length - 3; - for (let i = 0; i < end; ++i) { - if (byteAt(i + 3) === LF) { - if (byteAt(i + 2) === CR && byteAt(i + 1) === LF && byteAt(i) === CR) { - return i; - } - i += 1; - } else if (byteAt(i + 3) === CR) { - i += 2; - } else { - i += 3; - } - } - - return -1; // Not found -} - /** * A part of a `multipart/*` message. */ From 042566dd39c659c99e50ebc93b84d68e66f2dc74 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 2 Aug 2024 09:22:00 -0700 Subject: [PATCH 145/730] wip --- examples/bun-server/.gitignore | 175 ++++++++++++++++++++++++++++++ examples/bun-server/README.md | 3 + examples/bun-server/bun.lockb | Bin 0 -> 3134 bytes examples/bun-server/package.json | 11 ++ examples/bun-server/server.ts | 63 +++++++++++ examples/bun-server/tsconfig.json | 27 +++++ 6 files changed, 279 insertions(+) create mode 100644 examples/bun-server/.gitignore create mode 100644 examples/bun-server/README.md create mode 100755 examples/bun-server/bun.lockb create mode 100644 examples/bun-server/package.json create mode 100644 examples/bun-server/server.ts create mode 100644 examples/bun-server/tsconfig.json diff --git a/examples/bun-server/.gitignore b/examples/bun-server/.gitignore new file mode 100644 index 00000000000..9b1ee42e848 --- /dev/null +++ b/examples/bun-server/.gitignore @@ -0,0 +1,175 @@ +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Caches + +.cache + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/examples/bun-server/README.md b/examples/bun-server/README.md new file mode 100644 index 00000000000..068cca5c257 --- /dev/null +++ b/examples/bun-server/README.md @@ -0,0 +1,3 @@ +# multipart-parser Bun Server Example + +This is an example of how you can upload a file to a [Bun](https://bun.sh) server and stream it to a tmp directory on the filesystem. diff --git a/examples/bun-server/bun.lockb b/examples/bun-server/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..ec16aeaa27ef23d15404e5c9b1cc442f3c37f104 GIT binary patch literal 3134 zcmY#Z)GsYA(of3F(@)JSQ%EY!;{sycoc!eMw9K4T-L(9o+{6;yG6OCq1_p*@TXxr8 zw_`ZL-F)luI)~SCPjBzM|0Rrv=VD-J z5CO74bTE+S1kwwDG|;eyr$CwqNKc1~1J!`ltu&WrJ{C6r^C>pXz1{|mU#j1vpY0HO ztu#?Ts#k5RttDr^&9PU3vvw~&J)?4d)}_q(str2Yt*J?jK>d^eP$+eT?2I&R4ffxYOUj)=|1GOKdpM@CBP&FVkKo}J6%uqJS3=kg{4HEk34`dKE0nj`~28g-HMzidg!PRRXej!s#psd*0Fh|XG<@0yusd~q`PfOZF zo;y^s;tDtK^sK#$(~ef^ZZFg3{gN@jw6>9GoJN2X&F{C5Ryykc+Om70;*BQonw$&y26 z7mDlcR+nTb1{xe?oOrm{u75_R3A5ca*7CwA?O90XBF8_AT0oEW^Mxf&T&n^LCohr@ zYY+*`Fn)W~`i%X!P9W|RKDSm&r-&-{8Rn-zC zbCJ_E%e~7NC;fHV=J4`dgpszA&5~@k6vlqRrT2C_oa>)(;`XGd?_qZt+hY^T4)BVJ zuAMBH`*q*7xQK(L&RQMLDpw3ABAE+IXP~fPF}k(w+o5I#H~zOPlij%et){%U{Pw{$ zGw9{zi|0A+3P0H5-u62FF@*8Kn`ei%Vkq)Y-9)2hr zK=pJoycRUDRPt+r{J_v2qneIU=t7g7Fk*}Wr7H(K?V}zzqi=toowN* zlH%gjBA{upmlYa=(!7790V5IQ+7=7bGmI5{|9(JSungJ)1Ev9BcpKshZU#^z4`O0T zWkG6ja#3bMi36Ca50uI%DJdwn($_CaP0uVYDXP@VE6B|%*2^zS*GDMQ*99rn1%O7l`O zlQRiA3RxM@7-X(4I0=}73?uA}@?xOw@?u?ZQZoVv2{;xZ;fzN=A_{;8AUHtFP4&PY K0Vj + + + multipart-parser Bun Server Example + + +

multipart-parser Bun Server Example

+ +

+

+

+ + + +`, + { + headers: { 'Content-Type': 'text/html' }, + }, + ); + } + + if (request.method === 'POST') { + let parts = []; + + for await (let part of parseMultipartRequest(request)) { + if (part.isFile) { + // let uniqueKey = `upload-${new Date().getTime()}-${Math.random() + // .toString(36) + // .slice(2, 8)}`; + + let bytes = await part.bytes(); + parts.push({ + name: part.name, + filename: part.filename, + mediaType: part.mediaType, + size: bytes.byteLength, + }); + } else { + parts.push({ + name: part.name, + value: await part.text(), + }); + } + } + + return new Response(JSON.stringify({ parts }, null, 2), { + headers: { 'Content-Type': 'application/json' }, + }); + } + + return new Response('Method Not Allowed', { status: 405 }); + }, +}); + +console.log(`Server listening on http://localhost:${server.port} ...`); diff --git a/examples/bun-server/tsconfig.json b/examples/bun-server/tsconfig.json new file mode 100644 index 00000000000..238655f2ce2 --- /dev/null +++ b/examples/bun-server/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + // Enable latest features + "lib": ["ESNext", "DOM"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +} From 050bfb8a377df213a38801b6c16024d48a757e0e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 2 Aug 2024 22:41:02 -0700 Subject: [PATCH 146/730] Add Bun example, update other examples --- README.md | 5 +- examples/bun-server/bun.lockb | Bin 3134 -> 0 bytes examples/bun-server/package.json | 11 --- examples/bun-server/server.ts | 63 ------------- examples/{bun-server => bun}/.gitignore | 0 examples/{bun-server => bun}/README.md | 2 +- examples/bun/package.json | 16 ++++ examples/bun/server.ts | 91 +++++++++++++++++++ examples/{bun-server => bun}/tsconfig.json | 0 examples/cf-workers/README.md | 2 + examples/cf-workers/src/index.ts | 91 +++++++++++-------- examples/cf-workers/wrangler.toml | 2 +- examples/node-server/README.md | 3 - examples/node/README.md | 3 + examples/{node-server => node}/package.json | 9 +- examples/{node-server => node}/server.js | 4 +- examples/{node-server => node}/tsconfig.json | 0 pnpm-lock.yaml | 50 +++++++++- 18 files changed, 224 insertions(+), 128 deletions(-) delete mode 100755 examples/bun-server/bun.lockb delete mode 100644 examples/bun-server/package.json delete mode 100644 examples/bun-server/server.ts rename examples/{bun-server => bun}/.gitignore (100%) rename examples/{bun-server => bun}/README.md (78%) create mode 100644 examples/bun/package.json create mode 100644 examples/bun/server.ts rename examples/{bun-server => bun}/tsconfig.json (100%) delete mode 100644 examples/node-server/README.md create mode 100644 examples/node/README.md rename examples/{node-server => node}/package.json (76%) rename examples/{node-server => node}/server.js (96%) rename examples/{node-server => node}/tsconfig.json (100%) diff --git a/README.md b/README.md index 40db21a6a09..2d121867ece 100644 --- a/README.md +++ b/README.md @@ -122,8 +122,9 @@ await parser.parse(multipartData, async (part) => { The [`examples` directory](/examples) contains a few working examples of how you can use this library: -- [`cf-workers`](/examples/cf-workers) shows how you can handle multipart uploads in a Cloudflare worker and store files in R2 -- [`node-server`](/examples/node-server) demonstrates handling multipart uploads and streaming files to disk +- [`examples/bun`](/examples/bun) demonstrates handling multipart uploads in Bun and saving them in a tmp file on disk +- [`examples/cf-workers`](/examples/cf-workers) demonstrates handling multipart uploads in a Cloudflare worker and store files in R2 +- [`examples/node`](/examples/node) demonstrates handling multipart uploads in Node.js and saving them in a tmp file on disk ## Benchmark diff --git a/examples/bun-server/bun.lockb b/examples/bun-server/bun.lockb deleted file mode 100755 index ec16aeaa27ef23d15404e5c9b1cc442f3c37f104..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3134 zcmY#Z)GsYA(of3F(@)JSQ%EY!;{sycoc!eMw9K4T-L(9o+{6;yG6OCq1_p*@TXxr8 zw_`ZL-F)luI)~SCPjBzM|0Rrv=VD-J z5CO74bTE+S1kwwDG|;eyr$CwqNKc1~1J!`ltu&WrJ{C6r^C>pXz1{|mU#j1vpY0HO ztu#?Ts#k5RttDr^&9PU3vvw~&J)?4d)}_q(str2Yt*J?jK>d^eP$+eT?2I&R4ffxYOUj)=|1GOKdpM@CBP&FVkKo}J6%uqJS3=kg{4HEk34`dKE0nj`~28g-HMzidg!PRRXej!s#psd*0Fh|XG<@0yusd~q`PfOZF zo;y^s;tDtK^sK#$(~ef^ZZFg3{gN@jw6>9GoJN2X&F{C5Ryykc+Om70;*BQonw$&y26 z7mDlcR+nTb1{xe?oOrm{u75_R3A5ca*7CwA?O90XBF8_AT0oEW^Mxf&T&n^LCohr@ zYY+*`Fn)W~`i%X!P9W|RKDSm&r-&-{8Rn-zC zbCJ_E%e~7NC;fHV=J4`dgpszA&5~@k6vlqRrT2C_oa>)(;`XGd?_qZt+hY^T4)BVJ zuAMBH`*q*7xQK(L&RQMLDpw3ABAE+IXP~fPF}k(w+o5I#H~zOPlij%et){%U{Pw{$ zGw9{zi|0A+3P0H5-u62FF@*8Kn`ei%Vkq)Y-9)2hr zK=pJoycRUDRPt+r{J_v2qneIU=t7g7Fk*}Wr7H(K?V}zzqi=toowN* zlH%gjBA{upmlYa=(!7790V5IQ+7=7bGmI5{|9(JSungJ)1Ev9BcpKshZU#^z4`O0T zWkG6ja#3bMi36Ca50uI%DJdwn($_CaP0uVYDXP@VE6B|%*2^zS*GDMQ*99rn1%O7l`O zlQRiA3RxM@7-X(4I0=}73?uA}@?xOw@?u?ZQZoVv2{;xZ;fzN=A_{;8AUHtFP4&PY K0Vj - - - multipart-parser Bun Server Example - - -

multipart-parser Bun Server Example

-
-

-

-

-
- - -`, - { - headers: { 'Content-Type': 'text/html' }, - }, - ); - } - - if (request.method === 'POST') { - let parts = []; - - for await (let part of parseMultipartRequest(request)) { - if (part.isFile) { - // let uniqueKey = `upload-${new Date().getTime()}-${Math.random() - // .toString(36) - // .slice(2, 8)}`; - - let bytes = await part.bytes(); - parts.push({ - name: part.name, - filename: part.filename, - mediaType: part.mediaType, - size: bytes.byteLength, - }); - } else { - parts.push({ - name: part.name, - value: await part.text(), - }); - } - } - - return new Response(JSON.stringify({ parts }, null, 2), { - headers: { 'Content-Type': 'application/json' }, - }); - } - - return new Response('Method Not Allowed', { status: 405 }); - }, -}); - -console.log(`Server listening on http://localhost:${server.port} ...`); diff --git a/examples/bun-server/.gitignore b/examples/bun/.gitignore similarity index 100% rename from examples/bun-server/.gitignore rename to examples/bun/.gitignore diff --git a/examples/bun-server/README.md b/examples/bun/README.md similarity index 78% rename from examples/bun-server/README.md rename to examples/bun/README.md index 068cca5c257..cabd35bd478 100644 --- a/examples/bun-server/README.md +++ b/examples/bun/README.md @@ -1,3 +1,3 @@ -# multipart-parser Bun Server Example +# multipart-parser Bun Example This is an example of how you can upload a file to a [Bun](https://bun.sh) server and stream it to a tmp directory on the filesystem. diff --git a/examples/bun/package.json b/examples/bun/package.json new file mode 100644 index 00000000000..0403e6be506 --- /dev/null +++ b/examples/bun/package.json @@ -0,0 +1,16 @@ +{ + "name": "multipart-parser-bun-example", + "private": true, + "type": "module", + "dependencies": { + "@mjackson/multipart-parser": "workspace:*", + "tmp": "^0.2.3" + }, + "devDependencies": { + "@types/bun": "^1.1.6", + "@types/tmp": "^0.2.6" + }, + "scripts": { + "start": "bun run server.ts" + } +} \ No newline at end of file diff --git a/examples/bun/server.ts b/examples/bun/server.ts new file mode 100644 index 00000000000..687184bf4af --- /dev/null +++ b/examples/bun/server.ts @@ -0,0 +1,91 @@ +import type { BunFile } from 'bun'; +import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser'; +import tmp from 'tmp'; + +const server = Bun.serve({ + port: 3000, + async fetch(request) { + if (request.method === 'GET') { + return new Response( + ` + + + + multipart-parser Bun Example + + +

multipart-parser Bun Example

+
+

+

+

+
+ + +`, + { + headers: { 'Content-Type': 'text/html' }, + }, + ); + } + + if (request.method === 'POST') { + try { + let parts: any[] = []; + + for await (let part of parseMultipartRequest(request)) { + if (part.isFile) { + let tmpfile = tmp.fileSync(); + let bytesWritten = await writeFile(Bun.file(tmpfile.name), part.body); + + parts.push({ + name: part.name, + filename: part.filename, + mediaType: part.mediaType, + size: bytesWritten, + file: tmpfile.name, + }); + } else { + parts.push({ + name: part.name, + value: await part.text(), + }); + } + } + + return new Response(JSON.stringify({ parts }, null, 2), { + headers: { 'Content-Type': 'application/json' }, + }); + } catch (error) { + console.error(error); + + if (error instanceof MultipartParseError) { + return new Response(error.message, { status: 400 }); + } + + return new Response('Internal Server Error', { status: 500 }); + } + } + + return new Response('Method Not Allowed', { status: 405 }); + }, +}); + +console.log(`Server listening on http://localhost:${server.port} ...`); + +async function writeFile(file: BunFile, stream: ReadableStream): Promise { + let reader = stream.getReader(); + let writer = file.writer(); + let bytesWritten = 0; + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + writer.write(value); + bytesWritten += value.byteLength; + } + + writer.end(); + + return bytesWritten; +} diff --git a/examples/bun-server/tsconfig.json b/examples/bun/tsconfig.json similarity index 100% rename from examples/bun-server/tsconfig.json rename to examples/bun/tsconfig.json diff --git a/examples/cf-workers/README.md b/examples/cf-workers/README.md index 0428b5d9dde..c407ebeb578 100644 --- a/examples/cf-workers/README.md +++ b/examples/cf-workers/README.md @@ -1,3 +1,5 @@ # multipart-parser CF Workers Example This is a demo of how you can upload a file directly to [a Cloudflare worker](https://developers.cloudflare.com/workers/) and store it in R2. + +Notice: `multipart-parser` doesn't use any node-specific APIs, so this demo does not rely on Cloudflare Workers' [`nodejs_compat` flag] in order to run. diff --git a/examples/cf-workers/src/index.ts b/examples/cf-workers/src/index.ts index 9c526e5ab82..52815d32be3 100644 --- a/examples/cf-workers/src/index.ts +++ b/examples/cf-workers/src/index.ts @@ -1,4 +1,4 @@ -import { parseMultipartRequest } from '@mjackson/multipart-parser'; +import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser'; export default { async fetch(request, env): Promise { @@ -27,49 +27,60 @@ export default { } if (request.method === 'POST') { - let bucket = env.MULTIPART_UPLOADS; - let parts = []; + try { - for await (let part of parseMultipartRequest(request)) { - if (part.isFile) { - let uniqueKey = `upload-${new Date().getTime()}-${Math.random() - .toString(36) - .slice(2, 8)}`; - - // Put the file in R2. - - // Ideally we could stream part.body directly, but Cloudflare's R2 - // API requires a FixedLengthStream and unfortunately we don't know - // the length of the stream at this point because browsers don't send - // Content-Length headers with file uploads. - // await bucket.put(uniqueKey, part.body); - - // So instead, we have to buffer the entire file in memory and then - // upload it to R2. - let bytes = await part.bytes(); - await bucket.put(uniqueKey, bytes, { - httpMetadata: { - contentType: part.headers.get('Content-Type')!, - }, - }); + let bucket = env.MULTIPART_UPLOADS; + let parts = []; + + for await (let part of parseMultipartRequest(request)) { + if (part.isFile) { + let uniqueKey = `upload-${new Date().getTime()}-${Math.random() + .toString(36) + .slice(2, 8)}`; + + // Put the file in R2. + + // Ideally we could stream part.body directly, but Cloudflare's R2 + // API requires a FixedLengthStream and unfortunately we don't know + // the length of the stream at this point because browsers don't send + // Content-Length headers with file uploads. + // await bucket.put(uniqueKey, part.body); + + // So instead, we have to buffer the entire file in memory and then + // upload it to R2. + let bytes = await part.bytes(); + await bucket.put(uniqueKey, bytes, { + httpMetadata: { + contentType: part.headers.get('Content-Type')!, + }, + }); + + parts.push({ + name: part.name, + filename: part.filename, + mediaType: part.mediaType, + size: bytes.byteLength, + }); + } else { + parts.push({ + name: part.name, + value: await part.text(), + }); + } + } + + return new Response(JSON.stringify({ parts }, null, 2), { + headers: { 'Content-Type': 'application/json' }, + }); + } catch (error) { + console.error(error); - parts.push({ - name: part.name, - filename: part.filename, - mediaType: part.mediaType, - size: bytes.byteLength, - }); - } else { - parts.push({ - name: part.name, - value: await part.text(), - }); + if (error instanceof MultipartParseError) { + return new Response(error.message, { status: 400 }); } - } - return new Response(JSON.stringify({ parts }, null, 2), { - headers: { 'Content-Type': 'application/json' }, - }); + return new Response('Internal Server Error', { status: 500 }); + } } return new Response('Method Not Allowed', { status: 405 }); diff --git a/examples/cf-workers/wrangler.toml b/examples/cf-workers/wrangler.toml index 6427e1d1296..a0bfbd88dcd 100644 --- a/examples/cf-workers/wrangler.toml +++ b/examples/cf-workers/wrangler.toml @@ -1,5 +1,5 @@ #:schema node_modules/wrangler/config-schema.json -name = "cf-workers" +name = "multipart-parser-cf-workers" main = "src/index.ts" compatibility_date = "2024-07-25" # compatibility_flags = ["nodejs_compat"] diff --git a/examples/node-server/README.md b/examples/node-server/README.md deleted file mode 100644 index b1c72fd89c7..00000000000 --- a/examples/node-server/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# multipart-parser Node Server Example - -This example is a simple node.js server that handles file uploads and streams them directly to a tmp file on disk. diff --git a/examples/node/README.md b/examples/node/README.md new file mode 100644 index 00000000000..460ad215a66 --- /dev/null +++ b/examples/node/README.md @@ -0,0 +1,3 @@ +# multipart-parser Node Example + +This example is a simple Node.js server that handles file uploads and streams them directly to a tmp file on disk. diff --git a/examples/node-server/package.json b/examples/node/package.json similarity index 76% rename from examples/node-server/package.json rename to examples/node/package.json index f2dcce4b746..13297b1a278 100644 --- a/examples/node-server/package.json +++ b/examples/node/package.json @@ -1,15 +1,16 @@ { - "name": "multipart-parser-node-server-example", + "name": "multipart-parser-node-example", "private": true, "type": "module", "dependencies": { "@mjackson/multipart-parser": "workspace:*", "tmp": "^0.2.3" }, - "scripts": { - "start": "node server.js" - }, "devDependencies": { + "@types/node": "^20.14.10", "@types/tmp": "^0.2.6" + }, + "scripts": { + "start": "node server.js" } } diff --git a/examples/node-server/server.js b/examples/node/server.js similarity index 96% rename from examples/node-server/server.js rename to examples/node/server.js index 48b97d3c1ed..6538f1c8022 100644 --- a/examples/node-server/server.js +++ b/examples/node/server.js @@ -16,10 +16,10 @@ const server = http.createServer(async (req, res) => { - multipart-parser Node Server Example + multipart-parser Node Example -

multipart-parser Node Server Example

+

multipart-parser Node Example

diff --git a/examples/node-server/tsconfig.json b/examples/node/tsconfig.json similarity index 100% rename from examples/node-server/tsconfig.json rename to examples/node/tsconfig.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5f4915cc9b4..d4e22050137 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,6 +40,22 @@ importers: specifier: ^1.6.0 version: 1.6.0 + examples/bun: + dependencies: + '@mjackson/multipart-parser': + specifier: workspace:* + version: link:../.. + tmp: + specifier: ^0.2.3 + version: 0.2.3 + devDependencies: + '@types/bun': + specifier: ^1.1.6 + version: 1.1.6 + '@types/tmp': + specifier: ^0.2.6 + version: 0.2.6 + examples/cf-workers: dependencies: '@mjackson/multipart-parser': @@ -56,7 +72,7 @@ importers: specifier: ^3.60.3 version: 3.67.1(@cloudflare/workers-types@4.20240725.0) - examples/node-server: + examples/node: dependencies: '@mjackson/multipart-parser': specifier: workspace:* @@ -65,6 +81,9 @@ importers: specifier: ^0.2.3 version: 0.2.3 devDependencies: + '@types/node': + specifier: ^20.14.10 + version: 20.14.13 '@types/tmp': specifier: ^0.2.6 version: 0.2.6 @@ -285,18 +304,27 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@types/bun@1.1.6': + resolution: {integrity: sha512-uJgKjTdX0GkWEHZzQzFsJkWp5+43ZS7HC8sZPFnOwnSo1AsNl2q9o2bFeS23disNDqbggEgyFkKCHl/w8iZsMA==} + '@types/busboy@1.5.4': resolution: {integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==} '@types/node-forge@1.3.11': resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} + '@types/node@20.12.14': + resolution: {integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==} + '@types/node@20.14.13': resolution: {integrity: sha512-+bHoGiZb8UiQ0+WEtmph2IWQCjIqg8MDZMAV+ppRRhUZnquF5mQkP/9vpSwJClEiSM/C7fZZExPzfU0vJTyp8w==} '@types/tmp@0.2.6': resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} + '@types/ws@8.5.12': + resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} + acorn-walk@8.3.3: resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} engines: {node: '>=0.4.0'} @@ -346,6 +374,9 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + bun-types@1.1.17: + resolution: {integrity: sha512-Z4+OplcSd/YZq7ZsrfD00DKJeCwuNY96a1IDJyR73+cTBaFIS7SC6LhpY/W3AMEXO9iYq5NJ58WAwnwL1p5vKg==} + busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -884,6 +915,10 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@types/bun@1.1.6': + dependencies: + bun-types: 1.1.17 + '@types/busboy@1.5.4': dependencies: '@types/node': 20.14.13 @@ -892,12 +927,20 @@ snapshots: dependencies: '@types/node': 20.14.13 + '@types/node@20.12.14': + dependencies: + undici-types: 5.26.5 + '@types/node@20.14.13': dependencies: undici-types: 5.26.5 '@types/tmp@0.2.6': {} + '@types/ws@8.5.12': + dependencies: + '@types/node': 20.14.13 + acorn-walk@8.3.3: dependencies: acorn: 8.12.1 @@ -937,6 +980,11 @@ snapshots: dependencies: fill-range: 7.1.1 + bun-types@1.1.17: + dependencies: + '@types/node': 20.12.14 + '@types/ws': 8.5.12 + busboy@1.6.0: dependencies: streamsearch: 1.1.0 From c770e8399cdce5cb8cd8b49edcf383a626652285 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 2 Aug 2024 22:46:27 -0700 Subject: [PATCH 147/730] Small tweaks to Node.js example --- examples/node/README.md | 2 +- examples/node/server.js | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/examples/node/README.md b/examples/node/README.md index 460ad215a66..ac7af04f8fb 100644 --- a/examples/node/README.md +++ b/examples/node/README.md @@ -1,3 +1,3 @@ # multipart-parser Node Example -This example is a simple Node.js server that handles file uploads and streams them directly to a tmp file on disk. +This example is a simple [Node.js server](https://nodejs.org/) that handles file uploads and streams them to a tmp file on disk. diff --git a/examples/node/server.js b/examples/node/server.js index 6538f1c8022..91154838ce6 100644 --- a/examples/node/server.js +++ b/examples/node/server.js @@ -28,7 +28,10 @@ const server = http.createServer(async (req, res) => { `); - } else if (req.method === 'POST') { + return; + } + + if (req.method === 'POST') { try { let parts = []; @@ -61,21 +64,24 @@ const server = http.createServer(async (req, res) => { 'Content-Type': 'application/json', }); res.end(JSON.stringify({ parts }, null, 2)); + return; } catch (error) { console.error(error); if (error instanceof MultipartParseError) { res.writeHead(400); res.end('Bad Request'); - } else { - res.writeHead(500); - res.end('Internal Server Error'); + return; } + + res.writeHead(500); + res.end('Internal Server Error'); + return; } - } else { - res.writeHead(405); - res.end('Method Not Allowed'); } + + res.writeHead(405); + res.end('Method Not Allowed'); }); server.listen(PORT, () => { From 3a883e41f37357297670c9929b1da9a610d748dc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 3 Aug 2024 00:01:58 -0700 Subject: [PATCH 148/730] Add missing await --- examples/bun/server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/bun/server.ts b/examples/bun/server.ts index 687184bf4af..baca9f3f43e 100644 --- a/examples/bun/server.ts +++ b/examples/bun/server.ts @@ -85,7 +85,7 @@ async function writeFile(file: BunFile, stream: ReadableStream): Pro bytesWritten += value.byteLength; } - writer.end(); + await writer.end(); return bytesWritten; } From 8b7119fefe4a4613c4773afeef8545dd8eb62c10 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 3 Aug 2024 08:59:19 -0700 Subject: [PATCH 149/730] Get rid of readStream generator --- src/lib/multipart.node.ts | 2 +- src/lib/multipart.ts | 41 ++++++++++++++++++++++++++++----------- src/lib/utils.ts | 26 ++++++++----------------- 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/lib/multipart.node.ts b/src/lib/multipart.node.ts index cbca13b2343..7e5a303e3c3 100644 --- a/src/lib/multipart.node.ts +++ b/src/lib/multipart.node.ts @@ -43,7 +43,7 @@ export async function* parseMultipartRequest( * building a web server, consider using `parseMultipartRequest(request)` instead. */ export async function* parseMultipart( - data: Buffer | Iterable | Readable | AsyncIterable, + data: Readable | Buffer | Iterable | AsyncIterable, boundary: string, options?: MultipartParserOptions, ): AsyncGenerator { diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 21fb321f665..220eab6d505 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -1,6 +1,6 @@ import { SuperHeaders } from 'fetch-super-headers'; -import { concatChunks, isIterable, readStream } from './utils.js'; +import { concatChunks, isAsyncIterable, isIterable } from './utils.js'; /** * Extracts the boundary string from a `multipart/*` content type. @@ -159,9 +159,9 @@ export class MultipartParser { */ async parse( data: + | ReadableStream | Uint8Array | Iterable - | ReadableStream | AsyncIterable, handler: (part: MultipartPart) => void, ): Promise { @@ -169,7 +169,22 @@ export class MultipartParser { let results = []; - if (data instanceof Uint8Array) { + if (data instanceof ReadableStream) { + let reader = data.getReader(); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + + for (let part of this.push(value)) { + results.push(handler(part)); + } + } + } finally { + reader.releaseLock(); + } + } else if (data instanceof Uint8Array) { for (let part of this.push(data)) { results.push(handler(part)); } @@ -179,16 +194,14 @@ export class MultipartParser { results.push(handler(part)); } } - } else { - if (data instanceof ReadableStream) { - data = readStream(data); - } - + } else if (isAsyncIterable(data)) { for await (let chunk of data) { for (let part of this.push(chunk)) { results.push(handler(part)); } } + } else { + throw new TypeError('Cannot parse data: expected a stream or buffer'); } if (!this.done) { @@ -458,7 +471,7 @@ export class MultipartPart { /** * The content of this part as an `ArrayBuffer`. */ - async arrayBuffer(): Promise { + async arrayBuffer(): Promise { return (await this.bytes()).buffer; } @@ -488,11 +501,17 @@ export class MultipartPart { this.#bodyUsed = true; + let reader = this.#body.getReader(); let chunks: Uint8Array[] = []; - for await (let chunk of readStream(this.#body)) { - chunks.push(chunk); + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + chunks.push(value); } + reader.releaseLock(); + return concatChunks(chunks); } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 0405a5eb564..f909f561300 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,3 +1,11 @@ +export function isIterable(value: unknown): value is Iterable { + return typeof value === 'object' && value != null && Symbol.iterator in value; +} + +export function isAsyncIterable(value: unknown): value is AsyncIterable { + return typeof value === 'object' && value != null && Symbol.asyncIterator in value; +} + export function concatChunks(chunks: Uint8Array[]): Uint8Array { if (chunks.length === 1) return chunks[0]; @@ -16,21 +24,3 @@ export function concatChunks(chunks: Uint8Array[]): Uint8Array { return result; } - -export function isIterable(value: unknown): value is Iterable { - return typeof value === 'object' && value != null && Symbol.iterator in value; -} - -export async function* readStream(stream: ReadableStream): AsyncGenerator { - let reader = stream.getReader(); - - try { - while (true) { - const { done, value } = await reader.read(); - if (done) break; - yield value; - } - } finally { - reader.releaseLock(); - } -} From 6161bd02e429002176e19bd0893f5e6564ee2fca Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 3 Aug 2024 09:16:36 -0700 Subject: [PATCH 150/730] Small find optimization --- src/lib/multipart.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 220eab6d505..7634177f26a 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -417,26 +417,22 @@ function find( ): number { let headLength = head.length; let totalLength = headLength + tail.length; - let i = pattern.length - 1; - - function byteAt(index: number) { - return index < headLength ? head[index] : tail[index - headLength]; - } + let patternLength = pattern.length; + let i = patternLength - 1; while (i < totalLength) { - let j = pattern.length - 1; - let k = i; + let j = patternLength - 1; - while (j >= 0 && byteAt(k) === pattern[j]) { + while (j >= 0 && (i < headLength ? head[i] : tail[i - headLength]) === pattern[j]) { j--; - k--; + i--; } if (j === -1) { - return k + 1; + return i + 1; } - i += skipTable[byteAt(i)]; + i += skipTable[i < headLength ? head[i] : tail[i - headLength]]; } return -1; // Not found From e3ec05980c89c3a6d9696b1d2d3a2b8dbd3e9af8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 3 Aug 2024 10:13:49 -0700 Subject: [PATCH 151/730] Version 0.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 02cf6f08217..2a70c7c3f5b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.1.1", + "version": "0.2.0", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "license": "MIT", From e23e52015f58f28d5ffc269ceab33e0559660808 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 3 Aug 2024 11:21:34 -0700 Subject: [PATCH 152/730] Remove deno from benchmark --- bench/package.json | 5 +- bench/runner.ts | 20 +-- deno.json | 3 - deno.lock | 340 --------------------------------------------- package.json | 5 +- pnpm-lock.yaml | 10 +- 6 files changed, 20 insertions(+), 363 deletions(-) delete mode 100644 deno.json delete mode 100644 deno.lock diff --git a/bench/package.json b/bench/package.json index 88a27c20e45..4595dcf85c0 100644 --- a/bench/package.json +++ b/bench/package.json @@ -5,7 +5,10 @@ "dependencies": { "@fastify/busboy": "^3.0.0", "@mjackson/multipart-parser": "workspace:*", - "@types/busboy": "^1.5.4", "busboy": "^1.6.0" + }, + "devDependencies": { + "@types/bun": "^1.1.6", + "@types/busboy": "^1.5.4" } } diff --git a/bench/runner.ts b/bench/runner.ts index 0fd924e4462..dcb890efb77 100644 --- a/bench/runner.ts +++ b/bench/runner.ts @@ -13,13 +13,6 @@ const benchmarks = [ { name: '5 large files', message: messages.fiveLargeFiles }, ]; -function getMeanAndStdDev(measurements: number[]): string { - let mean = measurements.reduce((a, b) => a + b, 0) / measurements.length; - let variance = measurements.reduce((a, b) => a + (b - mean) ** 2, 0) / measurements.length; - let stdDev = Math.sqrt(variance); - return mean.toFixed(2) + ' ms ± ' + stdDev.toFixed(2); -} - interface Parser { parse(message: messages.MultipartMessage): Promise; } @@ -42,6 +35,13 @@ async function runParserBenchmarks( return results; } +function getMeanAndStdDev(measurements: number[]): string { + let mean = measurements.reduce((a, b) => a + b, 0) / measurements.length; + let variance = measurements.reduce((a, b) => a + (b - mean) ** 2, 0) / measurements.length; + let stdDev = Math.sqrt(variance); + return mean.toFixed(2) + ' ms ± ' + stdDev.toFixed(2); +} + interface BenchmarkResults { [parserName: string]: { [testName: string]: string; @@ -69,14 +69,8 @@ function printResults(results: BenchmarkResults) { console.log(`CPU: ${os.cpus()[0].model}`); console.log(`Date: ${new Date().toLocaleString()}`); - // @ts-expect-error - const Bun = globalThis.Bun; - // @ts-expect-error - const Deno = globalThis.Deno; if (typeof Bun !== 'undefined') { console.log(`Bun ${Bun.version}`); - } else if (typeof Deno !== 'undefined') { - console.log(`Deno ${Deno.version.deno}`); } else { console.log(`Node.js ${process.version}`); } diff --git a/deno.json b/deno.json deleted file mode 100644 index 5317e28d918..00000000000 --- a/deno.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "workspace": ["./bench"] -} diff --git a/deno.lock b/deno.lock deleted file mode 100644 index 0f1a48ad606..00000000000 --- a/deno.lock +++ /dev/null @@ -1,340 +0,0 @@ -{ - "version": "3", - "packages": { - "specifiers": { - "npm:@fastify/busboy@^3.0.0": "npm:@fastify/busboy@3.0.0", - "npm:@types/busboy@^1.5.4": "npm:@types/busboy@1.5.4", - "npm:@types/node@^20.14.10": "npm:@types/node@20.14.13", - "npm:busboy@^1.6.0": "npm:busboy@1.6.0", - "npm:fetch-super-headers@^0.4.1": "npm:fetch-super-headers@0.4.1", - "npm:prettier@^3.3.3": "npm:prettier@3.3.3", - "npm:tsimp@^2.0.11": "npm:tsimp@2.0.11_typescript@5.5.4", - "npm:typescript@^5.5.3": "npm:typescript@5.5.4" - }, - "npm": { - "@fastify/busboy@3.0.0": { - "integrity": "sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==", - "dependencies": {} - }, - "@isaacs/cached@1.0.1": { - "integrity": "sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==", - "dependencies": { - "@isaacs/catcher": "@isaacs/catcher@1.0.4" - } - }, - "@isaacs/catcher@1.0.4": { - "integrity": "sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA==", - "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" - } - }, - "@pkgjs/parseargs@0.11.0": { - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dependencies": {} - }, - "@types/busboy@1.5.4": { - "integrity": "sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==", - "dependencies": { - "@types/node": "@types/node@18.16.19" - } - }, - "@types/node@18.16.19": { - "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==", - "dependencies": {} - }, - "@types/node@20.14.13": { - "integrity": "sha512-+bHoGiZb8UiQ0+WEtmph2IWQCjIqg8MDZMAV+ppRRhUZnquF5mQkP/9vpSwJClEiSM/C7fZZExPzfU0vJTyp8w==", - "dependencies": { - "undici-types": "undici-types@5.26.5" - } - }, - "ansi-regex@5.0.1": { - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dependencies": {} - }, - "ansi-regex@6.0.1": { - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dependencies": {} - }, - "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": {} - }, - "balanced-match@1.0.2": { - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dependencies": {} - }, - "brace-expansion@2.0.1": { - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "balanced-match@1.0.2" - } - }, - "busboy@1.6.0": { - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "streamsearch@1.1.0" - } - }, - "color-convert@2.0.1": { - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "color-name@1.1.4" - } - }, - "color-name@1.1.4": { - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dependencies": {} - }, - "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" - } - }, - "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": {} - }, - "fetch-super-headers@0.4.1": { - "integrity": "sha512-jXB/p3m6iMeDFhHpJ56BgqrvoDIiyueNPF39twy2N63DMcme0imKhGoEZH8AAbnplnggU9OdUs9eFFPZxPULFA==", - "dependencies": {} - }, - "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" - } - }, - "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" - } - }, - "is-fullwidth-code-point@3.0.0": { - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dependencies": {} - }, - "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" - } - }, - "lru-cache@10.4.3": { - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dependencies": {} - }, - "minimatch@9.0.5": { - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dependencies": { - "brace-expansion": "brace-expansion@2.0.1" - } - }, - "minipass@7.1.2": { - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dependencies": {} - }, - "mkdirp@3.0.1": { - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "dependencies": {} - }, - "package-json-from-dist@1.0.0": { - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", - "dependencies": {} - }, - "path-key@3.1.1": { - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dependencies": {} - }, - "path-scurry@1.11.1": { - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dependencies": { - "lru-cache": "lru-cache@10.4.3", - "minipass": "minipass@7.1.2" - } - }, - "pirates@4.0.6": { - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dependencies": {} - }, - "prettier@3.3.3": { - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", - "dependencies": {} - }, - "rimraf@5.0.10": { - "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", - "dependencies": { - "glob": "glob@10.4.5" - } - }, - "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": {} - }, - "signal-exit@4.1.0": { - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dependencies": {} - }, - "sock-daemon@1.4.2": { - "integrity": "sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg==", - "dependencies": { - "rimraf": "rimraf@5.0.10", - "signal-exit": "signal-exit@4.1.0", - "socket-post-message": "socket-post-message@1.0.3" - } - }, - "socket-post-message@1.0.3": { - "integrity": "sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==", - "dependencies": {} - }, - "streamsearch@1.1.0": { - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "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" - } - }, - "tsimp@2.0.11_typescript@5.5.4": { - "integrity": "sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==", - "dependencies": { - "@isaacs/cached": "@isaacs/cached@1.0.1", - "@isaacs/catcher": "@isaacs/catcher@1.0.4", - "foreground-child": "foreground-child@3.2.1", - "mkdirp": "mkdirp@3.0.1", - "pirates": "pirates@4.0.6", - "rimraf": "rimraf@5.0.10", - "signal-exit": "signal-exit@4.1.0", - "sock-daemon": "sock-daemon@1.4.2", - "typescript": "typescript@5.5.4", - "walk-up-path": "walk-up-path@3.0.1" - } - }, - "typescript@5.5.4": { - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", - "dependencies": {} - }, - "undici-types@5.26.5": { - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dependencies": {} - }, - "walk-up-path@3.0.1": { - "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==", - "dependencies": {} - }, - "which@2.0.2": { - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "isexe@2.0.0" - } - }, - "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" - } - } - } - }, - "remote": {}, - "workspace": { - "packageJson": { - "dependencies": [ - "npm:@types/node@^20.14.10", - "npm:fetch-super-headers@^0.4.1", - "npm:prettier@^3.3.3", - "npm:tsimp@^2.0.11", - "npm:typescript@^5.5.3" - ] - }, - "members": { - "bench": { - "packageJson": { - "dependencies": [ - "npm:@fastify/busboy@^3.0.0", - "npm:@types/busboy@^1.5.4", - "npm:busboy@^1.6.0" - ] - } - } - } - } -} diff --git a/package.json b/package.json index 2a70c7c3f5b..0cff04a38db 100644 --- a/package.json +++ b/package.json @@ -26,10 +26,9 @@ }, "scripts": { "clean": "git clean -fdX .", - "bench": "pnpm run bench:node && pnpm run bench:bun && pnpm run bench:deno", - "bench:bun": "bun run ./bench/runner.ts", - "bench:deno": "deno --unstable-sloppy-imports run --allow-sys ./bench/runner.ts", + "bench": "pnpm run bench:node && pnpm run bench:bun", "bench:node": "node --import tsimp/import ./bench/runner.ts", + "bench:bun": "bun run ./bench/runner.ts", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", "prepare": "npm run build", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d4e22050137..d734408cb45 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,12 +33,16 @@ importers: '@mjackson/multipart-parser': specifier: workspace:* version: link:.. - '@types/busboy': - specifier: ^1.5.4 - version: 1.5.4 busboy: specifier: ^1.6.0 version: 1.6.0 + devDependencies: + '@types/bun': + specifier: ^1.1.6 + version: 1.1.6 + '@types/busboy': + specifier: ^1.5.4 + version: 1.5.4 examples/bun: dependencies: From 1d736a2bb789ca80d95a0466a6a5f4315f0081ea Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 3 Aug 2024 11:22:14 -0700 Subject: [PATCH 153/730] Revert "Small find optimization" This reverts commit 6161bd02e429002176e19bd0893f5e6564ee2fca. --- src/lib/multipart.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 7634177f26a..220eab6d505 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -417,22 +417,26 @@ function find( ): number { let headLength = head.length; let totalLength = headLength + tail.length; - let patternLength = pattern.length; - let i = patternLength - 1; + let i = pattern.length - 1; + + function byteAt(index: number) { + return index < headLength ? head[index] : tail[index - headLength]; + } while (i < totalLength) { - let j = patternLength - 1; + let j = pattern.length - 1; + let k = i; - while (j >= 0 && (i < headLength ? head[i] : tail[i - headLength]) === pattern[j]) { + while (j >= 0 && byteAt(k) === pattern[j]) { j--; - i--; + k--; } if (j === -1) { - return i + 1; + return k + 1; } - i += skipTable[i < headLength ? head[i] : tail[i - headLength]]; + i += skipTable[byteAt(i)]; } return -1; // Not found From 54d4b548c22ff4200d51ec9a4c717b0723e27ad7 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 3 Aug 2024 11:34:04 -0700 Subject: [PATCH 154/730] Remove byteAt function calls --- src/lib/multipart.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 220eab6d505..0b9c127d78e 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -419,15 +419,11 @@ function find( let totalLength = headLength + tail.length; let i = pattern.length - 1; - function byteAt(index: number) { - return index < headLength ? head[index] : tail[index - headLength]; - } - while (i < totalLength) { let j = pattern.length - 1; let k = i; - while (j >= 0 && byteAt(k) === pattern[j]) { + while (j >= 0 && (k < headLength ? head[k] : tail[k - headLength]) === pattern[j]) { j--; k--; } @@ -436,7 +432,7 @@ function find( return k + 1; } - i += skipTable[byteAt(i)]; + i += skipTable[i < headLength ? head[i] : tail[i - headLength]]; } return -1; // Not found From e9504b81fdea581dd6291d837ce0e168b6517add Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 3 Aug 2024 11:38:10 -0700 Subject: [PATCH 155/730] Version 0.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0cff04a38db..cd098807afb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.2.0", + "version": "0.2.1", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "license": "MIT", From f522ae159e6baf197523bc58c5f11fd80bc3aceb Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 3 Aug 2024 11:42:46 -0700 Subject: [PATCH 156/730] Update README --- README.md | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 2d121867ece..fe9af336df0 100644 --- a/README.md +++ b/README.md @@ -135,47 +135,35 @@ Important: Benchmarking can be tricky, and results vary greatly depending on pla The results of running the benchmarks on my laptop: ``` +> @mjackson/multipart-parser@0.2.1 bench:node /Users/michael/Projects/multipart-parser +> node --import tsimp/import ./bench/runner.ts + Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/2/2024, 2:40:59 PM +Date: 8/3/2024, 11:39:34 AM Node.js v20.15.1 ┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ multipart-parser │ '0.01 ms ± 0.03' │ '1.33 ms ± 0.07' │ '0.33 ms ± 0.14' │ '13.28 ms ± 0.33' │ -│ busboy │ '0.03 ms ± 0.07' │ '3.11 ms ± 1.26' │ '0.22 ms ± 0.03' │ '43.30 ms ± 2.25' │ -│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.12 ms ± 0.22' │ '0.39 ms ± 0.03' │ '11.28 ms ± 0.36' │ +│ multipart-parser │ '0.01 ms ± 0.03' │ '1.11 ms ± 0.04' │ '0.32 ms ± 0.13' │ '10.94 ms ± 0.70' │ +│ busboy │ '0.03 ms ± 0.07' │ '2.84 ms ± 0.06' │ '0.22 ms ± 0.02' │ '43.24 ms ± 2.45' │ +│ @fastify/busboy │ '0.03 ms ± 0.06' │ '1.09 ms ± 0.07' │ '0.38 ms ± 0.03' │ '10.99 ms ± 0.15' │ └──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ -> @mjackson/multipart-parser@0.1.1 bench:bun /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.2.1 bench:bun /Users/michael/Projects/multipart-parser > bun run ./bench/runner.ts Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/2/2024, 2:43:05 PM +Date: 8/3/2024, 11:41:38 AM Bun 1.1.21 ┌──────────────────┬────────────────┬────────────────┬─────────────────┬─────────────────┐ │ │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼────────────────┼────────────────┼─────────────────┼─────────────────┤ -│ multipart-parser │ 0.01 ms ± 0.05 │ 1.14 ms ± 0.16 │ 0.13 ms ± 0.07 │ 11.49 ms ± 1.61 │ -│ busboy │ 0.03 ms ± 0.13 │ 3.32 ms ± 0.13 │ 0.33 ms ± 0.14 │ 33.31 ms ± 3.08 │ -│ @fastify/busboy │ 0.03 ms ± 0.13 │ 6.71 ms ± 0.13 │ 0.60 ms ± 0.14 │ 67.62 ms ± 3.66 │ +│ multipart-parser │ 0.01 ms ± 0.04 │ 1.08 ms ± 0.07 │ 0.14 ms ± 0.13 │ 10.55 ms ± 0.26 │ +│ busboy │ 0.02 ms ± 0.07 │ 3.29 ms ± 0.12 │ 0.34 ms ± 0.14 │ 33.07 ms ± 1.87 │ +│ @fastify/busboy │ 0.03 ms ± 0.07 │ 6.64 ms ± 0.13 │ 0.60 ms ± 0.13 │ 67.54 ms ± 4.17 │ └──────────────────┴────────────────┴────────────────┴─────────────────┴─────────────────┘ - -> @mjackson/multipart-parser@0.1.1 bench:deno /Users/michael/Projects/multipart-parser -> deno --unstable-sloppy-imports run --allow-sys ./bench/runner.ts - -Platform: Darwin (23.5.0) -CPU: Apple M2 Pro -Date: 8/2/2024, 2:45:58 PM -Deno 1.45.5 -┌──────────────────┬──────────────────┬───────────────────┬──────────────────┬────────────────────┐ -│ (idx) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ -├──────────────────┼──────────────────┼───────────────────┼──────────────────┼────────────────────┤ -│ multipart-parser │ "0.02 ms ± 0.20" │ "1.09 ms ± 1.00" │ "0.09 ms ± 0.42" │ "10.95 ms ± 1.81" │ -│ busboy │ "0.04 ms ± 0.28" │ "2.88 ms ± 0.99" │ "0.29 ms ± 0.70" │ "29.23 ms ± 2.58" │ -│ @fastify/busboy │ "0.04 ms ± 0.30" │ "11.55 ms ± 0.89" │ "0.74 ms ± 0.97" │ "115.39 ms ± 6.50" │ -└──────────────────┴──────────────────┴───────────────────┴──────────────────┴────────────────────┘ ``` I'd encourage you to run the benchmarks yourself. You'll probably get different results! From 195f49a2b3439923f0fd13743f19b1658de79e31 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 3 Aug 2024 13:51:10 -0700 Subject: [PATCH 157/730] Re-order types --- src/lib/multipart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 0b9c127d78e..31a2bc3cccc 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -48,7 +48,7 @@ export async function* parseMultipartRequest( * building a web server, consider using `parseMultipartRequest(request)` instead. */ export async function* parseMultipart( - data: Uint8Array | Iterable | ReadableStream | AsyncIterable, + data: ReadableStream | Uint8Array | Iterable | AsyncIterable, boundary: string, options?: MultipartParserOptions, ): AsyncGenerator { From 2032f00e51c14b40a5f26d0a88a99fb84a160d1e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 3 Aug 2024 14:04:36 -0700 Subject: [PATCH 158/730] Add link to CF workers docs --- examples/cf-workers/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cf-workers/README.md b/examples/cf-workers/README.md index c407ebeb578..1371fee230d 100644 --- a/examples/cf-workers/README.md +++ b/examples/cf-workers/README.md @@ -2,4 +2,4 @@ This is a demo of how you can upload a file directly to [a Cloudflare worker](https://developers.cloudflare.com/workers/) and store it in R2. -Notice: `multipart-parser` doesn't use any node-specific APIs, so this demo does not rely on Cloudflare Workers' [`nodejs_compat` flag] in order to run. +Notice: `multipart-parser` doesn't use any node-specific APIs, so this demo does not rely on Cloudflare Workers' [`nodejs_compat` flag](https://developers.cloudflare.com/workers/runtime-apis/nodejs/) in order to run. From 9391972d32397de2194b73c46af554784fcb88b8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 3 Aug 2024 14:14:52 -0700 Subject: [PATCH 159/730] Small test re-org --- src/lib/multipart.node.spec.ts | 6 ++++-- src/lib/multipart.spec.ts | 8 ++++++-- src/test/utils.ts | 4 +--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/lib/multipart.node.spec.ts b/src/lib/multipart.node.spec.ts index 46e489facd3..245dde314dd 100644 --- a/src/lib/multipart.node.spec.ts +++ b/src/lib/multipart.node.spec.ts @@ -5,8 +5,6 @@ import { readFixture } from '../test/fixtures.js'; import { createMultipartMockRequest } from '../test/utils.node.js'; import { parseMultipartRequest } from './multipart.node.js'; -const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); - describe('parseMultipartRequest (node)', () => { let boundary = 'boundary123'; @@ -37,6 +35,8 @@ describe('parseMultipartRequest (node)', () => { }); it('parses large file uploads correctly', async () => { + const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); + let request = createMultipartMockRequest(boundary, { file1: { filename: 'tesla.jpg', @@ -58,6 +58,8 @@ describe('parseMultipartRequest (node)', () => { }); it('allows buffering part contents while parsing', async () => { + const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); + let request = createMultipartMockRequest(boundary, { file1: { filename: 'tesla.jpg', diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 40d4e2d8943..53f31e11825 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -2,7 +2,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; import { readFixture } from '../test/fixtures.js'; -import { CRLF, createMockRequest, createMultipartMockRequest } from '../test/utils.js'; +import { createMockRequest, createMultipartMockRequest } from '../test/utils.js'; import { isMultipartRequest, parseMultipartRequest, @@ -10,7 +10,7 @@ import { getMultipartBoundary, } from './multipart.js'; -const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); +const CRLF = '\r\n'; describe('getMultipartBoundary', async () => { it('returns the boundary from the Content-Type header', async () => { @@ -163,6 +163,8 @@ describe('parseMultipartRequest', async () => { }); it('allows buffering part contents while parsing', async () => { + const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); + let request = createMultipartMockRequest(boundary, { file1: { filename: 'tesla.jpg', @@ -188,6 +190,8 @@ describe('parseMultipartRequest', async () => { }); it('parses large file uploads correctly', async () => { + const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); + let request = createMultipartMockRequest(boundary, { file1: { filename: 'tesla.jpg', diff --git a/src/test/utils.ts b/src/test/utils.ts index dcfead044c1..9926d7fb5e9 100644 --- a/src/test/utils.ts +++ b/src/test/utils.ts @@ -2,8 +2,6 @@ import { ContentDisposition, ContentType, SuperHeaders } from 'fetch-super-heade import { concatChunks } from '../lib/utils.js'; -export const CRLF = '\r\n'; - export function createReadableStream( content: string | Uint8Array, chunkSize = 64 * 1024, @@ -58,7 +56,7 @@ export function createMultipartBody( } function pushLine(line = '') { - pushString(line + CRLF); + pushString(line + '\r\n'); } if (parts) { From cc4475d6fd07bf2a12fadd60299fea52eb58d696 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 3 Aug 2024 14:18:15 -0700 Subject: [PATCH 160/730] Fix small type error in node tests --- src/test/utils.node.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/utils.node.ts b/src/test/utils.node.ts index 683947aadc5..ddf8321e4d4 100644 --- a/src/test/utils.node.ts +++ b/src/test/utils.node.ts @@ -3,13 +3,13 @@ import * as stream from 'node:stream'; import { PartValue, createMultipartBody } from './utils.js'; -export function createReadable(content: string, chunkSize = 16 * 1024): stream.Readable { +export function createReadable(content: Uint8Array, chunkSize = 16 * 1024): stream.Readable { let i = 0; return new stream.Readable({ read() { if (i < content.length) { - this.push(Buffer.from(content.slice(i, i + chunkSize))); + this.push(content.subarray(i, i + chunkSize)); i += chunkSize; } else { this.push(null); @@ -20,7 +20,7 @@ export function createReadable(content: string, chunkSize = 16 * 1024): stream.R export function createMultipartMockRequest( boundary: string, - parts?: { [name: string]: PartValue } + parts?: { [name: string]: PartValue }, ): http.IncomingMessage { let body = createMultipartBody(boundary, parts); From 0356d1b0f570ce77b9ee0d2d7fdc93ae5918ea4f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 3 Aug 2024 16:43:02 -0700 Subject: [PATCH 161/730] Add Deno to benchmarks --- README.md | 23 +++++++++++++++++++---- bench/globals.d.ts | 5 +++++ bench/runner.ts | 2 ++ package.json | 5 +++-- 4 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 bench/globals.d.ts diff --git a/README.md b/README.md index fe9af336df0..848c834f178 100644 --- a/README.md +++ b/README.md @@ -155,15 +155,30 @@ Node.js v20.15.1 Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/3/2024, 11:41:38 AM +Date: 8/3/2024, 4:37:33 PM Bun 1.1.21 ┌──────────────────┬────────────────┬────────────────┬─────────────────┬─────────────────┐ │ │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼────────────────┼────────────────┼─────────────────┼─────────────────┤ -│ multipart-parser │ 0.01 ms ± 0.04 │ 1.08 ms ± 0.07 │ 0.14 ms ± 0.13 │ 10.55 ms ± 0.26 │ -│ busboy │ 0.02 ms ± 0.07 │ 3.29 ms ± 0.12 │ 0.34 ms ± 0.14 │ 33.07 ms ± 1.87 │ -│ @fastify/busboy │ 0.03 ms ± 0.07 │ 6.64 ms ± 0.13 │ 0.60 ms ± 0.13 │ 67.54 ms ± 4.17 │ +│ multipart-parser │ 0.01 ms ± 0.04 │ 1.08 ms ± 0.09 │ 0.14 ms ± 0.13 │ 10.79 ms ± 1.92 │ +│ busboy │ 0.02 ms ± 0.07 │ 3.30 ms ± 0.30 │ 0.33 ms ± 0.16 │ 33.09 ms ± 2.06 │ +│ @fastify/busboy │ 0.03 ms ± 0.09 │ 6.67 ms ± 0.31 │ 0.60 ms ± 0.14 │ 67.18 ms ± 3.58 │ └──────────────────┴────────────────┴────────────────┴─────────────────┴─────────────────┘ + +> @mjackson/multipart-parser@0.2.1 bench:deno /Users/michael/Projects/multipart-parser +> deno --unstable-byonm --unstable-sloppy-imports run --allow-sys ./bench/runner.ts + +Platform: Darwin (23.5.0) +CPU: Apple M2 Pro +Date: 8/3/2024, 4:40:26 PM +Deno 1.45.5 +┌──────────────────┬──────────────────┬───────────────────┬──────────────────┬────────────────────┐ +│ (idx) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ +├──────────────────┼──────────────────┼───────────────────┼──────────────────┼────────────────────┤ +│ multipart-parser │ "0.02 ms ± 0.19" │ "1.12 ms ± 0.99" │ "0.10 ms ± 0.44" │ "11.08 ms ± 1.03" │ +│ busboy │ "0.04 ms ± 0.27" │ "2.88 ms ± 1.00" │ "0.28 ms ± 0.69" │ "29.03 ms ± 2.15" │ +│ @fastify/busboy │ "0.04 ms ± 0.29" │ "11.61 ms ± 2.77" │ "0.75 ms ± 0.98" │ "115.50 ms ± 4.23" │ +└──────────────────┴──────────────────┴───────────────────┴──────────────────┴────────────────────┘ ``` I'd encourage you to run the benchmarks yourself. You'll probably get different results! diff --git a/bench/globals.d.ts b/bench/globals.d.ts new file mode 100644 index 00000000000..4c75c2fd6ef --- /dev/null +++ b/bench/globals.d.ts @@ -0,0 +1,5 @@ +declare global { + var Deno: { version: { deno: string } } | undefined; +} + +export {}; diff --git a/bench/runner.ts b/bench/runner.ts index dcb890efb77..5f102c4fa66 100644 --- a/bench/runner.ts +++ b/bench/runner.ts @@ -71,6 +71,8 @@ function printResults(results: BenchmarkResults) { if (typeof Bun !== 'undefined') { console.log(`Bun ${Bun.version}`); + } else if (typeof Deno !== 'undefined') { + console.log(`Deno ${Deno.version.deno}`); } else { console.log(`Node.js ${process.version}`); } diff --git a/package.json b/package.json index cd098807afb..887a2f07c6b 100644 --- a/package.json +++ b/package.json @@ -26,9 +26,10 @@ }, "scripts": { "clean": "git clean -fdX .", - "bench": "pnpm run bench:node && pnpm run bench:bun", - "bench:node": "node --import tsimp/import ./bench/runner.ts", + "bench": "pnpm run bench:node && pnpm run bench:bun && pnpm run bench:deno", "bench:bun": "bun run ./bench/runner.ts", + "bench:deno": "deno --unstable-byonm --unstable-sloppy-imports run --allow-sys ./bench/runner.ts", + "bench:node": "node --import tsimp/import ./bench/runner.ts", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", "prepare": "npm run build", From 8539b558ab990c27382ea1d7cf1c7ddd6162f656 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 01:09:53 -0700 Subject: [PATCH 162/730] Update some doc comments --- src/lib/multipart.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 31a2bc3cccc..6a3ec43e199 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -112,7 +112,7 @@ enum MultipartParserState { } /** - * A parser for `multipart/*` message streams. + * A parser for `multipart/*` HTTP messages. */ export class MultipartParser { boundary: string; @@ -450,7 +450,7 @@ function computeSkipTable(pattern: Uint8Array): Uint8Array { } /** - * A part of a `multipart/*` message. + * A part of a `multipart/*` HTTP message. */ export class MultipartPart { #header: Uint8Array; From 8efdb6d1262873eaacb10a237efd65118a379dce Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 01:18:15 -0700 Subject: [PATCH 163/730] Add tests for finding in buffer --- src/lib/buffer-utils.spec.ts | 76 ++++++++++++++++++++++++++++++++++++ src/lib/buffer-utils.ts | 58 +++++++++++++++++++++++++++ src/lib/multipart.ts | 55 ++++++-------------------- src/lib/utils.ts | 26 ------------ src/test/utils.ts | 4 +- 5 files changed, 147 insertions(+), 72 deletions(-) create mode 100644 src/lib/buffer-utils.spec.ts create mode 100644 src/lib/buffer-utils.ts delete mode 100644 src/lib/utils.ts diff --git a/src/lib/buffer-utils.spec.ts b/src/lib/buffer-utils.spec.ts new file mode 100644 index 00000000000..d982c4c9885 --- /dev/null +++ b/src/lib/buffer-utils.spec.ts @@ -0,0 +1,76 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { indexOf } from './buffer-utils.js'; + +describe('indexOf', () => { + it('finds the needle at the beginning of the head', () => { + let head = new Uint8Array([1, 2, 3]); + let tail = new Uint8Array([4, 5, 6]); + let needle = new Uint8Array([1, 2]); + assert.equal(indexOf(head, tail, needle), 0); + }); + + it('finds the needle at the end of the head', () => { + let head = new Uint8Array([1, 2, 3]); + let tail = new Uint8Array([4, 5, 6]); + let needle = new Uint8Array([2, 3]); + assert.equal(indexOf(head, tail, needle), 1); + }); + + it('finds the needle split between head and tail', () => { + let head = new Uint8Array([1, 2, 3]); + let tail = new Uint8Array([4, 5, 6]); + assert.equal(indexOf(head, tail, new Uint8Array([2, 3, 4])), 1); + assert.equal(indexOf(head, tail, new Uint8Array([3, 4, 5])), 2); + }); + + it('finds the needle at the beginning of the tail', () => { + let head = new Uint8Array([1, 2, 3]); + let tail = new Uint8Array([4, 5, 6]); + let needle = new Uint8Array([4, 5]); + assert.equal(indexOf(head, tail, needle), 3); + }); + + it('finds the needle at the end of the tail', () => { + let head = new Uint8Array([1, 2, 3]); + let tail = new Uint8Array([4, 5, 6]); + let needle = new Uint8Array([5, 6]); + assert.equal(indexOf(head, tail, needle), 4); + }); + + it('returns -1 when the needle is not found', () => { + let head = new Uint8Array([1, 2, 3]); + let tail = new Uint8Array([4, 5, 6]); + let needle = new Uint8Array([2, 4]); + assert.equal(indexOf(head, tail, needle), -1); + }); + + it('handles empty head correctly', () => { + let head = new Uint8Array([]); + let tail = new Uint8Array([1, 2, 3]); + let needle = new Uint8Array([1, 2]); + assert.equal(indexOf(head, tail, needle), 0); + }); + + it('handles needle equal to the total length', () => { + let head = new Uint8Array([1, 2, 3]); + let tail = new Uint8Array([4, 5, 6]); + let needle = new Uint8Array([1, 2, 3, 4, 5, 6]); + assert.equal(indexOf(head, tail, needle), 0); + }); + + it('handles needle longer than the total length', () => { + let head = new Uint8Array([1, 2, 3]); + let tail = new Uint8Array([4, 5, 6]); + let needle = new Uint8Array([1, 2, 3, 4, 5, 6, 7]); + assert.equal(indexOf(head, tail, needle), -1); + }); + + it('handles repeated patterns correctly', () => { + let head = new Uint8Array([1, 2, 1, 2]); + let tail = new Uint8Array([1, 2, 1, 2]); + let needle = new Uint8Array([2, 1, 2, 1]); + assert.equal(indexOf(head, tail, needle), 1); + }); +}); diff --git a/src/lib/buffer-utils.ts b/src/lib/buffer-utils.ts new file mode 100644 index 00000000000..31e6dc5c3d2 --- /dev/null +++ b/src/lib/buffer-utils.ts @@ -0,0 +1,58 @@ +export function concat(chunks: Uint8Array[]): Uint8Array { + if (chunks.length === 1) return chunks[0]; + + let length = 0; + for (let chunk of chunks) { + length += chunk.length; + } + + let result = new Uint8Array(length); + let offset = 0; + + for (let chunk of chunks) { + result.set(chunk, offset); + offset += chunk.length; + } + + return result; +} + +export function indexOf( + head: Uint8Array, + tail: Uint8Array, + needle: Uint8Array, + skipTable = computeSkipTable(needle), +): number { + let headLength = head.length; + let totalLength = headLength + tail.length; + let i = needle.length - 1; + + while (i < totalLength) { + let j = needle.length - 1; + let k = i; + + while (j >= 0 && (k < headLength ? head[k] : tail[k - headLength]) === needle[j]) { + j--; + k--; + } + + if (j === -1) { + return k + 1; + } + + i += skipTable[i < headLength ? head[i] : tail[i - headLength]]; + } + + return -1; // Not found +} + +export function computeSkipTable(needle: Uint8Array): Uint8Array { + let table = new Uint8Array(256).fill(needle.length); + let lastIndex = needle.length - 1; + + for (let i = 0; i < lastIndex; ++i) { + table[needle[i]] = lastIndex - i; + } + + return table; +} diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 6a3ec43e199..64884f77463 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -1,6 +1,6 @@ import { SuperHeaders } from 'fetch-super-headers'; -import { concatChunks, isAsyncIterable, isIterable } from './utils.js'; +import { concat, indexOf, computeSkipTable } from './buffer-utils.js'; /** * Extracts the boundary string from a `multipart/*` content type. @@ -228,7 +228,7 @@ export class MultipartParser { return []; } - let boundaryIndex = find( + let boundaryIndex = indexOf( this.#buffer, this.#chunk, this.#boundaryArray, @@ -276,7 +276,7 @@ export class MultipartParser { break; } - let headerEndIndex = find( + let headerEndIndex = indexOf( this.#buffer, this.#chunk, DOUBLE_NEWLINE, @@ -289,7 +289,7 @@ export class MultipartParser { ); } - let header = concatChunks(this.#read(headerEndIndex)); + let header = concat(this.#read(headerEndIndex)); this.#skip(4); // Skip \r\n\r\n let body = new ReadableStream({ @@ -309,7 +309,7 @@ export class MultipartParser { break; } - let boundaryIndex = find( + let boundaryIndex = indexOf( this.#buffer, this.#chunk, this.#boundaryArray, @@ -385,8 +385,7 @@ export class MultipartParser { #save(): void { if (this.#chunk.length === 0) return; - this.#buffer = - this.#buffer.length > 0 ? concatChunks([this.#buffer, this.#chunk]) : this.#chunk; + this.#buffer = this.#buffer.length > 0 ? concat([this.#buffer, this.#chunk]) : this.#chunk; } #writeBody(chunks: Uint8Array[]): void { @@ -409,44 +408,12 @@ export class MultipartParser { } } -function find( - head: Uint8Array, - tail: Uint8Array, - pattern: Uint8Array, - skipTable = computeSkipTable(pattern), -): number { - let headLength = head.length; - let totalLength = headLength + tail.length; - let i = pattern.length - 1; - - while (i < totalLength) { - let j = pattern.length - 1; - let k = i; - - while (j >= 0 && (k < headLength ? head[k] : tail[k - headLength]) === pattern[j]) { - j--; - k--; - } - - if (j === -1) { - return k + 1; - } - - i += skipTable[i < headLength ? head[i] : tail[i - headLength]]; - } - - return -1; // Not found +function isIterable(value: unknown): value is Iterable { + return typeof value === 'object' && value != null && Symbol.iterator in value; } -function computeSkipTable(pattern: Uint8Array): Uint8Array { - let table = new Uint8Array(256).fill(pattern.length); - let lastIndex = pattern.length - 1; - - for (let i = 0; i < lastIndex; ++i) { - table[pattern[i]] = lastIndex - i; - } - - return table; +function isAsyncIterable(value: unknown): value is AsyncIterable { + return typeof value === 'object' && value != null && Symbol.asyncIterator in value; } /** @@ -508,7 +475,7 @@ export class MultipartPart { reader.releaseLock(); - return concatChunks(chunks); + return concat(chunks); } /** diff --git a/src/lib/utils.ts b/src/lib/utils.ts deleted file mode 100644 index f909f561300..00000000000 --- a/src/lib/utils.ts +++ /dev/null @@ -1,26 +0,0 @@ -export function isIterable(value: unknown): value is Iterable { - return typeof value === 'object' && value != null && Symbol.iterator in value; -} - -export function isAsyncIterable(value: unknown): value is AsyncIterable { - return typeof value === 'object' && value != null && Symbol.asyncIterator in value; -} - -export function concatChunks(chunks: Uint8Array[]): Uint8Array { - if (chunks.length === 1) return chunks[0]; - - let length = 0; - for (let chunk of chunks) { - length += chunk.length; - } - - let result = new Uint8Array(length); - let offset = 0; - - for (let chunk of chunks) { - result.set(chunk, offset); - offset += chunk.length; - } - - return result; -} diff --git a/src/test/utils.ts b/src/test/utils.ts index 9926d7fb5e9..d6a970e8154 100644 --- a/src/test/utils.ts +++ b/src/test/utils.ts @@ -1,6 +1,6 @@ import { ContentDisposition, ContentType, SuperHeaders } from 'fetch-super-headers'; -import { concatChunks } from '../lib/utils.js'; +import { concat } from '../lib/buffer-utils.js'; export function createReadableStream( content: string | Uint8Array, @@ -99,7 +99,7 @@ export function createMultipartBody( pushString(`--${boundary}--`); - return concatChunks(chunks); + return concat(chunks); } export function createMultipartMockRequest( From caaa1bf153b18e4f2c5cc833d6f69a425ca78a3f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 13:10:48 -0700 Subject: [PATCH 164/730] Small optimization for parsing large file uploads --- src/lib/buffer-utils.spec.ts | 50 +++++++++++++++++++++++-------- src/lib/buffer-utils.ts | 58 +++++++++++++++++++++++++++++------- src/lib/multipart.ts | 8 ++--- 3 files changed, 89 insertions(+), 27 deletions(-) diff --git a/src/lib/buffer-utils.spec.ts b/src/lib/buffer-utils.spec.ts index d982c4c9885..32b1734bab9 100644 --- a/src/lib/buffer-utils.spec.ts +++ b/src/lib/buffer-utils.spec.ts @@ -1,76 +1,102 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { indexOf } from './buffer-utils.js'; +import { indexOf, combinedIndexOf } from './buffer-utils.js'; describe('indexOf', () => { + it('finds the needle at the beginning', () => { + let haystack = new Uint8Array([1, 2, 3, 4, 5]); + let needle = new Uint8Array([1, 2]); + assert.equal(indexOf(haystack, needle), 0); + }); + + it('finds the needle at the end', () => { + let haystack = new Uint8Array([1, 2, 3, 4, 5]); + let needle = new Uint8Array([4, 5]); + assert.equal(indexOf(haystack, needle), 3); + }); + + it('finds the needle in the middle', () => { + let haystack = new Uint8Array([1, 2, 3, 4, 5]); + let needle = new Uint8Array([2, 3]); + assert.equal(indexOf(haystack, needle), 1); + }); + + it('returns -1 when the needle is not found', () => { + let haystack = new Uint8Array([1, 2, 3, 4, 5]); + let needle = new Uint8Array([2, 4]); + assert.equal(indexOf(haystack, needle), -1); + }); +}); + +describe('combinedIndexOf', () => { it('finds the needle at the beginning of the head', () => { let head = new Uint8Array([1, 2, 3]); let tail = new Uint8Array([4, 5, 6]); let needle = new Uint8Array([1, 2]); - assert.equal(indexOf(head, tail, needle), 0); + assert.equal(combinedIndexOf(head, tail, needle), 0); }); it('finds the needle at the end of the head', () => { let head = new Uint8Array([1, 2, 3]); let tail = new Uint8Array([4, 5, 6]); let needle = new Uint8Array([2, 3]); - assert.equal(indexOf(head, tail, needle), 1); + assert.equal(combinedIndexOf(head, tail, needle), 1); }); it('finds the needle split between head and tail', () => { let head = new Uint8Array([1, 2, 3]); let tail = new Uint8Array([4, 5, 6]); - assert.equal(indexOf(head, tail, new Uint8Array([2, 3, 4])), 1); - assert.equal(indexOf(head, tail, new Uint8Array([3, 4, 5])), 2); + assert.equal(combinedIndexOf(head, tail, new Uint8Array([2, 3, 4])), 1); + assert.equal(combinedIndexOf(head, tail, new Uint8Array([3, 4, 5])), 2); }); it('finds the needle at the beginning of the tail', () => { let head = new Uint8Array([1, 2, 3]); let tail = new Uint8Array([4, 5, 6]); let needle = new Uint8Array([4, 5]); - assert.equal(indexOf(head, tail, needle), 3); + assert.equal(combinedIndexOf(head, tail, needle), 3); }); it('finds the needle at the end of the tail', () => { let head = new Uint8Array([1, 2, 3]); let tail = new Uint8Array([4, 5, 6]); let needle = new Uint8Array([5, 6]); - assert.equal(indexOf(head, tail, needle), 4); + assert.equal(combinedIndexOf(head, tail, needle), 4); }); it('returns -1 when the needle is not found', () => { let head = new Uint8Array([1, 2, 3]); let tail = new Uint8Array([4, 5, 6]); let needle = new Uint8Array([2, 4]); - assert.equal(indexOf(head, tail, needle), -1); + assert.equal(combinedIndexOf(head, tail, needle), -1); }); it('handles empty head correctly', () => { let head = new Uint8Array([]); let tail = new Uint8Array([1, 2, 3]); let needle = new Uint8Array([1, 2]); - assert.equal(indexOf(head, tail, needle), 0); + assert.equal(combinedIndexOf(head, tail, needle), 0); }); it('handles needle equal to the total length', () => { let head = new Uint8Array([1, 2, 3]); let tail = new Uint8Array([4, 5, 6]); let needle = new Uint8Array([1, 2, 3, 4, 5, 6]); - assert.equal(indexOf(head, tail, needle), 0); + assert.equal(combinedIndexOf(head, tail, needle), 0); }); it('handles needle longer than the total length', () => { let head = new Uint8Array([1, 2, 3]); let tail = new Uint8Array([4, 5, 6]); let needle = new Uint8Array([1, 2, 3, 4, 5, 6, 7]); - assert.equal(indexOf(head, tail, needle), -1); + assert.equal(combinedIndexOf(head, tail, needle), -1); }); it('handles repeated patterns correctly', () => { let head = new Uint8Array([1, 2, 1, 2]); let tail = new Uint8Array([1, 2, 1, 2]); let needle = new Uint8Array([2, 1, 2, 1]); - assert.equal(indexOf(head, tail, needle), 1); + assert.equal(combinedIndexOf(head, tail, needle), 1); }); }); diff --git a/src/lib/buffer-utils.ts b/src/lib/buffer-utils.ts index 31e6dc5c3d2..ffd27b9a525 100644 --- a/src/lib/buffer-utils.ts +++ b/src/lib/buffer-utils.ts @@ -17,7 +17,45 @@ export function concat(chunks: Uint8Array[]): Uint8Array { return result; } +export function computeSkipTable(needle: Uint8Array): Uint8Array { + let table = new Uint8Array(256).fill(needle.length); + + let lastIndex = needle.length - 1; + for (let i = 0; i < lastIndex; ++i) { + table[needle[i]] = lastIndex - i; + } + + return table; +} + export function indexOf( + haystack: Uint8Array, + needle: Uint8Array, + offset = 0, + skipTable = computeSkipTable(needle), +): number { + let i = Math.max(needle.length - 1, offset); + + while (i < haystack.length) { + let j = needle.length - 1; + let k = i; + + while (j >= 0 && haystack[k] === needle[j]) { + j--; + k--; + } + + if (j === -1) { + return k + 1; + } + + i += skipTable[haystack[i]]; + } + + return -1; // Not found +} + +export function combinedIndexOf( head: Uint8Array, tail: Uint8Array, needle: Uint8Array, @@ -41,18 +79,16 @@ export function indexOf( } i += skipTable[i < headLength ? head[i] : tail[i - headLength]]; - } - - return -1; // Not found -} - -export function computeSkipTable(needle: Uint8Array): Uint8Array { - let table = new Uint8Array(256).fill(needle.length); - let lastIndex = needle.length - 1; - for (let i = 0; i < lastIndex; ++i) { - table[needle[i]] = lastIndex - i; + // This optimization is worthwhile when streaming large files because the head is + // typically very small compared to the tail, so we can switch to a simpler implementation + // once we are sure the boundary is not contained in the head (the parser's buffer) + + // the beginning of the tail (the new chunk) + if (i >= headLength + needle.length) { + let index = indexOf(tail, needle, i - headLength, skipTable); + return index === -1 ? -1 : index + headLength; + } } - return table; + return -1; // Not found } diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 64884f77463..c322505ec9f 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -1,6 +1,6 @@ import { SuperHeaders } from 'fetch-super-headers'; -import { concat, indexOf, computeSkipTable } from './buffer-utils.js'; +import { concat, computeSkipTable, combinedIndexOf } from './buffer-utils.js'; /** * Extracts the boundary string from a `multipart/*` content type. @@ -228,7 +228,7 @@ export class MultipartParser { return []; } - let boundaryIndex = indexOf( + let boundaryIndex = combinedIndexOf( this.#buffer, this.#chunk, this.#boundaryArray, @@ -276,7 +276,7 @@ export class MultipartParser { break; } - let headerEndIndex = indexOf( + let headerEndIndex = combinedIndexOf( this.#buffer, this.#chunk, DOUBLE_NEWLINE, @@ -309,7 +309,7 @@ export class MultipartParser { break; } - let boundaryIndex = indexOf( + let boundaryIndex = combinedIndexOf( this.#buffer, this.#chunk, this.#boundaryArray, From 365f6c217bfaa8edb574b3050d927bf49fee916d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 14:53:02 -0700 Subject: [PATCH 165/730] Parse a stream in the benchmark --- bench/parsers/multipart-parser.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/bench/parsers/multipart-parser.ts b/bench/parsers/multipart-parser.ts index a22af422286..850e91f270c 100644 --- a/bench/parsers/multipart-parser.ts +++ b/bench/parsers/multipart-parser.ts @@ -3,11 +3,18 @@ import { MultipartParser } from '@mjackson/multipart-parser'; import { MultipartMessage } from '../messages.js'; export async function parse(message: MultipartMessage): Promise { - let start = performance.now(); + let stream = new ReadableStream({ + start(controller) { + for (let chunk of message.generateChunks()) { + controller.enqueue(chunk); + } + controller.close(); + }, + }); - let parser = new MultipartParser(message.boundary, { maxFileSize: Infinity }); + let start = performance.now(); - await parser.parse(message.generateChunks(), (_) => { + await new MultipartParser(message.boundary, { maxFileSize: Infinity }).parse(stream, (_) => { // Do nothing }); From 474e572813f6b183618dbc7a581cd18adfeacfde Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 15:26:17 -0700 Subject: [PATCH 166/730] Update Bun example README --- examples/bun/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/bun/README.md b/examples/bun/README.md index cabd35bd478..e97941cb7c7 100644 --- a/examples/bun/README.md +++ b/examples/bun/README.md @@ -1,3 +1,3 @@ # multipart-parser Bun Example -This is an example of how you can upload a file to a [Bun](https://bun.sh) server and stream it to a tmp directory on the filesystem. +This is an example of handling a `` POST to [a Bun server](https://bun.sh) and streaming any files it contains to a tmp directory on the filesystem. From d50d8561ae6007924a44ef33599f52ace469de99 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 15:26:00 -0700 Subject: [PATCH 167/730] Add Deno example --- .vscode/settings.json | 3 ++ README.md | 7 ++-- examples/deno/README.md | 3 ++ examples/deno/main.ts | 81 ++++++++++++++++++++++++++++++++++++++ examples/deno/package.json | 15 +++++++ pnpm-lock.yaml | 13 ++++++ 6 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 examples/deno/README.md create mode 100644 examples/deno/main.ts create mode 100644 examples/deno/package.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000000..f4ab7915a02 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "deno.enablePaths": ["./examples/deno"] +} diff --git a/README.md b/README.md index 848c834f178..929b84c00c1 100644 --- a/README.md +++ b/README.md @@ -122,9 +122,10 @@ await parser.parse(multipartData, async (part) => { The [`examples` directory](/examples) contains a few working examples of how you can use this library: -- [`examples/bun`](/examples/bun) demonstrates handling multipart uploads in Bun and saving them in a tmp file on disk -- [`examples/cf-workers`](/examples/cf-workers) demonstrates handling multipart uploads in a Cloudflare worker and store files in R2 -- [`examples/node`](/examples/node) demonstrates handling multipart uploads in Node.js and saving them in a tmp file on disk +- [`examples/bun`](/examples/bun) - using multipart-parser in Bun +- [`examples/cf-workers`](/examples/cf-workers) - using multipart-parser in a Cloudflare Worker and storing file uploads in R2 +- [`examples/deno`](/examples/deno) - using multipart-parser in Deno +- [`examples/node`](/examples/node) - using multipart-parser in Node.js ## Benchmark diff --git a/examples/deno/README.md b/examples/deno/README.md new file mode 100644 index 00000000000..9d2fc479abf --- /dev/null +++ b/examples/deno/README.md @@ -0,0 +1,3 @@ +# multipart-parser Deno Example + +This example demonstrates handling a `` POST to [a Deno server](https://deno.com/) and streaming any file uploads it contains to a tmp directory on the filesystem. diff --git a/examples/deno/main.ts b/examples/deno/main.ts new file mode 100644 index 00000000000..58ad609eea7 --- /dev/null +++ b/examples/deno/main.ts @@ -0,0 +1,81 @@ +// deno-lint-ignore-file prefer-const +import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser'; +// @deno-types="npm:@types/tmp" +import tmp from 'npm:tmp'; + +const PORT = 3000; + +Deno.serve( + { + port: PORT, + onListen() { + console.log(`Server listening on http://localhost:${PORT}`); + }, + }, + async (request) => { + if (request.method === 'GET') { + return new Response( + ` + + + + multipart-parser Deno Example + + +

multipart-parser Deno Example

+ +

+

+

+ + + +`, + { + headers: { 'Content-Type': 'text/html' }, + }, + ); + } + + if (request.method === 'POST') { + try { + // deno-lint-ignore no-explicit-any + let parts: any[] = []; + + for await (let part of parseMultipartRequest(request)) { + if (part.isFile) { + let tmpfile = tmp.fileSync(); + await Deno.writeFile(tmpfile.name, part.body); + + parts.push({ + name: part.name, + filename: part.filename, + mediaType: part.mediaType, + size: Deno.statSync(tmpfile.name).size, + file: tmpfile.name, + }); + } else { + parts.push({ + name: part.name, + value: await part.text(), + }); + } + } + + return new Response(JSON.stringify({ parts }, null, 2), { + headers: { 'Content-Type': 'application/json' }, + }); + } catch (error) { + console.error(error); + + if (error instanceof MultipartParseError) { + return new Response('Bad Request', { status: 400 }); + } + + return new Response('Internal Server Error', { status: 500 }); + } + } + + return new Response('Method Not Allowed', { status: 405 }); + }, +); diff --git a/examples/deno/package.json b/examples/deno/package.json new file mode 100644 index 00000000000..e344cdf4545 --- /dev/null +++ b/examples/deno/package.json @@ -0,0 +1,15 @@ +{ + "name": "multipart-parser-deno-example", + "private": true, + "type": "module", + "dependencies": { + "@mjackson/multipart-parser": "workspace:*", + "tmp": "^0.2.3" + }, + "devDependencies": { + "@types/tmp": "^0.2.6" + }, + "scripts": { + "start": "deno --unstable-byonm run --allow-all main.ts" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d734408cb45..b641219c830 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -76,6 +76,19 @@ importers: specifier: ^3.60.3 version: 3.67.1(@cloudflare/workers-types@4.20240725.0) + examples/deno: + dependencies: + '@mjackson/multipart-parser': + specifier: workspace:* + version: link:../.. + tmp: + specifier: ^0.2.3 + version: 0.2.3 + devDependencies: + '@types/tmp': + specifier: ^0.2.6 + version: 0.2.6 + examples/node: dependencies: '@mjackson/multipart-parser': From b645639ea8f427830dc780896fc36c0d53ccbfe4 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 15:34:51 -0700 Subject: [PATCH 168/730] Version 0.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 887a2f07c6b..f327c6d28a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.2.1", + "version": "0.3.0", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "license": "MIT", From ea1dae84a50d0ef3d5421f0c0b82aad2c1f99e31 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 31 Jul 2024 16:49:01 -0700 Subject: [PATCH 169/730] Add to JSR --- README.md | 8 ++++++++ jsr.json | 15 +++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 jsr.json diff --git a/README.md b/README.md index 929b84c00c1..127cf00cc6b 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,18 @@ The goals of this project are: ## Installation +Install from [npm](https://www.npmjs.com/): + ```sh $ npm install @mjackson/multipart-parser ``` +Or install from [JSR](https://jsr.io/): + +```sh +$ deno add @mjackson/multipart-parser +``` + ## Usage The most common use case for `multipart-parser` is handling file uploads when you're building a web server. For this case, the `parseMultipartRequest` function is your friend. It will automatically validate the request is `multipart/form-data`, extract the multipart boundary from the `Content-Type` header, parse all fields and files in the `request.body` stream, and `yield` each one to you as a `MultipartPart` object so you can save it to disk or upload it somewhere. diff --git a/jsr.json b/jsr.json new file mode 100644 index 00000000000..ac91b2ef749 --- /dev/null +++ b/jsr.json @@ -0,0 +1,15 @@ +{ + "name": "@mjackson/multipart-parser", + "version": "0.3.0", + "exports": "./src/multipart-parser.ts", + "publish": { + "include": [ + "LICENSE", + "README.md", + "src/**/*.ts", + "!src/test/", + "!src/**/*.spec.ts", + "!src/**/*.node.ts" + ] + } +} From 2add70905907a6693ac05a87f61d082f23064056 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 15:39:16 -0700 Subject: [PATCH 170/730] Use GitHub links in README --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 127cf00cc6b..03d7ecf72fe 100644 --- a/README.md +++ b/README.md @@ -128,12 +128,12 @@ await parser.parse(multipartData, async (part) => { ## Examples -The [`examples` directory](/examples) contains a few working examples of how you can use this library: +The [`examples` directory](https://github.com/mjackson/multipart-parser/tree/main/examples) contains a few working examples of how you can use this library: -- [`examples/bun`](/examples/bun) - using multipart-parser in Bun -- [`examples/cf-workers`](/examples/cf-workers) - using multipart-parser in a Cloudflare Worker and storing file uploads in R2 -- [`examples/deno`](/examples/deno) - using multipart-parser in Deno -- [`examples/node`](/examples/node) - using multipart-parser in Node.js +- [`examples/bun`](https://github.com/mjackson/multipart-parser/tree/main/examples/bun) - using multipart-parser in Bun +- [`examples/cf-workers`](https://github.com/mjackson/multipart-parser/tree/main/examples/cf-workers) - using multipart-parser in a Cloudflare Worker and storing file uploads in R2 +- [`examples/deno`](https://github.com/mjackson/multipart-parser/tree/main/examples/deno) - using multipart-parser in Deno +- [`examples/node`](https://github.com/mjackson/multipart-parser/tree/main/examples/node) - using multipart-parser in Node.js ## Benchmark From c6584662d35582c24614c8231a784d8a9cc4e845 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 16:04:23 -0700 Subject: [PATCH 171/730] Update benchmarks --- README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 03d7ecf72fe..eb1b3946e93 100644 --- a/README.md +++ b/README.md @@ -144,49 +144,49 @@ Important: Benchmarking can be tricky, and results vary greatly depending on pla The results of running the benchmarks on my laptop: ``` -> @mjackson/multipart-parser@0.2.1 bench:node /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.3.0 bench:node /Users/michael/Projects/multipart-parser > node --import tsimp/import ./bench/runner.ts Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/3/2024, 11:39:34 AM +Date: 8/4/2024, 3:41:42 PM Node.js v20.15.1 ┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ multipart-parser │ '0.01 ms ± 0.03' │ '1.11 ms ± 0.04' │ '0.32 ms ± 0.13' │ '10.94 ms ± 0.70' │ -│ busboy │ '0.03 ms ± 0.07' │ '2.84 ms ± 0.06' │ '0.22 ms ± 0.02' │ '43.24 ms ± 2.45' │ -│ @fastify/busboy │ '0.03 ms ± 0.06' │ '1.09 ms ± 0.07' │ '0.38 ms ± 0.03' │ '10.99 ms ± 0.15' │ +│ multipart-parser │ '0.02 ms ± 0.09' │ '2.44 ms ± 0.21' │ '0.35 ms ± 0.15' │ '10.37 ms ± 0.53' │ +│ busboy │ '0.03 ms ± 0.07' │ '4.52 ms ± 1.36' │ '0.25 ms ± 0.03' │ '43.37 ms ± 2.01' │ +│ @fastify/busboy │ '0.03 ms ± 0.09' │ '1.11 ms ± 0.06' │ '0.38 ms ± 0.03' │ '11.14 ms ± 0.25' │ └──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ -> @mjackson/multipart-parser@0.2.1 bench:bun /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.3.0 bench:bun /Users/michael/Projects/multipart-parser > bun run ./bench/runner.ts Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/3/2024, 4:37:33 PM +Date: 8/4/2024, 3:43:45 PM Bun 1.1.21 ┌──────────────────┬────────────────┬────────────────┬─────────────────┬─────────────────┐ │ │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼────────────────┼────────────────┼─────────────────┼─────────────────┤ -│ multipart-parser │ 0.01 ms ± 0.04 │ 1.08 ms ± 0.09 │ 0.14 ms ± 0.13 │ 10.79 ms ± 1.92 │ -│ busboy │ 0.02 ms ± 0.07 │ 3.30 ms ± 0.30 │ 0.33 ms ± 0.16 │ 33.09 ms ± 2.06 │ -│ @fastify/busboy │ 0.03 ms ± 0.09 │ 6.67 ms ± 0.31 │ 0.60 ms ± 0.14 │ 67.18 ms ± 3.58 │ +│ multipart-parser │ 0.01 ms ± 0.03 │ 0.87 ms ± 0.05 │ 0.14 ms ± 0.17 │ 8.58 ms ± 1.58 │ +│ busboy │ 0.02 ms ± 0.10 │ 3.29 ms ± 0.09 │ 0.33 ms ± 0.15 │ 33.07 ms ± 1.85 │ +│ @fastify/busboy │ 0.04 ms ± 0.14 │ 6.78 ms ± 0.12 │ 0.60 ms ± 0.14 │ 68.10 ms ± 3.41 │ └──────────────────┴────────────────┴────────────────┴─────────────────┴─────────────────┘ -> @mjackson/multipart-parser@0.2.1 bench:deno /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.3.0 bench:deno /Users/michael/Projects/multipart-parser > deno --unstable-byonm --unstable-sloppy-imports run --allow-sys ./bench/runner.ts Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/3/2024, 4:40:26 PM +Date: 8/4/2024, 3:46:35 PM Deno 1.45.5 ┌──────────────────┬──────────────────┬───────────────────┬──────────────────┬────────────────────┐ │ (idx) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼───────────────────┼──────────────────┼────────────────────┤ -│ multipart-parser │ "0.02 ms ± 0.19" │ "1.12 ms ± 0.99" │ "0.10 ms ± 0.44" │ "11.08 ms ± 1.03" │ -│ busboy │ "0.04 ms ± 0.27" │ "2.88 ms ± 1.00" │ "0.28 ms ± 0.69" │ "29.03 ms ± 2.15" │ -│ @fastify/busboy │ "0.04 ms ± 0.29" │ "11.61 ms ± 2.77" │ "0.75 ms ± 0.98" │ "115.50 ms ± 4.23" │ +│ multipart-parser │ "0.01 ms ± 0.14" │ "1.01 ms ± 1.00" │ "0.10 ms ± 0.43" │ "10.27 ms ± 1.83" │ +│ busboy │ "0.03 ms ± 0.26" │ "2.91 ms ± 1.10" │ "0.28 ms ± 0.70" │ "29.00 ms ± 1.45" │ +│ @fastify/busboy │ "0.04 ms ± 0.29" │ "11.22 ms ± 0.98" │ "0.74 ms ± 0.97" │ "114.25 ms ± 6.69" │ └──────────────────┴──────────────────┴───────────────────┴──────────────────┴────────────────────┘ ``` From e798c43bccaa93e7a84ddca09a59e2e9827cd370 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 16:19:32 -0700 Subject: [PATCH 172/730] Small update to README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eb1b3946e93..2c9fdbdbe66 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,7 @@ Deno 1.45.5 └──────────────────┴──────────────────┴───────────────────┴──────────────────┴────────────────────┘ ``` -I'd encourage you to run the benchmarks yourself. You'll probably get different results! +I encourage you to run the benchmarks yourself. You'll probably get different results! ```sh $ pnpm run bench From 035473bde40a4c7302eceef22d725d29e29b0dfc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 16:44:53 -0700 Subject: [PATCH 173/730] Create publish-jsr.yml --- .github/workflows/publish-jsr.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/publish-jsr.yml diff --git a/.github/workflows/publish-jsr.yml b/.github/workflows/publish-jsr.yml new file mode 100644 index 00000000000..782bb0c959b --- /dev/null +++ b/.github/workflows/publish-jsr.yml @@ -0,0 +1,19 @@ +name: Publish to JSR +on: + push: + tags: + - v[0-9]* + +jobs: + publish: + runs-on: ubuntu-latest + + permissions: + contents: read + id-token: write + + steps: + - uses: actions/checkout@v4 + + - name: Publish package + run: npx jsr publish From 462f07aeb9391f02db1f6e06327c7c4d190ea921 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 17:14:22 -0700 Subject: [PATCH 174/730] Small tweak to README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2c9fdbdbe66..7e34d744b51 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ If you'd prefer a callback-based API, instantiate your own `MultipartParser` and ```typescript import { MultipartParser } from '@mjackson/multipart-parser'; -let multipartData = new Uint8Array(); +let multipartData = new Uint8Array(); // or ReadableStream let boundary = '...'; let parser = new MultipartParser(boundary); From a0f9ab1ba251db833ad6835c12aaa8129083ce78 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 17:14:53 -0700 Subject: [PATCH 175/730] Add publish workflow --- .github/workflows/publish-jsr.yml | 19 ----------------- .github/workflows/publish.yml | 35 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 19 deletions(-) delete mode 100644 .github/workflows/publish-jsr.yml create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish-jsr.yml b/.github/workflows/publish-jsr.yml deleted file mode 100644 index 782bb0c959b..00000000000 --- a/.github/workflows/publish-jsr.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Publish to JSR -on: - push: - tags: - - v[0-9]* - -jobs: - publish: - runs-on: ubuntu-latest - - permissions: - contents: read - id-token: write - - steps: - - uses: actions/checkout@v4 - - - name: Publish package - run: npx jsr publish diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000000..96ef3d19106 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,35 @@ +name: Publish + +on: + push: + tags: + - v[0-9]* + +jobs: + build: + runs-on: ubuntu-latest + + permissions: + contents: read + id-token: write + + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '20.x' + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - run: pnpm install + + - name: Publish to npm + run: npm publish --provenance --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Publish to JSR + run: npx jsr publish From 94a215d2b432d0b5b2313829f396e72db062d079 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 1 Aug 2024 14:24:29 +1200 Subject: [PATCH 176/730] add multipasta to bench --- bench/package.json | 3 ++- bench/parsers/multipasta.ts | 24 ++++++++++++++++++++++++ bench/runner.ts | 4 ++++ pnpm-lock.yaml | 8 ++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 bench/parsers/multipasta.ts diff --git a/bench/package.json b/bench/package.json index 4595dcf85c0..4bb5e8ce417 100644 --- a/bench/package.json +++ b/bench/package.json @@ -5,7 +5,8 @@ "dependencies": { "@fastify/busboy": "^3.0.0", "@mjackson/multipart-parser": "workspace:*", - "busboy": "^1.6.0" + "busboy": "^1.6.0", + "multipasta": "^0.2.4" }, "devDependencies": { "@types/bun": "^1.1.6", diff --git a/bench/parsers/multipasta.ts b/bench/parsers/multipasta.ts new file mode 100644 index 00000000000..37b0b2e5237 --- /dev/null +++ b/bench/parsers/multipasta.ts @@ -0,0 +1,24 @@ +import * as Multipasta from 'multipasta'; + +import { MultipartMessage } from '../messages.js'; + +export function parse(message: MultipartMessage): Promise { + return new Promise((resolve, reject) => { + const start = performance.now(); + const parser = Multipasta.make({ + headers: { 'content-type': `multipart/form-data; boundary=${message.boundary}` }, + onDone() { + resolve(performance.now() - start); + }, + onError: reject, + onFile(_info) { + return (_chunk) => {}; + }, + onField() {}, + }); + for (const chunk of message.generateChunks()) { + parser.write(chunk); + } + parser.end(); + }); +} diff --git a/bench/runner.ts b/bench/runner.ts index 5f102c4fa66..8359ba47cb1 100644 --- a/bench/runner.ts +++ b/bench/runner.ts @@ -5,6 +5,7 @@ import * as messages from './messages.js'; import * as busboy from './parsers/busboy.js'; import * as fastifyBusboy from './parsers/fastify-busboy.js'; import * as multipartParser from './parsers/multipart-parser.js'; +import * as multipasta from './parsers/multipasta.js'; const benchmarks = [ { name: '1 small file', message: messages.oneSmallFile }, @@ -60,6 +61,9 @@ async function runBenchmarks(parserName?: string): Promise { if (parserName === 'fastify-busboy' || parserName === undefined) { results['@fastify/busboy'] = await runParserBenchmarks(fastifyBusboy); } + if (parserName === 'multipasta' || parserName === undefined) { + results['multipasta'] = await runParserBenchmarks(multipasta); + } return results; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b641219c830..46a2ce993c7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,6 +36,9 @@ importers: busboy: specifier: ^1.6.0 version: 1.6.0 + multipasta: + specifier: ^0.2.4 + version: 0.2.4 devDependencies: '@types/bun': specifier: ^1.1.6 @@ -566,6 +569,9 @@ packages: ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + multipasta@0.2.4: + resolution: {integrity: sha512-uS6VKZou4iDU4evtrNKGvRqgqkFtPdjG/ql9XDICfnzKEedgf0OZ+oEhM0ps0FL5IVFhkIzOBgLV/KpEEJMthw==} + mustache@4.2.0: resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} hasBin: true @@ -1191,6 +1197,8 @@ snapshots: ms@2.1.2: {} + multipasta@0.2.4: {} + mustache@4.2.0: {} nanoid@3.3.7: {} From 1f4f57fcdb7df9efbfcb25b2570311f95adb651b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 20:54:30 -0700 Subject: [PATCH 177/730] Auto sync jsr.json version with package.json --- .github/workflows/publish.yml | 9 ++++++++- scripts/sync-jsr-version.js | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 scripts/sync-jsr-version.js diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 96ef3d19106..72e3538a012 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest permissions: - contents: read + contents: write id-token: write steps: @@ -31,5 +31,12 @@ jobs: env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - run: node scripts/sync-jsr-version.js + + - uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: Sync JSR package version + file_pattern: jsr.json + - name: Publish to JSR run: npx jsr publish diff --git a/scripts/sync-jsr-version.js b/scripts/sync-jsr-version.js new file mode 100644 index 00000000000..07ec1e079ae --- /dev/null +++ b/scripts/sync-jsr-version.js @@ -0,0 +1,14 @@ +import * as fs from 'node:fs/promises'; +import * as path from 'node:path'; + +const __dirname = path.dirname(new URL(import.meta.url).pathname); + +let packageJsonPath = path.resolve(__dirname, '../package.json'); +let jsrJsonPath = path.resolve(__dirname, '../jsr.json'); + +let packageVersion = JSON.parse(await fs.readFile(packageJsonPath)).version; + +let jsrJson = JSON.parse(await fs.readFile(jsrJsonPath)); +jsrJson.version = packageVersion; + +await fs.writeFile(jsrJsonPath, JSON.stringify(jsrJson, null, 2) + '\n'); From 98b122210767bd3f9afd341e207a02fdff74d644 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 21:03:32 -0700 Subject: [PATCH 178/730] Remove prepublishOnly script --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index f327c6d28a1..55d8a719a2d 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,7 @@ "bench:node": "node --import tsimp/import ./bench/runner.ts", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", - "prepare": "npm run build", - "prepublishOnly": "npm run test" + "prepare": "npm run build" }, "packageManager": "pnpm@9.4.0", "keywords": [ From e8285d4f86fecde700b980160fe81670081dd9eb Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 21:06:17 -0700 Subject: [PATCH 179/730] Add repository config --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 55d8a719a2d..78b54cd7727 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,10 @@ "version": "0.3.0", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", + "repository": { + "type": "git", + "url": "https://github.com/mjackson/multipart-parser" + }, "license": "MIT", "files": [ "dist", From 31f85728eab8de361514c53c6a5f85056931a6c6 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 21:06:42 -0700 Subject: [PATCH 180/730] Version 0.3.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 78b54cd7727..9120fa1db92 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.3.0", + "version": "0.3.1", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "repository": { From 4e4c351badc9eb6cf9acc9b345c1f51e653bf47b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 21:09:43 -0700 Subject: [PATCH 181/730] Use main branch --- .github/workflows/publish.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 72e3538a012..185b3a75bb8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -35,6 +35,7 @@ jobs: - uses: stefanzweifel/git-auto-commit-action@v5 with: + branch: main commit_message: Sync JSR package version file_pattern: jsr.json From 38b46eef4dd510a38608c873e94b296afa2b3a61 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 21:09:48 -0700 Subject: [PATCH 182/730] Version 0.3.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9120fa1db92..ebfb393741b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.3.1", + "version": "0.3.2", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "repository": { From 1f030fc4c91450bac842d9e46cec4105737c650e Mon Sep 17 00:00:00 2001 From: mjackson Date: Mon, 5 Aug 2024 04:10:18 +0000 Subject: [PATCH 183/730] Sync JSR package version --- jsr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsr.json b/jsr.json index ac91b2ef749..548e3069c6b 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.3.0", + "version": "0.3.2", "exports": "./src/multipart-parser.ts", "publish": { "include": [ From 263f16d7cebb8b91ed5a2dbf48073bc503ad58e2 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 22:09:39 -0700 Subject: [PATCH 184/730] Update benchmark --- README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 7e34d744b51..b3ddddbbf6e 100644 --- a/README.md +++ b/README.md @@ -144,49 +144,49 @@ Important: Benchmarking can be tricky, and results vary greatly depending on pla The results of running the benchmarks on my laptop: ``` -> @mjackson/multipart-parser@0.3.0 bench:node /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.3.2 bench:node /Users/michael/Projects/multipart-parser > node --import tsimp/import ./bench/runner.ts Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/4/2024, 3:41:42 PM +Date: 8/4/2024, 9:45:08 PM Node.js v20.15.1 ┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ multipart-parser │ '0.02 ms ± 0.09' │ '2.44 ms ± 0.21' │ '0.35 ms ± 0.15' │ '10.37 ms ± 0.53' │ -│ busboy │ '0.03 ms ± 0.07' │ '4.52 ms ± 1.36' │ '0.25 ms ± 0.03' │ '43.37 ms ± 2.01' │ -│ @fastify/busboy │ '0.03 ms ± 0.09' │ '1.11 ms ± 0.06' │ '0.38 ms ± 0.03' │ '11.14 ms ± 0.25' │ +│ multipart-parser │ '0.02 ms ± 0.09' │ '1.04 ms ± 0.15' │ '0.32 ms ± 0.13' │ '10.39 ms ± 1.77' │ +│ busboy │ '0.03 ms ± 0.08' │ '4.26 ms ± 0.09' │ '0.24 ms ± 0.03' │ '43.00 ms ± 0.71' │ +│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.09 ms ± 0.06' │ '0.38 ms ± 0.03' │ '10.89 ms ± 0.14' │ └──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ -> @mjackson/multipart-parser@0.3.0 bench:bun /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.3.2 bench:bun /Users/michael/Projects/multipart-parser > bun run ./bench/runner.ts Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/4/2024, 3:43:45 PM +Date: 8/4/2024, 9:47:10 PM Bun 1.1.21 ┌──────────────────┬────────────────┬────────────────┬─────────────────┬─────────────────┐ │ │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼────────────────┼────────────────┼─────────────────┼─────────────────┤ -│ multipart-parser │ 0.01 ms ± 0.03 │ 0.87 ms ± 0.05 │ 0.14 ms ± 0.17 │ 8.58 ms ± 1.58 │ -│ busboy │ 0.02 ms ± 0.10 │ 3.29 ms ± 0.09 │ 0.33 ms ± 0.15 │ 33.07 ms ± 1.85 │ -│ @fastify/busboy │ 0.04 ms ± 0.14 │ 6.78 ms ± 0.12 │ 0.60 ms ± 0.14 │ 68.10 ms ± 3.41 │ +│ multipart-parser │ 0.01 ms ± 0.04 │ 0.85 ms ± 0.04 │ 0.13 ms ± 0.17 │ 8.31 ms ± 0.25 │ +│ busboy │ 0.02 ms ± 0.13 │ 3.29 ms ± 0.10 │ 0.34 ms ± 0.15 │ 33.09 ms ± 1.72 │ +│ @fastify/busboy │ 0.04 ms ± 0.13 │ 6.61 ms ± 0.11 │ 0.60 ms ± 0.22 │ 67.90 ms ± 4.82 │ └──────────────────┴────────────────┴────────────────┴─────────────────┴─────────────────┘ -> @mjackson/multipart-parser@0.3.0 bench:deno /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.3.2 bench:deno /Users/michael/Projects/multipart-parser > deno --unstable-byonm --unstable-sloppy-imports run --allow-sys ./bench/runner.ts Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/4/2024, 3:46:35 PM +Date: 8/4/2024, 9:50:01 PM Deno 1.45.5 ┌──────────────────┬──────────────────┬───────────────────┬──────────────────┬────────────────────┐ │ (idx) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼───────────────────┼──────────────────┼────────────────────┤ -│ multipart-parser │ "0.01 ms ± 0.14" │ "1.01 ms ± 1.00" │ "0.10 ms ± 0.43" │ "10.27 ms ± 1.83" │ -│ busboy │ "0.03 ms ± 0.26" │ "2.91 ms ± 1.10" │ "0.28 ms ± 0.70" │ "29.00 ms ± 1.45" │ -│ @fastify/busboy │ "0.04 ms ± 0.29" │ "11.22 ms ± 0.98" │ "0.74 ms ± 0.97" │ "114.25 ms ± 6.69" │ +│ multipart-parser │ "0.02 ms ± 0.19" │ "1.01 ms ± 1.00" │ "0.10 ms ± 0.44" │ "10.02 ms ± 0.70" │ +│ busboy │ "0.03 ms ± 0.25" │ "2.85 ms ± 0.99" │ "0.27 ms ± 0.69" │ "29.03 ms ± 2.07" │ +│ @fastify/busboy │ "0.04 ms ± 0.29" │ "11.23 ms ± 0.98" │ "0.72 ms ± 0.96" │ "115.38 ms ± 6.64" │ └──────────────────┴──────────────────┴───────────────────┴──────────────────┴────────────────────┘ ``` From a11e6fa5bc10eaa4a0337e716da8d682a319a9cc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 4 Aug 2024 23:02:46 -0700 Subject: [PATCH 185/730] Rename helper --- bench/messages.ts | 4 ++-- bench/utils.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bench/messages.ts b/bench/messages.ts index ce43600c962..ea6edbcd60a 100644 --- a/bench/messages.ts +++ b/bench/messages.ts @@ -1,4 +1,4 @@ -import { concatChunks, getRandomBytes } from './utils.js'; +import { concat, getRandomBytes } from './utils.js'; const NodeDefaultHighWaterMark = 65536; @@ -30,7 +30,7 @@ export class MultipartMessage { pushString(`--${boundary}--`); - this.content = concatChunks(chunks); + this.content = concat(chunks); } *generateChunks(chunkSize = NodeDefaultHighWaterMark): Generator { diff --git a/bench/utils.ts b/bench/utils.ts index 4a0ecb67155..7e433503a98 100644 --- a/bench/utils.ts +++ b/bench/utils.ts @@ -1,4 +1,4 @@ -export function concatChunks(chunks: Uint8Array[]): Uint8Array { +export function concat(chunks: Uint8Array[]): Uint8Array { if (chunks.length === 1) return chunks[0]; let length = 0; @@ -24,5 +24,5 @@ export function getRandomBytes(size: number): Uint8Array { chunks.push(crypto.getRandomValues(new Uint8Array(Math.min(size - i, 65536)))); } - return concatChunks(chunks); + return concat(chunks); } From 7af00cac9f2df40533ba89e508fa62129908c9ff Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 5 Aug 2024 08:53:22 -0700 Subject: [PATCH 186/730] Rename var --- src/lib/multipart.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index c322505ec9f..d8f7c697134 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -362,14 +362,14 @@ export class MultipartParser { return [head, tail]; } - let head = this.#chunk.subarray(0, size); + let view = this.#chunk.subarray(0, size); this.#chunk = this.#chunk.subarray(size); - return [head]; + return [view]; } - let head = this.#buffer.subarray(0, size); + let view = this.#buffer.subarray(0, size); this.#buffer = this.#buffer.subarray(size); - return [head]; + return [view]; } #skip(size: number): void { From 60d068ca329ddceb44b2e8ab0a452200cdb43a49 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 5 Aug 2024 10:27:19 -0700 Subject: [PATCH 187/730] Clean up example package.json --- examples/bun/package.json | 3 +-- examples/cf-workers/package.json | 12 ++++++------ examples/deno/package.json | 1 - 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/examples/bun/package.json b/examples/bun/package.json index 0403e6be506..fa37c3b35d0 100644 --- a/examples/bun/package.json +++ b/examples/bun/package.json @@ -1,7 +1,6 @@ { "name": "multipart-parser-bun-example", "private": true, - "type": "module", "dependencies": { "@mjackson/multipart-parser": "workspace:*", "tmp": "^0.2.3" @@ -13,4 +12,4 @@ "scripts": { "start": "bun run server.ts" } -} \ No newline at end of file +} diff --git a/examples/cf-workers/package.json b/examples/cf-workers/package.json index 3385bfe02a2..3ae2bf546a8 100644 --- a/examples/cf-workers/package.json +++ b/examples/cf-workers/package.json @@ -1,12 +1,6 @@ { "name": "multipart-parser-cf-workers-example", "private": true, - "scripts": { - "deploy": "wrangler deploy", - "dev": "wrangler dev", - "start": "wrangler dev", - "cf-typegen": "wrangler types" - }, "dependencies": { "@mjackson/multipart-parser": "workspace:*" }, @@ -14,5 +8,11 @@ "@cloudflare/workers-types": "^4.20240725.0", "typescript": "^5.5.2", "wrangler": "^3.60.3" + }, + "scripts": { + "deploy": "wrangler deploy", + "dev": "wrangler dev", + "start": "wrangler dev", + "cf-typegen": "wrangler types" } } diff --git a/examples/deno/package.json b/examples/deno/package.json index e344cdf4545..050d73d47d5 100644 --- a/examples/deno/package.json +++ b/examples/deno/package.json @@ -1,7 +1,6 @@ { "name": "multipart-parser-deno-example", "private": true, - "type": "module", "dependencies": { "@mjackson/multipart-parser": "workspace:*", "tmp": "^0.2.3" From 86d6a6060fbc63e7e9cca38d79aaefc4e25ba67a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 5 Aug 2024 13:54:03 -0700 Subject: [PATCH 188/730] Update tsconfig --- examples/cf-workers/tsconfig.json | 191 +++++++++++++++--------------- 1 file changed, 96 insertions(+), 95 deletions(-) diff --git a/examples/cf-workers/tsconfig.json b/examples/cf-workers/tsconfig.json index 79207ab7ae9..d0fd7d0e1df 100644 --- a/examples/cf-workers/tsconfig.json +++ b/examples/cf-workers/tsconfig.json @@ -1,105 +1,106 @@ { - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ - /* Projects */ - // "incremental": true, /* Enable incremental compilation */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + /* Projects */ + // "incremental": true, /* Enable incremental compilation */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - /* Language and Environment */ - "target": "es2021" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, - "lib": ["es2021"] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, - "jsx": "react-jsx" /* Specify what JSX code is generated. */, - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ - // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + /* Language and Environment */ + "target": "es2021" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + "lib": [ + "es2021" + ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, + "jsx": "react-jsx" /* Specify what JSX code is generated. */, + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ + // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - /* Modules */ - "module": "es2022" /* Specify what module code is generated. */, - // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "Bundler" /* Specify how TypeScript looks up a file from a given module specifier. */, - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ - "types": [ - "@cloudflare/workers-types/2023-07-01" - ] /* Specify type package names to be included without being referenced in a source file. */, - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - "resolveJsonModule": true /* Enable importing .json files */, - // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ + /* Modules */ + "module": "es2022" /* Specify what module code is generated. */, + // "rootDir": "./", /* Specify the root folder within your source files. */ + "moduleResolution": "Bundler" /* Specify how TypeScript looks up a file from a given module specifier. */, + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ + "types": [ + "@cloudflare/workers-types/2023-07-01" + ] /* Specify type package names to be included without being referenced in a source file. */, + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + "resolveJsonModule": true /* Enable importing .json files */, + // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ - /* JavaScript Support */ - "allowJs": true /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */, - "checkJs": false /* Enable error reporting in type-checked JavaScript files. */, - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ + /* JavaScript Support */ + "allowJs": true /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */, + "checkJs": false /* Enable error reporting in type-checked JavaScript files. */, + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - "noEmit": true /* Disable emitting files from a compilation. */, - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + "noEmit": true /* Disable emitting files from a compilation. */, + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - /* Interop Constraints */ - "isolatedModules": true /* Ensure that each file can be safely transpiled without relying on other imports. */, - "allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */, - // "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + /* Interop Constraints */ + "isolatedModules": true /* Ensure that each file can be safely transpiled without relying on other imports. */, + "allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */, + // "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, - /* Type Checking */ - "strict": true /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ - // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ - // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + /* Type Checking */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ + // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ + // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - }, - "exclude": ["test"], - "include": ["worker-configuration.d.ts", "src/**/*.ts"] + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": ["worker-configuration.d.ts", "src/**/*.ts"] } From 41ec33d7317423337796cfab03f4321b1c8ec416 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 5 Aug 2024 14:46:32 -0700 Subject: [PATCH 189/730] Update some examples --- examples/bun/server.ts | 4 ++-- examples/cf-workers/src/index.ts | 19 +++++++++---------- examples/deno/main.ts | 4 ++-- examples/node/server.js | 15 +++++++-------- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/examples/bun/server.ts b/examples/bun/server.ts index baca9f3f43e..a319a89f3ec 100644 --- a/examples/bun/server.ts +++ b/examples/bun/server.ts @@ -57,12 +57,12 @@ const server = Bun.serve({ headers: { 'Content-Type': 'application/json' }, }); } catch (error) { - console.error(error); - if (error instanceof MultipartParseError) { return new Response(error.message, { status: 400 }); } + console.error(error); + return new Response('Internal Server Error', { status: 500 }); } } diff --git a/examples/cf-workers/src/index.ts b/examples/cf-workers/src/index.ts index 52815d32be3..1c2ed26a7f5 100644 --- a/examples/cf-workers/src/index.ts +++ b/examples/cf-workers/src/index.ts @@ -22,30 +22,29 @@ export default { `, { headers: { 'Content-Type': 'text/html' }, - } + }, ); } if (request.method === 'POST') { try { - let bucket = env.MULTIPART_UPLOADS; let parts = []; - + for await (let part of parseMultipartRequest(request)) { if (part.isFile) { let uniqueKey = `upload-${new Date().getTime()}-${Math.random() .toString(36) .slice(2, 8)}`; - + // Put the file in R2. - + // Ideally we could stream part.body directly, but Cloudflare's R2 // API requires a FixedLengthStream and unfortunately we don't know // the length of the stream at this point because browsers don't send // Content-Length headers with file uploads. // await bucket.put(uniqueKey, part.body); - + // So instead, we have to buffer the entire file in memory and then // upload it to R2. let bytes = await part.bytes(); @@ -54,7 +53,7 @@ export default { contentType: part.headers.get('Content-Type')!, }, }); - + parts.push({ name: part.name, filename: part.filename, @@ -68,17 +67,17 @@ export default { }); } } - + return new Response(JSON.stringify({ parts }, null, 2), { headers: { 'Content-Type': 'application/json' }, }); } catch (error) { - console.error(error); - if (error instanceof MultipartParseError) { return new Response(error.message, { status: 400 }); } + console.error(error); + return new Response('Internal Server Error', { status: 500 }); } } diff --git a/examples/deno/main.ts b/examples/deno/main.ts index 58ad609eea7..782baeb855a 100644 --- a/examples/deno/main.ts +++ b/examples/deno/main.ts @@ -66,12 +66,12 @@ Deno.serve( headers: { 'Content-Type': 'application/json' }, }); } catch (error) { - console.error(error); - if (error instanceof MultipartParseError) { return new Response('Bad Request', { status: 400 }); } + console.error(error); + return new Response('Internal Server Error', { status: 500 }); } } diff --git a/examples/node/server.js b/examples/node/server.js index 91154838ce6..4e26395b305 100644 --- a/examples/node/server.js +++ b/examples/node/server.js @@ -66,17 +66,16 @@ const server = http.createServer(async (req, res) => { res.end(JSON.stringify({ parts }, null, 2)); return; } catch (error) { - console.error(error); - if (error instanceof MultipartParseError) { res.writeHead(400); res.end('Bad Request'); return; } + console.error(error); + res.writeHead(500); res.end('Internal Server Error'); - return; } } @@ -95,25 +94,25 @@ async function writeFile(filename, stream) { let fileStream = fs.createWriteStream(filename); let bytesWritten = 0; - await readStream(stream, (chunk) => { + for await (let chunk of readStream(stream)) { fileStream.write(chunk); bytesWritten += chunk.byteLength; - }); + } fileStream.end(); return bytesWritten; } -/** @type (stream: ReadableStream, callback: (value: T) => void) => Promise */ -async function readStream(stream, callback) { +/** @type (stream: ReadableStream) => AsyncGenerator */ +async function* readStream(stream) { let reader = stream.getReader(); try { while (true) { const { done, value } = await reader.read(); if (done) break; - callback(value); + yield value; } } finally { reader.releaseLock(); From 4064244e91280fca799c886758cfb9599b557a86 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 5 Aug 2024 17:57:17 -0700 Subject: [PATCH 190/730] Add license to README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index b3ddddbbf6e..399780c86be 100644 --- a/README.md +++ b/README.md @@ -199,3 +199,7 @@ $ pnpm run bench ## Credits Thanks to Jacob Ebey who gave me several code reviews on this project prior to publishing. + +## License + +See [LICENSE](https://github.com/mjackson/multipart-parser/blob/main/LICENSE) From fa8f98bd7c314c4e5a425089375acaed90a09d52 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 5 Aug 2024 18:22:28 -0700 Subject: [PATCH 191/730] Add docs links to MDN --- src/lib/content-disposition.ts | 4 +++- src/lib/content-type.ts | 4 +++- src/lib/cookie.ts | 4 +++- src/lib/set-cookie.ts | 4 +++- src/lib/super-headers.ts | 4 ++++ 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/lib/content-disposition.ts b/src/lib/content-disposition.ts index 2c2cc417311..082a9e4385b 100644 --- a/src/lib/content-disposition.ts +++ b/src/lib/content-disposition.ts @@ -9,7 +9,9 @@ export interface ContentDispositionInit { } /** - * Represents the value of a `Content-Disposition` HTTP header. + * The value of a `Content-Disposition` HTTP header. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) */ export class ContentDisposition implements HeaderValue { public filename?: string; diff --git a/src/lib/content-type.ts b/src/lib/content-type.ts index f09202d24e2..ab30a159e30 100644 --- a/src/lib/content-type.ts +++ b/src/lib/content-type.ts @@ -8,7 +8,9 @@ export interface ContentTypeInit { } /** - * Represents the value of a `Content-Type` HTTP header. + * The value of a `Content-Type` HTTP header. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) */ export class ContentType implements HeaderValue { public boundary?: string; diff --git a/src/lib/cookie.ts b/src/lib/cookie.ts index e2ad7bcf9ea..8a6b3222136 100644 --- a/src/lib/cookie.ts +++ b/src/lib/cookie.ts @@ -4,7 +4,9 @@ import { parseParams, quote } from './param-values.js'; export type CookieInit = [string, string][] | Record; /** - * Represents the value of a `Cookie` HTTP header. + * The value of a `Cookie` HTTP header. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie) */ export class Cookie implements HeaderValue, Iterable<[string, string]> { private cookies: Map; diff --git a/src/lib/set-cookie.ts b/src/lib/set-cookie.ts index 7b8c79a3d39..3b86819a90d 100644 --- a/src/lib/set-cookie.ts +++ b/src/lib/set-cookie.ts @@ -17,7 +17,9 @@ export interface SetCookieInit { } /** - * Represents the value of a `Set-Cookie` HTTP header. + * The value of a `Set-Cookie` HTTP header. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) */ export class SetCookie implements HeaderValue { public domain?: string; diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index d987dbda7ea..346d3f97229 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -17,6 +17,10 @@ export type SuperHeadersInit = /** * An enhanced JavaScript `Headers` interface with type-safe access. + * + * [API Reference](https://github.com/mjackson/headers) + * + * [MDN Reference for `Headers` base class](https://developer.mozilla.org/en-US/docs/Web/API/Headers) */ export class SuperHeaders extends Headers implements Iterable<[string, string]> { private map: Map; From dbe4f0ff5400e6dc7271c25aa791dac064007602 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 5 Aug 2024 18:23:32 -0700 Subject: [PATCH 192/730] Rename main exports file --- package.json | 5 ++++- src/{index.ts => headers.ts} | 0 2 files changed, 4 insertions(+), 1 deletion(-) rename src/{index.ts => headers.ts} (100%) diff --git a/package.json b/package.json index 6d74415fcbc..080127493f4 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,10 @@ "README.md" ], "type": "module", - "main": "./dist/index.js", + "exports": { + ".": "./dist/headers.js", + "./package.json": "./package.json" + }, "devDependencies": { "@types/node": "^20.14.10", "tsimp": "^2.0.11", diff --git a/src/index.ts b/src/headers.ts similarity index 100% rename from src/index.ts rename to src/headers.ts From 0ff699a9177d57c5f9fc282b98bd087280accd19 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 5 Aug 2024 18:24:29 -0700 Subject: [PATCH 193/730] Use JS private properties instead of TS public/private annotations --- src/lib/content-disposition.ts | 8 +-- src/lib/content-type.ts | 6 +- src/lib/cookie.ts | 32 ++++----- src/lib/set-cookie.ts | 18 +++--- src/lib/super-headers.ts | 114 ++++++++++++++++----------------- 5 files changed, 89 insertions(+), 89 deletions(-) diff --git a/src/lib/content-disposition.ts b/src/lib/content-disposition.ts index 082a9e4385b..c786196e1cb 100644 --- a/src/lib/content-disposition.ts +++ b/src/lib/content-disposition.ts @@ -14,10 +14,10 @@ export interface ContentDispositionInit { * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) */ export class ContentDisposition implements HeaderValue { - public filename?: string; - public filenameSplat?: string; - public name?: string; - public type?: string; + filename?: string; + filenameSplat?: string; + name?: string; + type?: string; constructor(init?: string | ContentDispositionInit) { if (init) { diff --git a/src/lib/content-type.ts b/src/lib/content-type.ts index ab30a159e30..ba8d267aec9 100644 --- a/src/lib/content-type.ts +++ b/src/lib/content-type.ts @@ -13,9 +13,9 @@ export interface ContentTypeInit { * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) */ export class ContentType implements HeaderValue { - public boundary?: string; - public charset?: string; - public mediaType?: string; + boundary?: string; + charset?: string; + mediaType?: string; constructor(init?: string | ContentTypeInit) { if (init) { diff --git a/src/lib/cookie.ts b/src/lib/cookie.ts index 8a6b3222136..d2c381decf3 100644 --- a/src/lib/cookie.ts +++ b/src/lib/cookie.ts @@ -9,24 +9,24 @@ export type CookieInit = [string, string][] | Record; * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie) */ export class Cookie implements HeaderValue, Iterable<[string, string]> { - private cookies: Map; + #cookies: Map; constructor(init?: string | CookieInit) { - this.cookies = new Map(); + this.#cookies = new Map(); if (init) { if (typeof init === 'string') { let params = parseParams(init); for (let [name, value] of params) { - this.cookies.set(name, value || ''); + this.#cookies.set(name, value || ''); } } else if (Array.isArray(init)) { for (let [name, value] of init) { - this.cookies.set(name, value); + this.#cookies.set(name, value); } } else { for (let name in init) { if (Object.prototype.hasOwnProperty.call(init, name)) { - this.cookies.set(name, init[name]); + this.#cookies.set(name, init[name]); } } } @@ -34,35 +34,35 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> { } get(name: string): string | undefined { - return this.cookies.get(name); + return this.#cookies.get(name); } set(name: string, value: string): void { - this.cookies.set(name, value); + this.#cookies.set(name, value); } delete(name: string): boolean { - return this.cookies.delete(name); + return this.#cookies.delete(name); } has(name: string): boolean { - return this.cookies.has(name); + return this.#cookies.has(name); } clear(): void { - this.cookies.clear(); + this.#cookies.clear(); } entries(): IterableIterator<[string, string]> { - return this.cookies.entries(); + return this.#cookies.entries(); } names(): IterableIterator { - return this.cookies.keys(); + return this.#cookies.keys(); } values(): IterableIterator { - return this.cookies.values(); + return this.#cookies.values(); } [Symbol.iterator](): IterableIterator<[string, string]> { @@ -73,17 +73,17 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> { callback: (value: string, key: string, map: Map) => void, thisArg?: any ): void { - this.cookies.forEach(callback, thisArg); + this.#cookies.forEach(callback, thisArg); } get size(): number { - return this.cookies.size; + return this.#cookies.size; } toString(): string { let pairs: string[] = []; - for (let [name, value] of this.cookies) { + for (let [name, value] of this.#cookies) { pairs.push(`${name}=${quote(value)}`); } diff --git a/src/lib/set-cookie.ts b/src/lib/set-cookie.ts index 3b86819a90d..67b9c5404c0 100644 --- a/src/lib/set-cookie.ts +++ b/src/lib/set-cookie.ts @@ -22,15 +22,15 @@ export interface SetCookieInit { * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) */ export class SetCookie implements HeaderValue { - public domain?: string; - public expires?: Date; - public httpOnly?: true; - public maxAge?: number; - public name?: string; - public path?: string; - public sameSite?: SameSiteValue; - public secure?: true; - public value?: string; + domain?: string; + expires?: Date; + httpOnly?: true; + maxAge?: number; + name?: string; + path?: string; + sameSite?: SameSiteValue; + secure?: true; + value?: string; constructor(init?: string | SetCookieInit) { if (init) { diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index 346d3f97229..09f5d6832fc 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -23,13 +23,13 @@ export type SuperHeadersInit = * [MDN Reference for `Headers` base class](https://developer.mozilla.org/en-US/docs/Web/API/Headers) */ export class SuperHeaders extends Headers implements Iterable<[string, string]> { - private map: Map; - private setCookieValues: (string | SetCookie)[] = []; + #map: Map; + #setCookieValues: (string | SetCookie)[] = []; constructor(init?: string | SuperHeadersInit) { super(); - this.map = new Map(); + this.#map = new Map(); if (init) { if (typeof init === 'string') { @@ -61,28 +61,28 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> append(name: string, value: string | HeaderValue): void { let key = name.toLowerCase(); if (key === SetCookieKey) { - this.setCookieValues.push(value as string | SetCookie); + this.#setCookieValues.push(value as string | SetCookie); } else { - let existingValue = this.map.get(key); - this.map.set(key, existingValue ? `${existingValue}, ${value}` : value); + let existingValue = this.#map.get(key); + this.#map.set(key, existingValue ? `${existingValue}, ${value}` : value); } } delete(name: string): void { let key = name.toLowerCase(); if (key === SetCookieKey) { - this.setCookieValues = []; + this.#setCookieValues = []; } else { - this.map.delete(key); + this.#map.delete(key); } } get(name: string): string | null { let key = name.toLowerCase(); if (key === SetCookieKey) { - return this.setCookieValues.map((value) => value.toString()).join(', '); + return this.#setCookieValues.map((value) => value.toString()).join(', '); } else { - let value = this.map.get(key); + let value = this.#map.get(key); if (typeof value === 'string') { return value; } else if (value instanceof Date) { @@ -96,36 +96,36 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } getSetCookie(): string[] { - return this.setCookieValues.map((value) => value.toString()); + return this.#setCookieValues.map((value) => value.toString()); } has(name: string): boolean { let key = name.toLowerCase(); if (key === SetCookieKey) { - return this.setCookieValues.length > 0; + return this.#setCookieValues.length > 0; } else { - return this.map.has(key); + return this.#map.has(key); } } set(name: string, value: string | HeaderValue): void { let key = name.toLowerCase(); if (key === SetCookieKey) { - this.setCookieValues = [value as string | SetCookie]; + this.#setCookieValues = [value as string | SetCookie]; } else { - this.map.set(key, value); + this.#map.set(key, value); } } *entries(): IterableIterator<[string, string]> { - for (let [key] of this.map) { + for (let [key] of this.#map) { let stringValue = this.get(key); if (stringValue) { yield [key, stringValue]; } } - for (let value of this.setCookieValues) { + for (let value of this.#setCookieValues) { let stringValue = value.toString(); if (stringValue) { yield [SetCookieKey, stringValue]; @@ -171,157 +171,157 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> // Header-specific getters and setters get age(): number | undefined { - return this.getNumberValue('age'); + return this.#getNumberValue('age'); } set age(value: string | number) { - this.map.set('age', value); + this.#map.set('age', value); } get contentDisposition(): ContentDisposition { - return this.getHeaderValue('content-disposition', ContentDisposition); + return this.#getHeaderValue('content-disposition', ContentDisposition); } set contentDisposition(value: string | ContentDisposition) { - this.map.set('content-disposition', value); + this.#map.set('content-disposition', value); } get contentLength(): number | undefined { - return this.getNumberValue('content-length'); + return this.#getNumberValue('content-length'); } set contentLength(value: string | number) { - this.map.set('content-length', value); + this.#map.set('content-length', value); } get contentType(): ContentType { - return this.getHeaderValue('content-type', ContentType); + return this.#getHeaderValue('content-type', ContentType); } set contentType(value: string | ContentType) { - this.map.set('content-type', value); + this.#map.set('content-type', value); } get cookie(): Cookie { - return this.getHeaderValue('cookie', Cookie); + return this.#getHeaderValue('cookie', Cookie); } set cookie(value: string | Cookie) { - this.map.set('cookie', value); + this.#map.set('cookie', value); } get date(): Date | undefined { - return this.getDateValue('date'); + return this.#getDateValue('date'); } set date(value: string | Date) { - this.map.set('date', value); + this.#map.set('date', value); } get expires(): Date | undefined { - return this.getDateValue('expires'); + return this.#getDateValue('expires'); } set expires(value: string | Date) { - this.map.set('expires', value); + this.#map.set('expires', value); } get ifModifiedSince(): Date | undefined { - return this.getDateValue('if-modified-since'); + return this.#getDateValue('if-modified-since'); } set ifModifiedSince(value: string | Date) { - this.map.set('if-modified-since', value); + this.#map.set('if-modified-since', value); } get ifUnmodifiedSince(): Date | undefined { - return this.getDateValue('if-unmodified-since'); + return this.#getDateValue('if-unmodified-since'); } set ifUnmodifiedSince(value: string | Date) { - this.map.set('if-unmodified-since', value); + this.#map.set('if-unmodified-since', value); } get lastModified(): Date | undefined { - return this.getDateValue('last-modified'); + return this.#getDateValue('last-modified'); } set lastModified(value: string | Date) { - this.map.set('last-modified', value); + this.#map.set('last-modified', value); } get setCookie(): SetCookie[] { - for (let i = 0; i < this.setCookieValues.length; i++) { - let value = this.setCookieValues[i]; + for (let i = 0; i < this.#setCookieValues.length; i++) { + let value = this.#setCookieValues[i]; if (typeof value === 'string') { - this.setCookieValues[i] = new SetCookie(value); + this.#setCookieValues[i] = new SetCookie(value); } } - return this.setCookieValues as SetCookie[]; + return this.#setCookieValues as SetCookie[]; } set setCookie(values: string | (string | SetCookie)[]) { if (typeof values === 'string') { - this.setCookieValues = [values]; + this.#setCookieValues = [values]; } else { - this.setCookieValues = values.slice(0); + this.#setCookieValues = values.slice(0); } } // helpers - private getDateValue(key: string): Date | undefined { - let value = this.map.get(key); + #getDateValue(key: string): Date | undefined { + let value = this.#map.get(key); if (value) { if (typeof value === 'string') { let date = new Date(value); if (isValidDate(date)) { - this.map.set(key, date); // cache the parsed date + this.#map.set(key, date); // cache the parsed date return date; } else { - this.map.delete(key); // bad value, remove it + this.#map.delete(key); // bad value, remove it } } else if (value instanceof Date) { return value; } else { - this.map.delete(key); // bad value, remove it + this.#map.delete(key); // bad value, remove it } } } - private getNumberValue(key: string): number | undefined { - let value = this.map.get(key); + #getNumberValue(key: string): number | undefined { + let value = this.#map.get(key); if (value) { if (typeof value === 'string') { let v = parseInt(value, 10); if (!isNaN(v)) { - this.map.set(key, v); // cache the parsed number + this.#map.set(key, v); // cache the parsed number return v; } else { - this.map.delete(key); // bad value, remove it + this.#map.delete(key); // bad value, remove it } } else if (typeof value === 'number') { return value; } else { - this.map.delete(key); // bad value, remove it + this.#map.delete(key); // bad value, remove it } } } - private getHeaderValue(key: string, ctor: new (init?: string) => T): T { - let value = this.map.get(key); + #getHeaderValue(key: string, ctor: new (init?: string) => T): T { + let value = this.#map.get(key); if (value) { if (typeof value === 'string') { let headerValue = new ctor(value); - this.map.set(key, headerValue); + this.#map.set(key, headerValue); return headerValue; } else { return value as T; } } else { let headerValue = new ctor(); - this.map.set(key, headerValue); + this.#map.set(key, headerValue); return headerValue; } } From 34f58da05e6999db3b47581a816a133dbaf1d71b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 6 Aug 2024 00:31:30 -0700 Subject: [PATCH 194/730] Add property initializers to SuperHeaders This allows SuperHeaders to be initialized with an object of property/value pairs that correspond with the names of the getter/setter methods for each header. Also, added a bunch of doc comments to various classes and methods and ensured that all classes can be initialized with an instance of themselves. --- src/headers.ts | 4 +- src/lib/content-disposition.spec.ts | 24 ++++- src/lib/content-disposition.ts | 15 ++- src/lib/content-type.spec.ts | 22 +++- src/lib/content-type.ts | 17 +++- src/lib/cookie.spec.ts | 153 ++++++++++++++++------------ src/lib/cookie.ts | 55 ++++++---- src/lib/set-cookie.spec.ts | 45 ++++++-- src/lib/set-cookie.ts | 48 ++++++++- src/lib/super-headers.spec.ts | 14 ++- src/lib/super-headers.ts | 75 ++++++++++---- src/lib/utils.ts | 4 + 12 files changed, 349 insertions(+), 127 deletions(-) diff --git a/src/headers.ts b/src/headers.ts index 8517c3ead09..a689791e5b4 100644 --- a/src/headers.ts +++ b/src/headers.ts @@ -1,6 +1,6 @@ -export { SuperHeadersInit, SuperHeaders, SuperHeaders as default } from './lib/super-headers.js'; - export { ContentDispositionInit, ContentDisposition } from './lib/content-disposition.js'; export { ContentTypeInit, ContentType } from './lib/content-type.js'; export { CookieInit, Cookie } from './lib/cookie.js'; export { SetCookieInit, SetCookie } from './lib/set-cookie.js'; + +export { SuperHeaders as default, SuperHeadersInit, SuperHeaders } from './lib/super-headers.js'; diff --git a/src/lib/content-disposition.spec.ts b/src/lib/content-disposition.spec.ts index 0bebd483ec8..8aca67022bc 100644 --- a/src/lib/content-disposition.spec.ts +++ b/src/lib/content-disposition.spec.ts @@ -4,16 +4,30 @@ import { describe, it } from 'node:test'; import { ContentDisposition } from './content-disposition.js'; describe('ContentDisposition', () => { - it('parses initial value correctly', () => { + it('initializes with an empty string', () => { + let header = new ContentDisposition(''); + assert.equal(header.type, undefined); + assert.equal(header.filename, undefined); + }); + + it('initializes with a string', () => { let header = new ContentDisposition('attachment; filename="example.txt"'); assert.equal(header.type, 'attachment'); assert.equal(header.filename, 'example.txt'); }); - it('handles empty initial value', () => { - let header = new ContentDisposition(''); - assert.equal(header.type, undefined); - assert.equal(header.filename, undefined); + it('initializes with an object', () => { + let header = new ContentDisposition({ type: 'attachment', filename: 'example.txt' }); + assert.equal(header.type, 'attachment'); + assert.equal(header.filename, 'example.txt'); + }); + + it('initializes with another ContentDisposition', () => { + let header = new ContentDisposition( + new ContentDisposition('attachment; filename="example.txt"') + ); + assert.equal(header.type, 'attachment'); + assert.equal(header.filename, 'example.txt'); }); it('handles whitespace in initial value', () => { diff --git a/src/lib/content-disposition.ts b/src/lib/content-disposition.ts index c786196e1cb..d8a7b8b8d9a 100644 --- a/src/lib/content-disposition.ts +++ b/src/lib/content-disposition.ts @@ -2,9 +2,22 @@ import { HeaderValue } from './header-value.js'; import { parseParams, quote } from './param-values.js'; export interface ContentDispositionInit { + /** + * For file uploads, the name of the file that the user selected. + */ filename?: string; + /** + * For file uploads, the name of the file that the user selected, encoded as a [RFC 8187](https://tools.ietf.org/html/rfc8187) `filename*` parameter. + * This parameter allows non-ASCII characters in filenames, and specifies the character encoding. + */ filenameSplat?: string; + /** + * For `multipart/form-data` requests, the name of the `` field associated with this content. + */ name?: string; + /** + * The disposition type of the content, such as `attachment` or `inline`. + */ type?: string; } @@ -13,7 +26,7 @@ export interface ContentDispositionInit { * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) */ -export class ContentDisposition implements HeaderValue { +export class ContentDisposition implements HeaderValue, ContentDispositionInit { filename?: string; filenameSplat?: string; name?: string; diff --git a/src/lib/content-type.spec.ts b/src/lib/content-type.spec.ts index 1e6ce1aa17d..f84a39220f3 100644 --- a/src/lib/content-type.spec.ts +++ b/src/lib/content-type.spec.ts @@ -4,16 +4,28 @@ import { describe, it } from 'node:test'; import { ContentType } from './content-type.js'; describe('ContentType', () => { - it('parses initial value correctly', () => { + it('initializes with an empty string', () => { + let header = new ContentType(''); + assert.equal(header.mediaType, undefined); + assert.equal(header.charset, undefined); + }); + + it('initializes with a string', () => { let header = new ContentType('text/plain; charset=utf-8'); assert.equal(header.mediaType, 'text/plain'); assert.equal(header.charset, 'utf-8'); }); - it('handles empty initial value', () => { - let header = new ContentType(''); - assert.equal(header.mediaType, undefined); - assert.equal(header.charset, undefined); + it('initializes with an object', () => { + let header = new ContentType({ mediaType: 'text/plain', charset: 'utf-8' }); + assert.equal(header.mediaType, 'text/plain'); + assert.equal(header.charset, 'utf-8'); + }); + + it('initializes with another ContentType', () => { + let header = new ContentType(new ContentType('text/plain; charset=utf-8')); + assert.equal(header.mediaType, 'text/plain'); + assert.equal(header.charset, 'utf-8'); }); it('handles whitespace in initial value', () => { diff --git a/src/lib/content-type.ts b/src/lib/content-type.ts index ba8d267aec9..b0d2a14f6b8 100644 --- a/src/lib/content-type.ts +++ b/src/lib/content-type.ts @@ -2,8 +2,23 @@ import { HeaderValue } from './header-value.js'; import { parseParams, quote } from './param-values.js'; export interface ContentTypeInit { + /** + * For multipart entities, the boundary that separates the different parts of the message. + */ boundary?: string; + /** + * Indicates the [character encoding](https://developer.mozilla.org/en-US/docs/Glossary/Character_encoding) of the content. + * + * For example, `utf-8`, `iso-8859-1`. + */ charset?: string; + /** + * The media type (or MIME type) of the content. This consists of a type and subtype, separated by a slash. + * + * For example, `text/html`, `application/json`, `image/png`. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) + */ mediaType?: string; } @@ -12,7 +27,7 @@ export interface ContentTypeInit { * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) */ -export class ContentType implements HeaderValue { +export class ContentType implements HeaderValue, ContentTypeInit { boundary?: string; charset?: string; mediaType?: string; diff --git a/src/lib/cookie.spec.ts b/src/lib/cookie.spec.ts index ac86e5a0cd8..fed21aa3b70 100644 --- a/src/lib/cookie.spec.ts +++ b/src/lib/cookie.spec.ts @@ -1,119 +1,140 @@ -import * as assert from "node:assert/strict"; -import { describe, it } from "node:test"; +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; -import { Cookie } from "./cookie.js"; +import { Cookie } from './cookie.js'; -describe("Cookie", () => { - it("parses initial value correctly", () => { - let header = new Cookie("name1=value1; name2=value2"); - assert.equal(header.get("name1"), "value1"); - assert.equal(header.get("name2"), "value2"); +describe('Cookie', () => { + it('initializes with an empty string', () => { + let header = new Cookie(''); + assert.equal(header.size, 0); }); - it("handles empty initial value", () => { - let header = new Cookie(""); - assert.equal(header.size, 0); + it('initializes with a string', () => { + let header = new Cookie('name1=value1; name2=value2'); + assert.equal(header.get('name1'), 'value1'); + assert.equal(header.get('name2'), 'value2'); + }); + + it('initializes with an array', () => { + let header = new Cookie([ + ['name1', 'value1'], + ['name2', 'value2'], + ]); + assert.equal(header.get('name1'), 'value1'); + assert.equal(header.get('name2'), 'value2'); + }); + + it('initializes with an object', () => { + let header = new Cookie({ name1: 'value1', name2: 'value2' }); + assert.equal(header.get('name1'), 'value1'); + assert.equal(header.get('name2'), 'value2'); + }); + + it('initializes with another Cookie', () => { + let header = new Cookie(new Cookie('name1=value1; name2=value2')); + assert.equal(header.get('name1'), 'value1'); + assert.equal(header.get('name2'), 'value2'); }); - it("handles whitespace in initial value", () => { - let header = new Cookie(" name1 = value1 ; name2 = value2 "); - assert.equal(header.get("name1"), "value1"); - assert.equal(header.get("name2"), "value2"); + it('handles whitespace in initial value', () => { + let header = new Cookie(' name1 = value1 ; name2 = value2 '); + assert.equal(header.get('name1'), 'value1'); + assert.equal(header.get('name2'), 'value2'); }); - it("sets and gets values", () => { - let header = new Cookie(""); - header.set("name", "value"); - assert.equal(header.get("name"), "value"); + it('sets and gets values', () => { + let header = new Cookie(''); + header.set('name', 'value'); + assert.equal(header.get('name'), 'value'); }); - it("deletes values", () => { - let header = new Cookie("name=value"); - assert.equal(header.delete("name"), true); - assert.equal(header.delete("nonexistent"), false); - assert.equal(header.get("name"), undefined); + it('deletes values', () => { + let header = new Cookie('name=value'); + assert.equal(header.delete('name'), true); + assert.equal(header.delete('nonexistent'), false); + assert.equal(header.get('name'), undefined); }); - it("checks if value exists", () => { - let header = new Cookie("name=value"); - assert.equal(header.has("name"), true); - assert.equal(header.has("nonexistent"), false); + it('checks if value exists', () => { + let header = new Cookie('name=value'); + assert.equal(header.has('name'), true); + assert.equal(header.has('nonexistent'), false); }); - it("clears all values", () => { - let header = new Cookie("name1=value1; name2=value2"); + it('clears all values', () => { + let header = new Cookie('name1=value1; name2=value2'); header.clear(); assert.equal(header.size, 0); }); - it("iterates over entries", () => { - let header = new Cookie("name1=value1; name2=value2"); + it('iterates over entries', () => { + let header = new Cookie('name1=value1; name2=value2'); let entries = Array.from(header.entries()); assert.deepEqual(entries, [ - ["name1", "value1"], - ["name2", "value2"] + ['name1', 'value1'], + ['name2', 'value2'], ]); }); - it("iterates over names", () => { - let header = new Cookie("name1=value1; name2=value2"); + it('iterates over names', () => { + let header = new Cookie('name1=value1; name2=value2'); let names = Array.from(header.names()); - assert.deepEqual(names, ["name1", "name2"]); + assert.deepEqual(names, ['name1', 'name2']); }); - it("iterates over values", () => { - let header = new Cookie("name1=value1; name2=value2"); + it('iterates over values', () => { + let header = new Cookie('name1=value1; name2=value2'); let values = Array.from(header.values()); - assert.deepEqual(values, ["value1", "value2"]); + assert.deepEqual(values, ['value1', 'value2']); }); - it("uses forEach correctly", () => { - let header = new Cookie("name1=value1; name2=value2"); + it('uses forEach correctly', () => { + let header = new Cookie('name1=value1; name2=value2'); let result: [string, string][] = []; header.forEach((value, name) => { result.push([name, value]); }); assert.deepEqual(result, [ - ["name1", "value1"], - ["name2", "value2"] + ['name1', 'value1'], + ['name2', 'value2'], ]); }); - it("returns correct size", () => { - let header = new Cookie("name1=value1; name2=value2"); + it('returns correct size', () => { + let header = new Cookie('name1=value1; name2=value2'); assert.equal(header.size, 2); }); - it("converts to string correctly", () => { - let header = new Cookie("name1=value1; name2=value2"); - assert.equal(header.toString(), "name1=value1; name2=value2"); + it('converts to string correctly', () => { + let header = new Cookie('name1=value1; name2=value2'); + assert.equal(header.toString(), 'name1=value1; name2=value2'); }); - it("is directly iterable", () => { - let header = new Cookie("name1=value1; name2=value2"); + it('is directly iterable', () => { + let header = new Cookie('name1=value1; name2=value2'); let entries = Array.from(header); assert.deepEqual(entries, [ - ["name1", "value1"], - ["name2", "value2"] + ['name1', 'value1'], + ['name2', 'value2'], ]); }); - it("handles cookies without values", () => { - let header = new Cookie("name1=value1; name2"); - assert.equal(header.get("name1"), "value1"); - assert.equal(header.get("name2"), ""); + it('handles cookies without values', () => { + let header = new Cookie('name1=value1; name2'); + assert.equal(header.get('name1'), 'value1'); + assert.equal(header.get('name2'), ''); }); - it("handles setting empty values", () => { - let header = new Cookie(""); - header.set("name", ""); - assert.equal(header.get("name"), ""); - assert.equal(header.toString(), "name="); + it('handles setting empty values', () => { + let header = new Cookie(''); + header.set('name', ''); + assert.equal(header.get('name'), ''); + assert.equal(header.toString(), 'name='); }); - it("overwrites existing values", () => { - let header = new Cookie("name=value1"); - header.set("name", "value2"); - assert.equal(header.get("name"), "value2"); + it('overwrites existing values', () => { + let header = new Cookie('name=value1'); + header.set('name', 'value2'); + assert.equal(header.get('name'), 'value2'); }); }); diff --git a/src/lib/cookie.ts b/src/lib/cookie.ts index d2c381decf3..cba42b43efc 100644 --- a/src/lib/cookie.ts +++ b/src/lib/cookie.ts @@ -1,7 +1,8 @@ import { HeaderValue } from './header-value.js'; import { parseParams, quote } from './param-values.js'; +import { isIterable } from './utils.js'; -export type CookieInit = [string, string][] | Record; +export type CookieInit = Iterable<[string, string]> | Record; /** * The value of a `Cookie` HTTP header. @@ -9,60 +10,75 @@ export type CookieInit = [string, string][] | Record; * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie) */ export class Cookie implements HeaderValue, Iterable<[string, string]> { - #cookies: Map; + #map: Map; constructor(init?: string | CookieInit) { - this.#cookies = new Map(); + this.#map = new Map(); if (init) { if (typeof init === 'string') { let params = parseParams(init); for (let [name, value] of params) { - this.#cookies.set(name, value || ''); + this.#map.set(name, value || ''); } - } else if (Array.isArray(init)) { + } else if (isIterable(init)) { for (let [name, value] of init) { - this.#cookies.set(name, value); + this.#map.set(name, value); } } else { for (let name in init) { if (Object.prototype.hasOwnProperty.call(init, name)) { - this.#cookies.set(name, init[name]); + this.#map.set(name, init[name]); } } } } } + /** + * Gets the value of a cookie with the given name from the `Cookie` header. + */ get(name: string): string | undefined { - return this.#cookies.get(name); + return this.#map.get(name); } + /** + * Sets a cookie with the given name and value in the `Cookie` header. + */ set(name: string, value: string): void { - this.#cookies.set(name, value); + this.#map.set(name, value); } + /** + * Removes a cookie with the given name from the `Cookie` header. + */ delete(name: string): boolean { - return this.#cookies.delete(name); + return this.#map.delete(name); } + /** + * True if a cookie with the given name exists in the `Cookie` header. + */ has(name: string): boolean { - return this.#cookies.has(name); + return this.#map.has(name); } + /** + * Removes all cookies from the `Cookie` header. + */ clear(): void { - this.#cookies.clear(); + this.#map.clear(); } entries(): IterableIterator<[string, string]> { - return this.#cookies.entries(); + return this.#map.entries(); } names(): IterableIterator { - return this.#cookies.keys(); + return this.#map.keys(); } values(): IterableIterator { - return this.#cookies.values(); + return this.#map.values(); } [Symbol.iterator](): IterableIterator<[string, string]> { @@ -73,17 +89,20 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> { callback: (value: string, key: string, map: Map) => void, thisArg?: any ): void { - this.#cookies.forEach(callback, thisArg); + this.#map.forEach(callback, thisArg); } + /** + * The number of cookies in the `Cookie` header. + */ get size(): number { - return this.#cookies.size; + return this.#map.size; } toString(): string { let pairs: string[] = []; - for (let [name, value] of this.#cookies) { + for (let [name, value] of this.#map) { pairs.push(`${name}=${quote(value)}`); } diff --git a/src/lib/set-cookie.spec.ts b/src/lib/set-cookie.spec.ts index 0980e5e40d1..346645a5b7a 100644 --- a/src/lib/set-cookie.spec.ts +++ b/src/lib/set-cookie.spec.ts @@ -4,7 +4,13 @@ import { describe, it } from 'node:test'; import { SetCookie } from './set-cookie.js'; describe('SetCookie', () => { - it('parses initial value correctly', () => { + it('initializes with an empty string', () => { + let header = new SetCookie(''); + assert.equal(header.name, undefined); + assert.equal(header.value, undefined); + }); + + it('initializes with a string', () => { let header = new SetCookie( 'session=abc123; Domain=example.com; Path=/; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly' ); @@ -17,18 +23,43 @@ describe('SetCookie', () => { assert.equal(header.httpOnly, true); }); + it('initializes with an object', () => { + let header = new SetCookie({ + name: 'session', + value: 'abc123', + domain: 'example.com', + path: '/', + expires: new Date('Wed, 21 Oct 2015 07:28:00 GMT'), + secure: true, + httpOnly: true, + }); + assert.equal(header.name, 'session'); + assert.equal(header.value, 'abc123'); + assert.equal(header.domain, 'example.com'); + assert.equal(header.path, '/'); + assert.equal(header.expires?.toUTCString(), 'Wed, 21 Oct 2015 07:28:00 GMT'); + assert.equal(header.secure, true); + assert.equal(header.httpOnly, true); + }); + + it('initializes with another SetCookie', () => { + let header = new SetCookie( + new SetCookie('session=abc123; Domain=example.com; Path=/; Secure; HttpOnly') + ); + assert.equal(header.name, 'session'); + assert.equal(header.value, 'abc123'); + assert.equal(header.domain, 'example.com'); + assert.equal(header.path, '/'); + assert.equal(header.secure, true); + assert.equal(header.httpOnly, true); + }); + it('handles cookies without attributes', () => { let header = new SetCookie('user=john'); assert.equal(header.name, 'user'); assert.equal(header.value, 'john'); }); - it('initializes with an empty string', () => { - let header = new SetCookie(''); - assert.equal(header.name, undefined); - assert.equal(header.value, undefined); - }); - it('handles cookie values with commas', () => { let header = new SetCookie('list=apple,banana,cherry; Domain=example.com'); assert.equal(header.name, 'list'); diff --git a/src/lib/set-cookie.ts b/src/lib/set-cookie.ts index 67b9c5404c0..3efc533879d 100644 --- a/src/lib/set-cookie.ts +++ b/src/lib/set-cookie.ts @@ -5,14 +5,60 @@ import { capitalize, isValidDate } from './utils.js'; type SameSiteValue = 'Strict' | 'Lax' | 'None'; export interface SetCookieInit { + /** + * The domain of the cookie. For example, `example.com`. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value) + */ domain?: string; + /** + * The expiration date of the cookie. If not specified, the cookie is a session cookie. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#expiresdate) + */ expires?: Date; + /** + * Indicates this cookie should not be accessible via JavaScript. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#httponly) + */ httpOnly?: true; + /** + * The maximum age of the cookie in seconds. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#max-age) + */ maxAge?: number; + /** + * The name of the cookie. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#cookie-namecookie-value) + */ name?: string; + /** + * The path of the cookie. For example, `/` or `/admin`. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value) + */ path?: string; + /** + * The `SameSite` attribute of the cookie. This attribute lets servers require that a cookie shouldn't be sent with + * cross-site requests, which provides some protection against cross-site request forgery attacks. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value) + */ sameSite?: SameSiteValue; + /** + * Indicates the cookie should only be sent over HTTPS. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#secure) + */ secure?: true; + /** + * The value of the cookie. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#cookie-namecookie-value) + */ value?: string; } @@ -21,7 +67,7 @@ export interface SetCookieInit { * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) */ -export class SetCookie implements HeaderValue { +export class SetCookie implements HeaderValue, SetCookieInit { domain?: string; expires?: Date; httpOnly?: true; diff --git a/src/lib/super-headers.spec.ts b/src/lib/super-headers.spec.ts index 254823e2b4a..0a15b3044e3 100644 --- a/src/lib/super-headers.spec.ts +++ b/src/lib/super-headers.spec.ts @@ -24,11 +24,23 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Content-Length'), '42'); }); - it('initializes from an object', () => { + it('initializes from an object of header name/value pairs', () => { let headers = new SuperHeaders({ 'Content-Type': 'text/plain' }); assert.equal(headers.get('Content-Type'), 'text/plain'); }); + it('initializes from an object of property name/value pairs', () => { + let headers = new SuperHeaders({ contentType: 'text/plain' }); + assert.equal(headers.get('Content-Type'), 'text/plain'); + + let headers2 = new SuperHeaders({ + contentType: { mediaType: 'text/plain' }, + lastModified: new Date('2021-01-01T00:00:00Z'), + }); + assert.equal(headers2.get('Content-Type'), 'text/plain'); + assert.equal(headers2.get('Last-Modified'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + }); + it('initializes from an array of key-value pairs', () => { let headers = new SuperHeaders([ ['Content-Type', 'text/plain'], diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index 09f5d6832fc..3598f9a6f97 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -1,19 +1,31 @@ -import { ContentDisposition } from './content-disposition.js'; -import { ContentType } from './content-type.js'; -import { Cookie } from './cookie.js'; +import { ContentDispositionInit, ContentDisposition } from './content-disposition.js'; +import { ContentTypeInit, ContentType } from './content-type.js'; +import { CookieInit, Cookie } from './cookie.js'; import { canonicalHeaderName } from './header-names.js'; import { HeaderValue } from './header-value.js'; -import { SetCookie } from './set-cookie.js'; -import { isValidDate } from './utils.js'; +import { SetCookieInit, SetCookie } from './set-cookie.js'; +import { isIterable, isValidDate } from './utils.js'; const CRLF = '\r\n'; const SetCookieKey = 'set-cookie'; +interface SuperHeadersPropertyInit { + age?: string | number; + contentDisposition?: string | ContentDispositionInit; + contentLength?: string | number; + contentType?: string | ContentTypeInit; + cookie?: string | CookieInit; + date?: string | Date; + expires?: string | Date; + ifModifiedSince?: string | Date; + ifUnmodifiedSince?: string | Date; + lastModified?: string | Date; + setCookie?: string | (string | SetCookieInit)[]; +} + export type SuperHeadersInit = - | SuperHeaders - | Headers - | [string, string | HeaderValue][] - | Record; + | Iterable<[string, string | HeaderValue]> + | (SuperHeadersPropertyInit & Record); /** * An enhanced JavaScript `Headers` interface with type-safe access. @@ -26,7 +38,7 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> #map: Map; #setCookieValues: (string | SetCookie)[] = []; - constructor(init?: string | SuperHeadersInit) { + constructor(init?: string | SuperHeadersInit | Headers) { super(); this.#map = new Map(); @@ -40,7 +52,7 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.append(match[1].trim(), match[2].trim()); } } - } else if (init instanceof SuperHeaders || Array.isArray(init)) { + } else if (isIterable(init)) { for (let [name, value] of init) { this.append(name, value); } @@ -51,7 +63,12 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } else if (typeof init === 'object') { for (let name in init) { if (Object.prototype.hasOwnProperty.call(init, name)) { - this.append(name, init[name]); + let setter = Object.getOwnPropertyDescriptor(SuperHeaders.prototype, name)?.set; + if (setter) { + setter.call(this, init[name]); + } else { + this.append(name, init[name]); + } } } } @@ -182,8 +199,8 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> return this.#getHeaderValue('content-disposition', ContentDisposition); } - set contentDisposition(value: string | ContentDisposition) { - this.#map.set('content-disposition', value); + set contentDisposition(value: string | ContentDispositionInit) { + this.#setHeaderValue('content-disposition', ContentDisposition, value); } get contentLength(): number | undefined { @@ -198,8 +215,8 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> return this.#getHeaderValue('content-type', ContentType); } - set contentType(value: string | ContentType) { - this.#map.set('content-type', value); + set contentType(value: string | ContentTypeInit) { + this.#setHeaderValue('content-type', ContentType, value); } get cookie(): Cookie { @@ -207,7 +224,7 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } set cookie(value: string | Cookie) { - this.#map.set('cookie', value); + this.#setHeaderValue('cookie', Cookie, value); } get date(): Date | undefined { @@ -251,7 +268,7 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } get setCookie(): SetCookie[] { - for (let i = 0; i < this.#setCookieValues.length; i++) { + for (let i = 0; i < this.#setCookieValues.length; ++i) { let value = this.#setCookieValues[i]; if (typeof value === 'string') { this.#setCookieValues[i] = new SetCookie(value); @@ -261,11 +278,17 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> return this.#setCookieValues as SetCookie[]; } - set setCookie(values: string | (string | SetCookie)[]) { + set setCookie(values: string | (string | SetCookieInit)[]) { if (typeof values === 'string') { this.#setCookieValues = [values]; } else { - this.#setCookieValues = values.slice(0); + this.#setCookieValues = values.map((value) => { + if (typeof value === 'string' || value instanceof SetCookie) { + return value; + } else { + return new SetCookie(value); + } + }); } } @@ -325,4 +348,16 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> return headerValue; } } + + #setHeaderValue( + key: string, + ctor: new (init?: string | T) => HeaderValue, + value: string | T + ): void { + if (typeof value === 'string' || value instanceof ctor) { + this.#map.set(key, value); + } else { + this.#map.set(key, new ctor(value)); + } + } } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 4fd9eb73620..efa5a2da1e1 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -2,6 +2,10 @@ export function capitalize(str: string): string { return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); } +export function isIterable(value: any): value is Iterable { + return value != null && typeof value[Symbol.iterator] === 'function'; +} + export function isValidDate(date: unknown): boolean { return date instanceof Date && !isNaN(date.getTime()); } From 4fa94473b764e38b1bb298ac325370cc50ed4617 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 6 Aug 2024 01:40:48 -0700 Subject: [PATCH 195/730] More docs and tests --- src/lib/content-disposition.ts | 15 ++++++++++----- src/lib/super-headers.spec.ts | 8 ++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/lib/content-disposition.ts b/src/lib/content-disposition.ts index d8a7b8b8d9a..793b3378703 100644 --- a/src/lib/content-disposition.ts +++ b/src/lib/content-disposition.ts @@ -57,12 +57,17 @@ export class ContentDisposition implements HeaderValue, ContentDispositionInit { } } + /** + * The preferred filename for the content, using the `filename*` parameter if present, falling back to the `filename` parameter. + * + * From [RFC 6266](https://tools.ietf.org/html/rfc6266): + * + * Many user agent implementations predating this specification do not understand the "filename*" parameter. + * Therefore, when both "filename" and "filename*" are present in a single header field value, recipients SHOULD + * pick "filename*" and ignore "filename". This way, senders can avoid special-casing specific user agents by + * sending both the more expressive "filename*" parameter, and the "filename" parameter as fallback for legacy recipients. + */ get preferredFilename(): string | undefined { - // From RFC 6266: - // Many user agent implementations predating this specification do not understand the "filename*" parameter. - // Therefore, when both "filename" and "filename*" are present in a single header field value, recipients SHOULD - // pick "filename*" and ignore "filename". This way, senders can avoid special-casing specific user agents by - // sending both the more expressive "filename*" parameter, and the "filename" parameter as fallback for legacy recipients. let filenameSplat = this.filenameSplat; if (filenameSplat) { let decodedFilename = decodeFilenameSplat(filenameSplat); diff --git a/src/lib/super-headers.spec.ts b/src/lib/super-headers.spec.ts index 0a15b3044e3..6db015c2a19 100644 --- a/src/lib/super-headers.spec.ts +++ b/src/lib/super-headers.spec.ts @@ -36,9 +36,17 @@ describe('SuperHeaders', () => { let headers2 = new SuperHeaders({ contentType: { mediaType: 'text/plain' }, lastModified: new Date('2021-01-01T00:00:00Z'), + setCookie: [ + { name: 'session', value: 'abc', path: '/' }, + { name: 'theme', value: 'dark', expires: new Date('2021-12-31T23:59:59Z') }, + ], }); assert.equal(headers2.get('Content-Type'), 'text/plain'); assert.equal(headers2.get('Last-Modified'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + assert.deepEqual(headers2.getSetCookie(), [ + 'session=abc; Path=/', + 'theme=dark; Expires=Fri, 31 Dec 2021 23:59:59 GMT', + ]); }); it('initializes from an array of key-value pairs', () => { From 7e1d0aa1e5d8048395fa956f6c902629a81db591 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 6 Aug 2024 01:46:09 -0700 Subject: [PATCH 196/730] Rename to @mjackson/headers --- README.md | 176 ++++++++++++++++++++++++++++++++++----------------- package.json | 9 +-- 2 files changed, 124 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 597017c3cd5..b261178697b 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,38 @@ -# fetch-super-headers +# headers -`SuperHeaders` is an enhanced JavaScript `Headers` interface with type-safe access. +`headers` is a toolkit for working with HTTP headers in JavaScript. -Another way to think about it is as a Swiss Army knife for HTTP headers. Whenever you need a spec-compliant, type-safe way to parse, modify, and stringify various HTTP headers and collections of them, SuperHeaders has you covered. +HTTP headers contain a wealth of information! -## Features +- Who is sending this request? +- What's in the payload and how is it encoded? +- What is the filename of this file upload? +- and much, much more! -This package is a suite of tools that make it a little more fun to work with `Headers`. - -- Strongly typed header-specific getters and setters (e.g., `headers.contentType`, `headers.setCookie`, etc.) -- Easy parsing and manipulation of complex headers like `Content-Disposition`, `Content-Type`, `Set-Cookie`, and more -- Iterable interface for easy header enumeration -- Convenient string conversion for HTTP message parsing and assembly -- Extends [the standard `Headers` class](https://developer.mozilla.org/en-US/docs/Web/API/Headers), so all `Headers` methods work as you'd expect +The list goes on and on. The [built-in JavaScript `Headers` interface](https://developer.mozilla.org/en-US/docs/Web/API/Headers) accepts and gives you strings for everything, which you're probably used to parsing and stringifying manually as needed. This library aims to give you a more fluent interface for all of this information. Similar to how the DOM gives you programmatic access to HTML documents, `headers` gives you access to HTTP headers. ## Installation ```sh -$ npm install fetch-super-headers +$ npm install @mjackson/headers ``` -## Usage - -fetch-super-headers is an enhanced interface for `Headers`, with some additions that make working with HTTP headers feel a lot more like working with JavaScript objects. +## Overview ```ts -import SuperHeaders from 'fetch-super-headers'; -// or, if you don't mind clobbering the global `Headers` reference: -// import Headers from `fetch-super-headers'; +import Headers from '@mjackson/headers'; -let headers = new SuperHeaders(); +let headers = new Headers(); // Content-Type headers.contentType = 'application/json; charset=utf-8'; -console.log(headers.contentType.mediaType); // 'application/json' -console.log(headers.contentType.charset); // 'utf-8' +console.log(headers.contentType.mediaType); // "application/json" +console.log(headers.contentType.charset); // "utf-8" headers.contentType.charset = 'iso-8859-1'; -// SuperHeaders *extends* Headers, so all methods of Headers work just -// as you'd expect them to. -console.log(headers.get('Content-Type')); // 'application/json; charset=iso-8859-1' +console.log(headers.get('Content-Type')); // "application/json; charset=iso-8859-1" // Content-Disposition headers.contentDisposition = @@ -87,29 +78,49 @@ for (let cookie of headers.getSetCookie()) { // user_id=12345; Path=/api; Secure ``` -You can easily build `SuperHeaders` from an exising `Headers` object, like the one you get in a `fetch` response: +`Headers` can be initialized with an object config: ```ts -let response = await fetch('https://example.com'); -let headers = new SuperHeaders(response.headers); +let headers = new Headers({ + contentType: { + mediaType: 'text/html', + charset: 'utf-8', + }, + setCookie: [ + { name: 'session', value: 'abc', path: '/' }, + { name: 'theme', value: 'dark', expires: new Date('2021-12-31T23:59:59Z') }, + ], +}); + +console.log(`${headers}`); +// Content-Type: text/html; charset=utf-8 +// Set-Cookie: session=abc; Path=/ +// Set-Cookie: theme=dark; Expires=Fri, 31 Dec 2021 23:59:59 GMT ``` -Or use them to construct a new `fetch` request, or even convert back to a normal `Headers` object: +`Headers` works just like [DOM's `Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers) (it's a subclass) so you can use them anywhere you need a `Headers`. ```ts -fetch('https://example.com', { - headers: new SuperHeaders(), +import Headers from '@mjackson/headers'; + +// Use in a fetch() +let response = await fetch('https://example.com', { + headers: new Headers(), }); -let headers = new Headers(new SuperHeaders()); +// Convert from DOM Headers +let headers = new Headers(response.headers); -assert.ok(new SuperHeaders() instanceof Headers); +headers.set('Content-Type', 'text/html'); +headers.get('Content-Type'); // "text/html" ``` -`SuperHeaders` are iterable: +If you're familiar with using DOM `Headers`, everything works as you'd expect. + +`Headers` are iterable: ```ts -let headers = new SuperHeaders({ +let headers = new Headers({ 'Content-Type': 'application/json', 'X-API-Key': 'secret-key', 'Accept-Language': 'en-US,en;q=0.9', @@ -126,40 +137,91 @@ for (let [name, value] of headers) { If you're assembling HTTP messages, you can easily convert to a multiline string suitable for using as a Request/Response header block: ```ts -let headers = new SuperHeaders(); -headers.set('Content-Type', 'text/html'); // or headers.contentType = 'text/html' -headers.set('X-Custom-Header', 'value'); +let headers = new Headers({ + 'Content-Type': 'application/json', + 'Accept-Language': 'en-US,en;q=0.9', +}); -console.log(headers.toString()); +console.log(`${headers}`); // Content-Type: text/html -// X-Custom-Header: value - -// Note: This varies from the built-in Headers class where you would normally -// get [object Headers] from toString(). +// Accept-Language: en-US,en;q=0.9 ``` -In addition to the high-level `SuperHeaders` API, fetch-super-headers also provides a rich set of primitives you can use to work with just about any complex HTTP header value. Each header class includes a spec-compliant parser (the constructor), stringifier (`toString`), and getters/setters for all relevant attributes. Classes for headers that contain a list of fields, like `Cookie`, are iterable. +## Low-level API + +In addition to the high-level `Headers` API, `headers` also provides a rich set of primitives you can use to work with just about any complex HTTP header value. Each header class includes a spec-compliant parser (the constructor), stringifier (`toString`), and getters/setters for all relevant attributes. Classes for headers that contain a list of fields, like `Cookie`, are `Iterable`. -All individual header classes may be initialized with either a) the string value of the header or b) an `init` object specific to that class. +All individual header classes may be initialized with either a) the string value of the header or b) an `init` object specific to that header. + +The following headers are supported: + +- [`Content-Disposition`](#content-disposition) +- [`Content-Type`](#content-type) +- [`Cookie`](#cookie) +- [`Set-Cookie`](#set-cookie) + +### Content-Type ```ts -import { ContentDisposition, ContentType, Cookie } from 'fetch-super-headers'; +import { ContentType } from '@mjackson/headers'; -// Parse a Content-Type header value -let contentType = new ContentType('text/html; charset=utf-8'); -console.log(contentType.charset); +let header = new ContentType('text/html; charset=utf-8'); +header.mediaType; // "text/html" +header.boundary; // undefined +header.charset; // "utf-8" -// Stringify a Content-Disposition header value -let contentDisposition = new ContentDisposition({ - type: 'attachment', - name: 'file1', - filename: 'file1.txt', +let header = new ContentType({ + mediaType: 'multipart/form-data', + boundary: '------WebKitFormBoundary12345', }); -console.log(`${contentDisposition}`); // "attachment; name=file1; filename=file1.txt" +``` -// Parse a Cookie header value and iterate over name/value pairs -let cookie = new Cookie('theme=dark; session_id=123'); -for (let [name, value] of cookie) { +### Content-Disposition + +```ts +import { ContentDisposition } from '@mjackson/headers'; + +let header = new ContentDisposition('attachment; name=file1; filename=file1.txt'); +header.type; // "attachment" +header.name; // "file1" +header.filename; // "file1.txt" +header.preferredFilename; // "file1.txt" +``` + +### Cookie + +```ts +import { Cookie } from '@mjackson/headers'; + +let header = new Cookie('theme=dark; session_id=123'); +header.get('theme'); // "dark" +header.set('theme', 'light'); +header.delete('theme'); +header.has('session_id'); // true + +// Iterate over cookie name/value pairs +for (let [name, value] of header) { // ... } ``` + +### Set-Cookie + +```ts +import { SetCookie } from '@mjackson/headers'; + +let header = new SetCookie('session_id=abc; Domain=example.com; Path=/; Secure; HttpOnly'); +header.name; // "session_id" +header.value; // "abc" +header.domain; // "example.com" +header.path; // "/" +header.secure; // true +header.httpOnly; // true +header.sameSite; // undefined +header.maxAge; // undefined +header.expires; // undefined +``` + +## License + +See [LICENSE](https://github.com/mjackson/headers/blob/main/LICENSE) diff --git a/package.json b/package.json index 080127493f4..ee756e481b8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "fetch-super-headers", + "name": "@mjackson/headers", "version": "0.4.1", - "description": "An enhanced JavaScript Headers interface type-safe access", + "description": "A toolkit for working with HTTP headers in JavaScript", "author": "Michael Jackson ", "license": "MIT", "files": [ @@ -22,12 +22,13 @@ "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", - "prepare": "npm run build", - "prepublishOnly": "npm run test" + "prepare": "npm run build" }, "packageManager": "pnpm@9.4.0", "keywords": [ "fetch", + "http", + "header", "headers" ] } From 286fe167e833b3ecc43f5c1d01240ab16c30796c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 6 Aug 2024 01:50:35 -0700 Subject: [PATCH 197/730] Add Prettier --- .prettierrc | 10 ++++------ package.json | 2 ++ pnpm-lock.yaml | 10 ++++++++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.prettierrc b/.prettierrc index 0aac4a10c5e..f018274ffc2 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,6 +1,4 @@ -{ - "printWidth": 100, - "singleQuote": true, - "semi": true, - "useTabs": false -} +printWidth: 100 +semi: true +singleQuote: true +useTabs: false diff --git a/package.json b/package.json index ee756e481b8..87aab0e660d 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,12 @@ }, "devDependencies": { "@types/node": "^20.14.10", + "prettier": "^3.3.3", "tsimp": "^2.0.11", "typescript": "^5.5.3" }, "scripts": { + "clean": "git clean -fdX .", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", "prepare": "npm run build" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a9d23a6c359..8f8380b0963 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@types/node': specifier: ^20.14.10 version: 20.14.10 + prettier: + specifier: ^3.3.3 + version: 3.3.3 tsimp: specifier: ^2.0.11 version: 2.0.11(typescript@5.5.3) @@ -128,6 +131,11 @@ packages: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + rimraf@5.0.9: resolution: {integrity: sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==} engines: {node: 14 >=14.20 || 16 >=16.20 || >=18} @@ -302,6 +310,8 @@ snapshots: pirates@4.0.6: {} + prettier@3.3.3: {} + rimraf@5.0.9: dependencies: glob: 10.4.5 From e45d36604072657e88f32c97eb876e1891c50656 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 6 Aug 2024 01:50:44 -0700 Subject: [PATCH 198/730] Add publish workflow --- .github/workflows/publish.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000000..1e2ee68c8b4 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,32 @@ +name: Publish + +on: + push: + tags: + - v[0-9]* + +jobs: + build: + runs-on: ubuntu-latest + + permissions: + contents: read + id-token: write + + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '20.x' + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - run: pnpm install + + - name: Publish to npm + run: npm publish --provenance --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From 0778cc5b80b51572c2c98996c7f083d6d282292a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 6 Aug 2024 01:53:49 -0700 Subject: [PATCH 199/730] Update README --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b261178697b..bc30ae7a6b6 100644 --- a/README.md +++ b/README.md @@ -153,13 +153,15 @@ In addition to the high-level `Headers` API, `headers` also provides a rich set All individual header classes may be initialized with either a) the string value of the header or b) an `init` object specific to that header. -The following headers are supported: +The following headers are currently supported: - [`Content-Disposition`](#content-disposition) - [`Content-Type`](#content-type) - [`Cookie`](#cookie) - [`Set-Cookie`](#set-cookie) +If you need support for a header that isn't listed here, please [send a PR](https://github.com/mjackson/headers/pulls)! The goal is to have first-class support for all common HTTP headers. + ### Content-Type ```ts From 892d17a76a233c75cfb0deca8156714a129774f1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 6 Aug 2024 01:58:18 -0700 Subject: [PATCH 200/730] Add repository to package.json --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 87aab0e660d..dee1917675a 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,10 @@ "description": "A toolkit for working with HTTP headers in JavaScript", "author": "Michael Jackson ", "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/mjackson/headers" + }, "files": [ "dist", "LICENSE", From 9038ed0e5694e64297e952502159f4198de14a0c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 6 Aug 2024 01:58:43 -0700 Subject: [PATCH 201/730] Version 0.5.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dee1917675a..9cc7d70f69b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/headers", - "version": "0.4.1", + "version": "0.5.0", "description": "A toolkit for working with HTTP headers in JavaScript", "author": "Michael Jackson ", "license": "MIT", From 714101ff2df68e444f7ac33ae31a7073733b6014 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 6 Aug 2024 08:15:51 -0700 Subject: [PATCH 202/730] Add CHANGELOG.md for version 0.5.0 --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000000..569959f15b1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,17 @@ +# `headers` CHANGELOG + +## v0.5.0 - Aug 6, 2024 + +- Added the ability to initialize a `SuperHeaders` instance with object config instead of just strings or header object instances. + +```ts +let headers = new Headers({ + contentType: { mediaType: 'text/html' }, + cookies: [ + ['session_id', 'abc'], + ['theme', 'dark'], + ], +}); +``` + +- Changed package name from `fetch-super-headers` to `@mjackson/headers`. Eventual goal is to get the `headers` npm package name. From d3ee213de213ef8d94b5105e041795885aa411c3 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 6 Aug 2024 08:16:38 -0700 Subject: [PATCH 203/730] fix: add CookieInit support to headers.cookie= --- CHANGELOG.md | 4 +++ src/lib/super-headers.spec.ts | 65 +++++++++++++++++++++++++++-------- src/lib/super-headers.ts | 6 ++-- 3 files changed, 57 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 569959f15b1..d153ed6d7cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # `headers` CHANGELOG +## HEAD + +- Added `CookieInit` support to `headers.cookie=` setter + ## v0.5.0 - Aug 6, 2024 - Added the ability to initialize a `SuperHeaders` instance with object config instead of just strings or header object instances. diff --git a/src/lib/super-headers.spec.ts b/src/lib/super-headers.spec.ts index 6db015c2a19..d1632ac9fa3 100644 --- a/src/lib/super-headers.spec.ts +++ b/src/lib/super-headers.spec.ts @@ -32,21 +32,6 @@ describe('SuperHeaders', () => { it('initializes from an object of property name/value pairs', () => { let headers = new SuperHeaders({ contentType: 'text/plain' }); assert.equal(headers.get('Content-Type'), 'text/plain'); - - let headers2 = new SuperHeaders({ - contentType: { mediaType: 'text/plain' }, - lastModified: new Date('2021-01-01T00:00:00Z'), - setCookie: [ - { name: 'session', value: 'abc', path: '/' }, - { name: 'theme', value: 'dark', expires: new Date('2021-12-31T23:59:59Z') }, - ], - }); - assert.equal(headers2.get('Content-Type'), 'text/plain'); - assert.equal(headers2.get('Last-Modified'), 'Fri, 01 Jan 2021 00:00:00 GMT'); - assert.deepEqual(headers2.getSetCookie(), [ - 'session=abc; Path=/', - 'theme=dark; Expires=Fri, 31 Dec 2021 23:59:59 GMT', - ]); }); it('initializes from an array of key-value pairs', () => { @@ -70,6 +55,41 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Content-Type'), 'text/plain'); }); + it('initializes with a ContentDispositionInit', () => { + let headers = new SuperHeaders({ + contentDisposition: { type: 'attachment', filename: 'example.txt' }, + }); + assert.equal(headers.get('Content-Disposition'), 'attachment; filename=example.txt'); + }); + + it('initializes with a ContentTypeInit', () => { + let headers = new SuperHeaders({ contentType: { mediaType: 'text/plain', charset: 'utf-8' } }); + assert.equal(headers.get('Content-Type'), 'text/plain; charset=utf-8'); + }); + + it('initializes with a CookieInit', () => { + let headers = new SuperHeaders({ cookie: [['name', 'value']] }); + assert.equal(headers.get('Cookie'), 'name=value'); + }); + + it('initializes with a SetCookieInit', () => { + let headers = new SuperHeaders({ + setCookie: [ + { name: 'session', value: 'abc', path: '/' }, + { name: 'theme', value: 'dark', expires: new Date('2021-12-31T23:59:59Z') }, + ], + }); + assert.deepEqual(headers.getSetCookie(), [ + 'session=abc; Path=/', + 'theme=dark; Expires=Fri, 31 Dec 2021 23:59:59 GMT', + ]); + }); + + it('initializes with a lastModified Date', () => { + let headers = new SuperHeaders({ lastModified: new Date('2021-01-01T00:00:00Z') }); + assert.equal(headers.get('Last-Modified'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + }); + it('appends values', () => { let headers = new SuperHeaders(); headers.append('X-Custom', 'value1'); @@ -180,6 +200,9 @@ describe('SuperHeaders', () => { headers.contentDisposition.filename = 'new.txt'; assert.equal(headers.get('Content-Disposition'), 'attachment; filename=new.txt'); + + headers.contentDisposition = { type: 'inline', filename: 'index.html' }; + assert.equal(headers.get('Content-Disposition'), 'inline; filename=index.html'); }); it('handles Content-Length header', () => { @@ -200,6 +223,9 @@ describe('SuperHeaders', () => { headers.contentType.charset = 'iso-8859-1'; assert.equal(headers.get('Content-Type'), 'text/plain; charset=iso-8859-1'); + + headers.contentType = { mediaType: 'text/html' }; + assert.equal(headers.get('Content-Type'), 'text/html'); }); it('handles Cookie header', () => { @@ -212,6 +238,9 @@ describe('SuperHeaders', () => { headers.cookie.set('name3', 'value3'); assert.equal(headers.get('Cookie'), 'name1=value1; name2=value2; name3=value3'); + + headers.cookie = [['name4', 'value4']]; + assert.equal(headers.get('Cookie'), 'name4=value4'); }); it('handles Expires header', () => { @@ -246,6 +275,12 @@ describe('SuperHeaders', () => { headers.setCookie = [...headers.setCookie, 'lang=en']; assert.equal(headers.get('Set-Cookie'), 'session=abc, theme=dark, lang=en'); + + headers.setCookie = [ + { name: 'session', value: 'def' }, + { name: 'theme', value: 'light' }, + ]; + assert.equal(headers.get('Set-Cookie'), 'session=def, theme=light'); }); it('creates empty header objects when accessed', () => { diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index 3598f9a6f97..3a628c7ff5a 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -168,7 +168,7 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> forEach( callback: (value: string, key: string, parent: SuperHeaders) => void, - thisArg?: any + thisArg?: any, ): void { for (let [key, value] of this) { callback.call(thisArg, value, key, this); @@ -223,7 +223,7 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> return this.#getHeaderValue('cookie', Cookie); } - set cookie(value: string | Cookie) { + set cookie(value: string | CookieInit) { this.#setHeaderValue('cookie', Cookie, value); } @@ -352,7 +352,7 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> #setHeaderValue( key: string, ctor: new (init?: string | T) => HeaderValue, - value: string | T + value: string | T, ): void { if (typeof value === 'string' || value instanceof ctor) { this.#map.set(key, value); From 656a31a77f72bbeca645fd85faf56ca999cc71d6 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 6 Aug 2024 02:06:30 -0700 Subject: [PATCH 204/730] Use @mjackson/headers --- CHANGELOG.md | 5 +++++ package.json | 2 +- pnpm-lock.yaml | 16 ++++++++-------- src/lib/multipart.ts | 8 ++++---- src/test/utils.ts | 44 +++++++++++++++++++++++++------------------- 5 files changed, 43 insertions(+), 32 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000000..79fb2bb0fee --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# `multipart-parser` CHANGELOG + +## HEAD + +- Switch dependency from `fetch-super-headers` to `@mjackson/headers` diff --git a/package.json b/package.json index ebfb393741b..59a3343b4ef 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "./package.json": "./package.json" }, "dependencies": { - "fetch-super-headers": "^0.4.1" + "@mjackson/headers": "^0.5.0" }, "devDependencies": { "@types/node": "^20.14.10", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b641219c830..eea38de52ca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,9 @@ importers: .: dependencies: - fetch-super-headers: - specifier: ^0.4.1 - version: 0.4.1 + '@mjackson/headers': + specifier: ^0.5.0 + version: 0.5.0 devDependencies: '@types/node': specifier: ^20.14.10 @@ -317,6 +317,9 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@mjackson/headers@0.5.0': + resolution: {integrity: sha512-aRlcySUJXTm2krQbXMXhOOPdCWN0dtIL4Y0M1veLqp0ObjslNSJ2ttKN2W0+9gE01MUo5UgtwSXq8UMhMifytQ==} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -467,9 +470,6 @@ packages: resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} engines: {node: '>=6'} - fetch-super-headers@0.4.1: - resolution: {integrity: sha512-jXB/p3m6iMeDFhHpJ56BgqrvoDIiyueNPF39twy2N63DMcme0imKhGoEZH8AAbnplnggU9OdUs9eFFPZxPULFA==} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -929,6 +929,8 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@mjackson/headers@0.5.0': {} + '@pkgjs/parseargs@0.11.0': optional: true @@ -1088,8 +1090,6 @@ snapshots: exit-hook@2.2.1: {} - fetch-super-headers@0.4.1: {} - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index d8f7c697134..ca1a6903824 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -1,4 +1,4 @@ -import { SuperHeaders } from 'fetch-super-headers'; +import Headers from '@mjackson/headers'; import { concat, computeSkipTable, combinedIndexOf } from './buffer-utils.js'; @@ -423,7 +423,7 @@ export class MultipartPart { #header: Uint8Array; #body: ReadableStream; - #headers?: SuperHeaders; + #headers?: Headers; #bodyUsed = false; constructor(header: Uint8Array, body: ReadableStream) { @@ -481,9 +481,9 @@ export class MultipartPart { /** * The headers associated with this part. */ - get headers(): SuperHeaders { + get headers(): Headers { if (!this.#headers) { - this.#headers = new SuperHeaders(new TextDecoder().decode(this.#header)); + this.#headers = new Headers(new TextDecoder().decode(this.#header)); } return this.#headers; diff --git a/src/test/utils.ts b/src/test/utils.ts index d6a970e8154..b8bb081e507 100644 --- a/src/test/utils.ts +++ b/src/test/utils.ts @@ -1,4 +1,4 @@ -import { ContentDisposition, ContentType, SuperHeaders } from 'fetch-super-headers'; +import Headers from '@mjackson/headers'; import { concat } from '../lib/buffer-utils.js'; @@ -64,28 +64,31 @@ export function createMultipartBody( pushLine(`--${boundary}`); if (typeof part === 'string') { - let contentDisposition = new ContentDisposition(); - contentDisposition.type = 'form-data'; - contentDisposition.name = name; - pushLine(`Content-Disposition: ${contentDisposition}`); + let headers = new Headers({ + contentDisposition: { + type: 'form-data', + name, + }, + }); + + pushLine(`${headers}`); pushLine(); pushLine(part); } else { - let contentDisposition = new ContentDisposition(); - contentDisposition.type = 'form-data'; - contentDisposition.name = name; - contentDisposition.filename = part.filename; - contentDisposition.filenameSplat = part.filenameSplat; - - pushLine(`Content-Disposition: ${contentDisposition}`); + let headers = new Headers({ + contentDisposition: { + type: 'form-data', + name, + filename: part.filename, + filenameSplat: part.filenameSplat, + }, + }); if (part.mediaType) { - let contentType = new ContentType(); - contentType.mediaType = part.mediaType; - - pushLine(`Content-Type: ${contentType}`); + headers.contentType = part.mediaType; } + pushLine(`${headers}`); pushLine(); if (typeof part.content === 'string') { pushLine(part.content); @@ -106,9 +109,12 @@ export function createMultipartMockRequest( boundary: string, parts?: { [name: string]: PartValue }, ): Request { - let headers = new SuperHeaders(); - headers.contentType.mediaType = 'multipart/form-data'; - headers.contentType.boundary = boundary; + let headers = new Headers({ + contentType: { + mediaType: 'multipart/form-data', + boundary, + }, + }); let body = createMultipartBody(boundary, parts); From 68e043d55a87f58077faf8ba31438a28ba858e0e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 6 Aug 2024 08:44:49 -0700 Subject: [PATCH 205/730] Version 0.5.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9cc7d70f69b..87e8c192d92 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/headers", - "version": "0.5.0", + "version": "0.5.1", "description": "A toolkit for working with HTTP headers in JavaScript", "author": "Michael Jackson ", "license": "MIT", From 91d8fe0fa71a8cdb0cbf9242c5832c80449bb588 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 6 Aug 2024 08:45:16 -0700 Subject: [PATCH 206/730] Update CHANGELOG for v0.5.1 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d153ed6d7cf..aac72383a37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # `headers` CHANGELOG -## HEAD +## v0.5.1 - Aug 6, 2024 - Added `CookieInit` support to `headers.cookie=` setter From c1376ec7520767e4fee5956e04f86f40e0d4c1ee Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 6 Aug 2024 12:54:12 -0700 Subject: [PATCH 207/730] Use Connection: close on node Minor updates to other examples as well --- examples/bun/server.ts | 25 ++++++++++++++++++------- examples/cf-workers/src/index.ts | 2 +- examples/deno/main.ts | 2 +- examples/node/server.js | 14 +++++--------- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/examples/bun/server.ts b/examples/bun/server.ts index a319a89f3ec..5dfa6f287dc 100644 --- a/examples/bun/server.ts +++ b/examples/bun/server.ts @@ -58,7 +58,7 @@ const server = Bun.serve({ }); } catch (error) { if (error instanceof MultipartParseError) { - return new Response(error.message, { status: 400 }); + return new Response(`Error: ${error.message}`, { status: 400 }); } console.error(error); @@ -74,18 +74,29 @@ const server = Bun.serve({ console.log(`Server listening on http://localhost:${server.port} ...`); async function writeFile(file: BunFile, stream: ReadableStream): Promise { - let reader = stream.getReader(); let writer = file.writer(); let bytesWritten = 0; - while (true) { - const { done, value } = await reader.read(); - if (done) break; - writer.write(value); - bytesWritten += value.byteLength; + for await (let chunk of readStream(stream)) { + writer.write(chunk); + bytesWritten += chunk.byteLength; } await writer.end(); return bytesWritten; } + +async function* readStream(stream: ReadableStream): AsyncGenerator { + let reader = stream.getReader(); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + yield value; + } + } finally { + reader.releaseLock(); + } +} diff --git a/examples/cf-workers/src/index.ts b/examples/cf-workers/src/index.ts index 1c2ed26a7f5..2c8953ab72a 100644 --- a/examples/cf-workers/src/index.ts +++ b/examples/cf-workers/src/index.ts @@ -73,7 +73,7 @@ export default { }); } catch (error) { if (error instanceof MultipartParseError) { - return new Response(error.message, { status: 400 }); + return new Response(`Error: ${error.message}`, { status: 400 }); } console.error(error); diff --git a/examples/deno/main.ts b/examples/deno/main.ts index 782baeb855a..a3fb88ba406 100644 --- a/examples/deno/main.ts +++ b/examples/deno/main.ts @@ -67,7 +67,7 @@ Deno.serve( }); } catch (error) { if (error instanceof MultipartParseError) { - return new Response('Bad Request', { status: 400 }); + return new Response(`Error: ${error.message}`, { status: 400 }); } console.error(error); diff --git a/examples/node/server.js b/examples/node/server.js index 4e26395b305..f9bc2d2a46b 100644 --- a/examples/node/server.js +++ b/examples/node/server.js @@ -9,9 +9,7 @@ const PORT = 3000; const server = http.createServer(async (req, res) => { if (req.method === 'GET') { - res.writeHead(200, { - 'Content-Type': 'text/html', - }); + res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(` @@ -60,21 +58,19 @@ const server = http.createServer(async (req, res) => { } } - res.writeHead(200, { - 'Content-Type': 'application/json', - }); + res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ parts }, null, 2)); return; } catch (error) { if (error instanceof MultipartParseError) { - res.writeHead(400); - res.end('Bad Request'); + res.writeHead(400, { 'Content-Type': 'text/plain', Connection: 'close' }); + res.end(`Error: ${error.message}`); return; } console.error(error); - res.writeHead(500); + res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end('Internal Server Error'); } } From 43d9a7d6ec9b38c22b9c3a39b801778fa515b408 Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Tue, 6 Aug 2024 17:02:37 -0600 Subject: [PATCH 208/730] docs: remove `$` from shell commands So you don't have to remove them when triple clicking the line to copy or clicking the copy button in GitHub. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 399780c86be..4588b73ba86 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,13 @@ The goals of this project are: Install from [npm](https://www.npmjs.com/): ```sh -$ npm install @mjackson/multipart-parser +npm install @mjackson/multipart-parser ``` Or install from [JSR](https://jsr.io/): ```sh -$ deno add @mjackson/multipart-parser +deno add @mjackson/multipart-parser ``` ## Usage From 717775b84259071a59cd7cc2040b1a72fd51ac8e Mon Sep 17 00:00:00 2001 From: Alex Anderson Date: Fri, 9 Aug 2024 13:05:02 -0400 Subject: [PATCH 209/730] Add Cache Control header implementation. --- src/headers.ts | 1 + src/lib/cache-control.spec.ts | 54 ++++++ src/lib/cache-control.ts | 308 ++++++++++++++++++++++++++++++++++ src/lib/param-values.ts | 8 +- src/lib/super-headers.spec.ts | 23 +++ src/lib/super-headers.ts | 10 ++ 6 files changed, 403 insertions(+), 1 deletion(-) create mode 100644 src/lib/cache-control.spec.ts create mode 100644 src/lib/cache-control.ts diff --git a/src/headers.ts b/src/headers.ts index a689791e5b4..740a182be19 100644 --- a/src/headers.ts +++ b/src/headers.ts @@ -2,5 +2,6 @@ export { ContentDispositionInit, ContentDisposition } from './lib/content-dispos export { ContentTypeInit, ContentType } from './lib/content-type.js'; export { CookieInit, Cookie } from './lib/cookie.js'; export { SetCookieInit, SetCookie } from './lib/set-cookie.js'; +export { CacheControlInit, CacheControl } from './lib/cache-control.js'; export { SuperHeaders as default, SuperHeadersInit, SuperHeaders } from './lib/super-headers.js'; diff --git a/src/lib/cache-control.spec.ts b/src/lib/cache-control.spec.ts new file mode 100644 index 00000000000..d4f6fc6a88e --- /dev/null +++ b/src/lib/cache-control.spec.ts @@ -0,0 +1,54 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { CacheControl } from './cache-control.js'; + +describe('CacheControl', () => { + it('initializes with an empty string', () => { + let header = new CacheControl(''); + assert.equal(header.maxAge, undefined); + assert.equal(header.public, undefined); + assert.equal(`${header}`, ''); + }); + it('initializes with a string', () => { + let header = new CacheControl('public, max-age=3600, s-maxage=3600'); + assert.equal(header.maxAge, 3600); + assert.equal(header.sMaxage, 3600); + assert.equal(header.public, true); + }); + it('initializes with an object', () => { + let header = new CacheControl({ public: true, maxAge: 3600, sMaxage: 3600 }); + assert.equal(header.maxAge, 3600); + assert.equal(header.sMaxage, 3600); + assert.equal(header.public, true); + }); + it('initializes with another CacheControl', () => { + let header = new CacheControl(new CacheControl('public, max-age=3600, s-maxage=3600')); + assert.equal(header.maxAge, 3600); + assert.equal(header.sMaxage, 3600); + assert.equal(header.public, true); + }); + it('handles whitespace in initial value', () => { + let header = new CacheControl(' public , max-age = 3600, s-maxage=3600 '); + assert.equal(header.maxAge, 3600); + assert.equal(header.sMaxage, 3600); + assert.equal(header.public, true); + }); + it('sets and gets attributes', () => { + let header = new CacheControl(''); + header.maxAge = 3600; + header.sMaxage = 3600; + header.public = true; + assert.equal(header.maxAge, 3600); + assert.equal(header.sMaxage, 3600); + assert.equal(header.public, true); + }); + it('converts to a string properly', () => { + let header = new CacheControl('public, max-age=3600, s-maxage=3600'); + assert.equal(header.toString(), 'public, max-age=3600, s-maxage=3600'); + }); + it('sets numerical values to 0 instead of omitting them', () => { + let header = new CacheControl(); + header.maxAge = 0; + assert.equal(header.toString(), 'max-age=0'); + }); +}); diff --git a/src/lib/cache-control.ts b/src/lib/cache-control.ts new file mode 100644 index 00000000000..36048ae603d --- /dev/null +++ b/src/lib/cache-control.ts @@ -0,0 +1,308 @@ +import { HeaderValue } from './header-value.js'; +import { parseParams } from './param-values.js'; + +// Taken from https://github.com/jjenzz/pretty-cache-header by jjenzz +// License: MIT https://github.com/jjenzz/pretty-cache-header/blob/main/LICENSE +export type CacheControlInit = { + /** + * The `max-age=N` **request directive** indicates that the client allows a stored response that + * is generated on the origin server within _N_ seconds — where _N_ may be any non-negative + * integer (including `0`). + * + * The `max-age=N` **response directive** indicates that the response remains + * [fresh](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age) + * until _N_ seconds after the response is generated. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#max-age + */ + maxAge?: number; + /** + * The `max-stale=N` **request directive** indicates that the client allows a stored response + * that is [stale](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age) + * within _N_ seconds. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#max-stale + */ + maxStale?: number; + /** + * The `min-fresh=N` **request directive** indicates that the client allows a stored response + * that is [fresh](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age) + * for at least _N_ seconds. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#min-fresh + */ + minFresh?: number; + /** + * The `s-maxage` **response directive** also indicates how long the response is + * [fresh](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age) for (similar to `max-age`) — + * but it is specific to shared caches, and they will ignore `max-age` when it is present. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#s-maxage + */ + sMaxage?: number; + /** + * The `no-cache` **request directive** asks caches to validate the response with the origin + * server before reuse. If you want caches to always check for content updates while reusing + * stored content, `no-cache` is the directive to use. + * + * The `no-cache` **response directive** indicates that the response can be stored in caches, but + * the response must be validated with the origin server before each reuse, even when the cache + * is disconnected from the origin server. + * + * `no-cache` allows clients to request the most up-to-date response even if the cache has a + * [fresh](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age) + * response. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#no-cache + */ + noCache?: true; + /** + * The `no-store` **request directive** allows a client to request that caches refrain from + * storing the request and corresponding response — even if the origin server's response could + * be stored. + * + * The `no-store` **response directive** indicates that any caches of any kind (private or shared) + * should not store this response. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#no-store + */ + noStore?: true; + /** + * `no-transform` indicates that any intermediary (regardless of whether it implements a cache) + * shouldn't transform the response contents. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#no-transform + */ + noTransform?: true; + /** + * The client indicates that cache should obtain an already-cached response. If a cache has + * stored a response, it's reused. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#only-if-cached + */ + onlyIfCached?: true; + /** + * The `must-revalidate` **response directive** indicates that the response can be stored in + * caches and can be reused while [fresh](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age). + * If the response becomes [stale](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age), + * it must be validated with the origin server before reuse. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#must-revalidate + */ + mustRevalidate?: true; + /** + * The `proxy-revalidate` **response directive** is the equivalent of `must-revalidate`, but + * specifically for shared caches only. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#proxy-revalidate + */ + proxyRevalidate?: true; + /** + * The `must-understand` **response directive** indicates that a cache should store the response + * only if it understands the requirements for caching based on status code. + * + * `must-understand` should be coupled with `no-store` for fallback behavior. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#must-understand + */ + mustUnderstand?: true; + /** + * The `private` **response directive** indicates that the response can be stored only in a + * private cache (e.g. local caches in browsers). + * + * You should add the `private` directive for user-personalized content, especially for responses + * received after login and for sessions managed via cookies. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#private + */ + private?: true; + /** + * The `public` **response directive** indicates that the response can be stored in a shared + * cache. Responses for requests with `Authorization` header fields must not be stored in a + * shared cache; however, the `public` directive will cause such responses to be stored in a + * shared cache. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#public + */ + public?: true; + /** + * The `immutable` **response directive** indicates that the response will not be updated while + * it's [fresh](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age). + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#public + */ + immutable?: true; + /** + * The `stale-while-revalidate` **response directive** indicates that the cache could reuse a + * stale response while it revalidates it to a cache. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate + */ + staleWhileRevalidate?: number; + /** + * The `stale-if-error` **response directive** indicates that the cache can reuse a + * [stale response](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age) + * when an upstream server generates an error, or when the error is generated locally. Here, an + * error is considered any response with a status code of 500, 502, 503, or 504. + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-if-error + */ + staleIfError?: number; +}; + +export class CacheControl implements HeaderValue, CacheControlInit { + maxAge?: number; + maxStale?: number; + minFresh?: number; + sMaxage?: number; + noCache?: true; + noStore?: true; + noTransform?: true; + onlyIfCached?: true; + mustRevalidate?: true; + proxyRevalidate?: true; + mustUnderstand?: true; + private?: true; + public?: true; + immutable?: true; + staleWhileRevalidate?: number; + staleIfError?: number; + + /** + * The value of a `Cache-Control` HTTP header. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) + */ + constructor(init?: string | CacheControlInit) { + if (init) { + if (typeof init === 'string') { + let params = parseParams(init, ','); + if (params.length > 0) { + for (let [name, value] of params) { + switch (name) { + case 'max-age': + this.maxAge = Number(value); + break; + case 'max-stale': + this.maxStale = Number(value); + break; + case 'min-fresh': + this.minFresh = Number(value); + break; + case 's-maxage': + this.sMaxage = Number(value); + break; + case 'no-cache': + this.noCache = true; + break; + case 'no-store': + this.noStore = true; + break; + case 'no-transform': + this.noTransform = true; + break; + case 'only-if-cached': + this.onlyIfCached = true; + break; + case 'must-revalidate': + this.mustRevalidate = true; + break; + case 'proxy-revalidate': + this.proxyRevalidate = true; + break; + case 'must-understand': + this.mustUnderstand = true; + break; + case 'private': + this.private = true; + break; + case 'public': + this.public = true; + break; + case 'immutable': + this.immutable = true; + break; + case 'stale-while-revalidate': + this.staleWhileRevalidate = Number(value); + break; + case 'stale-if-error': + this.staleIfError = Number(value); + break; + } + } + } + } else { + this.maxAge = init.maxAge; + this.maxStale = init.maxStale; + this.minFresh = init.minFresh; + this.sMaxage = init.sMaxage; + this.noCache = init.noCache; + this.noStore = init.noStore; + this.noTransform = init.noTransform; + this.onlyIfCached = init.onlyIfCached; + this.mustRevalidate = init.mustRevalidate; + this.proxyRevalidate = init.proxyRevalidate; + this.mustUnderstand = init.mustUnderstand; + this.private = init.private; + this.public = init.public; + this.immutable = init.immutable; + this.staleWhileRevalidate = init.staleWhileRevalidate; + this.staleIfError = init.staleIfError; + } + } + } + + toString(): string { + let parts = []; + + if (this.public) { + parts.push('public'); + } + if (this.private) { + parts.push('private'); + } + if (typeof this.maxAge === 'number') { + parts.push(`max-age=${this.maxAge}`); + } + if (typeof this.sMaxage === 'number') { + parts.push(`s-maxage=${this.sMaxage}`); + } + if (this.noCache) { + parts.push('no-cache'); + } + if (this.noStore) { + parts.push('no-store'); + } + if (this.noTransform) { + parts.push('no-transform'); + } + if (this.onlyIfCached) { + parts.push('only-if-cached'); + } + if (this.mustRevalidate) { + parts.push('must-revalidate'); + } + if (this.proxyRevalidate) { + parts.push('proxy-revalidate'); + } + if (this.mustUnderstand) { + parts.push('must-understand'); + } + if (this.immutable) { + parts.push('immutable'); + } + if (typeof this.staleWhileRevalidate === 'number') { + parts.push(`stale-while-revalidate=${this.staleWhileRevalidate}`); + } + if (typeof this.staleIfError === 'number') { + parts.push(`stale-if-error=${this.staleIfError}`); + } + if (typeof this.maxStale === 'number') { + parts.push(`max-stale=${this.maxStale}`); + } + if (typeof this.minFresh === 'number') { + parts.push(`min-fresh=${this.minFresh}`); + } + return parts.join(', '); + } +} diff --git a/src/lib/param-values.ts b/src/lib/param-values.ts index 4fff2f32ee7..fa1391d6b45 100644 --- a/src/lib/param-values.ts +++ b/src/lib/param-values.ts @@ -1,5 +1,11 @@ -export function parseParams(input: string): [string, string | undefined][] { +export function parseParams( + input: string, + delimiter: ';' | ',' = ';', +): [string, string | undefined][] { let regex = /(?:^|;)\s*([^=;\s]+)(\s*=\s*(?:"((?:[^"\\]|\\.)*)"|((?:[^;]|\\\;)+))?)?/g; + if (delimiter === ',') { + regex = /(?:^|,)\s*([^=,\s]+)(\s*=\s*(?:"((?:[^"\\]|\\.)*)"|((?:[^,]|\\\,)+))?)?/g; + } let params: [string, string | undefined][] = []; let match; diff --git a/src/lib/super-headers.spec.ts b/src/lib/super-headers.spec.ts index d1632ac9fa3..b092da96e9b 100644 --- a/src/lib/super-headers.spec.ts +++ b/src/lib/super-headers.spec.ts @@ -5,6 +5,7 @@ import { ContentDisposition } from './content-disposition.js'; import { ContentType } from './content-type.js'; import { Cookie } from './cookie.js'; import { SuperHeaders } from './super-headers.js'; +import { CacheControl } from './cache-control.js'; describe('SuperHeaders', () => { it('is an instance of Headers', () => { @@ -55,6 +56,11 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Content-Type'), 'text/plain'); }); + it('initializes with a CacheControlInit', () => { + let headers = new SuperHeaders({ cacheControl: 'public, max-age=3600' }); + assert.equal(headers.get('Cache-Control'), 'public, max-age=3600'); + }); + it('initializes with a ContentDispositionInit', () => { let headers = new SuperHeaders({ contentDisposition: { type: 'attachment', filename: 'example.txt' }, @@ -190,6 +196,20 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Age'), '42'); }); + it('handles Cache-Control header', () => { + let headers = new SuperHeaders(); + headers.cacheControl = 'public, max-age=3600'; + + assert.ok(headers.cacheControl instanceof CacheControl); + assert.equal(headers.cacheControl.toString(), 'public, max-age=3600'); + + headers.cacheControl.maxAge = 1800; + assert.equal(headers.get('Cache-Control'), 'public, max-age=1800'); + + headers.cacheControl = { noCache: true, noStore: true }; + assert.equal(headers.get('Cache-Control'), 'no-cache, no-store'); + }); + it('handles Content-Disposition header', () => { let headers = new SuperHeaders(); headers.contentDisposition = 'attachment; filename="example.txt"'; @@ -286,6 +306,9 @@ describe('SuperHeaders', () => { it('creates empty header objects when accessed', () => { let headers = new SuperHeaders(); + assert.ok(headers.cacheControl instanceof CacheControl); + assert.equal(headers.cacheControl.toString(), ''); + assert.ok(headers.contentDisposition instanceof ContentDisposition); assert.equal(headers.contentDisposition.toString(), ''); diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index 3a628c7ff5a..1cbde87355e 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -1,3 +1,4 @@ +import { CacheControl, CacheControlInit } from './cache-control.js'; import { ContentDispositionInit, ContentDisposition } from './content-disposition.js'; import { ContentTypeInit, ContentType } from './content-type.js'; import { CookieInit, Cookie } from './cookie.js'; @@ -21,6 +22,7 @@ interface SuperHeadersPropertyInit { ifUnmodifiedSince?: string | Date; lastModified?: string | Date; setCookie?: string | (string | SetCookieInit)[]; + cacheControl?: string | CacheControlInit; } export type SuperHeadersInit = @@ -195,6 +197,14 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.#map.set('age', value); } + get cacheControl(): CacheControl { + return this.#getHeaderValue('cache-control', CacheControl); + } + + set cacheControl(value: string | CacheControlInit) { + this.#setHeaderValue('cache-control', CacheControl, value); + } + get contentDisposition(): ContentDisposition { return this.#getHeaderValue('content-disposition', ContentDisposition); } From 8991e6617e39b60776b7900bb3a02404b5b9d55c Mon Sep 17 00:00:00 2001 From: m4rc3l05 <15786310+M4RC3L05@users.noreply.github.com> Date: Sun, 11 Aug 2024 16:00:23 +0100 Subject: [PATCH 210/730] Add type export modifier to `MultipartParserOptions` interface Its appers that with deno and using the jsr package, if the named export does not contain the type keyworkd, it throw an error of `The requested module './lib/multipart.ts' does not provide an export named 'MultipartParserOptions'`. Adding the type keyworkd seems to fix it. Signed-off-by: m4rc3l05 <15786310+M4RC3L05@users.noreply.github.com> --- src/multipart-parser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/multipart-parser.ts b/src/multipart-parser.ts index 57460076ffe..6b24ef81e3b 100644 --- a/src/multipart-parser.ts +++ b/src/multipart-parser.ts @@ -4,7 +4,7 @@ export { parseMultipartRequest, parseMultipart, MultipartParseError, - MultipartParserOptions, + type MultipartParserOptions, MultipartParser, MultipartPart, } from './lib/multipart.js'; From db37d8a329d43e19b05dd31da898105908dbdae1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 12 Aug 2024 15:56:59 -0700 Subject: [PATCH 211/730] Small wording tweaks --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bc30ae7a6b6..31f73313ba8 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,14 @@ `headers` is a toolkit for working with HTTP headers in JavaScript. -HTTP headers contain a wealth of information! +HTTP headers contain a wealth of information: - Who is sending this request? - What's in the payload and how is it encoded? - What is the filename of this file upload? - and much, much more! -The list goes on and on. The [built-in JavaScript `Headers` interface](https://developer.mozilla.org/en-US/docs/Web/API/Headers) accepts and gives you strings for everything, which you're probably used to parsing and stringifying manually as needed. This library aims to give you a more fluent interface for all of this information. Similar to how the DOM gives you programmatic access to HTML documents, `headers` gives you access to HTTP headers. +The [built-in JavaScript `Headers` interface](https://developer.mozilla.org/en-US/docs/Web/API/Headers) accepts and gives you strings for everything, which you're probably used to parsing and stringifying manually as needed. This library aims to give you a more fluent interface for all of this information. Similar to how the DOM gives you programmatic access to HTML documents, `headers` gives you access to HTTP headers. ## Installation From a49790b450f18d443487de00809643171f817da4 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 12 Aug 2024 15:57:10 -0700 Subject: [PATCH 212/730] Small capitalization tweak --- src/lib/super-headers.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/super-headers.spec.ts b/src/lib/super-headers.spec.ts index d1632ac9fa3..04dbc7114df 100644 --- a/src/lib/super-headers.spec.ts +++ b/src/lib/super-headers.spec.ts @@ -15,7 +15,7 @@ describe('SuperHeaders', () => { it('initializes with no arguments', () => { let headers = new SuperHeaders(); - assert.equal(headers.get('content-type'), null); + assert.equal(headers.get('Content-Type'), null); }); it('initializes from a string', () => { From cacaecc8a877f98eb881366a5586aef3379ed520 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 12 Aug 2024 20:40:52 -0700 Subject: [PATCH 213/730] Use `for await...of` for ReadableStream iteration --- CHANGELOG.md | 1 + src/lib/global.d.ts | 6 ++++++ src/lib/multipart.ts | 33 ++++++--------------------------- 3 files changed, 13 insertions(+), 27 deletions(-) create mode 100644 src/lib/global.d.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 79fb2bb0fee..ca420691f51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,3 +3,4 @@ ## HEAD - Switch dependency from `fetch-super-headers` to `@mjackson/headers` +- Use `for await...of` to iterate over `ReadableStream` internally. This will also cancel the stream when the loop exits from e.g. an error in a user-defined `part` handler. diff --git a/src/lib/global.d.ts b/src/lib/global.d.ts new file mode 100644 index 00000000000..b8041179bc5 --- /dev/null +++ b/src/lib/global.d.ts @@ -0,0 +1,6 @@ +// See https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62651 + +interface ReadableStream { + values(options?: { preventCancel?: boolean }): AsyncIterableIterator; + [Symbol.asyncIterator](): AsyncIterableIterator; +} diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index ca1a6903824..ad08c310d3c 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -169,20 +169,11 @@ export class MultipartParser { let results = []; - if (data instanceof ReadableStream) { - let reader = data.getReader(); - - try { - while (true) { - const { done, value } = await reader.read(); - if (done) break; - - for (let part of this.push(value)) { - results.push(handler(part)); - } + if (data instanceof ReadableStream || isAsyncIterable(data)) { + for await (let chunk of data) { + for (let part of this.push(chunk)) { + results.push(handler(part)); } - } finally { - reader.releaseLock(); } } else if (data instanceof Uint8Array) { for (let part of this.push(data)) { @@ -194,12 +185,6 @@ export class MultipartParser { results.push(handler(part)); } } - } else if (isAsyncIterable(data)) { - for await (let chunk of data) { - for (let part of this.push(chunk)) { - results.push(handler(part)); - } - } } else { throw new TypeError('Cannot parse data: expected a stream or buffer'); } @@ -464,17 +449,11 @@ export class MultipartPart { this.#bodyUsed = true; - let reader = this.#body.getReader(); let chunks: Uint8Array[] = []; - - while (true) { - const { done, value } = await reader.read(); - if (done) break; - chunks.push(value); + for await (let chunk of this.#body) { + chunks.push(chunk); } - reader.releaseLock(); - return concat(chunks); } From 7b2e415a1d5850a4d601566b99d0304aba0735e2 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 12 Aug 2024 21:58:17 -0700 Subject: [PATCH 214/730] Add version script --- .github/workflows/publish.yml | 8 -------- package.json | 3 ++- scripts/sync-jsr-version.js | 14 ------------- scripts/version.js | 37 +++++++++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 23 deletions(-) delete mode 100644 scripts/sync-jsr-version.js create mode 100644 scripts/version.js diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 185b3a75bb8..b80f53a3ce9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -31,13 +31,5 @@ jobs: env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - run: node scripts/sync-jsr-version.js - - - uses: stefanzweifel/git-auto-commit-action@v5 - with: - branch: main - commit_message: Sync JSR package version - file_pattern: jsr.json - - name: Publish to JSR run: npx jsr publish diff --git a/package.json b/package.json index 59a3343b4ef..bb682ff3f27 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,8 @@ "bench:node": "node --import tsimp/import ./bench/runner.ts", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", - "prepare": "npm run build" + "prepare": "npm run build", + "version": "node scripts/version.js" }, "packageManager": "pnpm@9.4.0", "keywords": [ diff --git a/scripts/sync-jsr-version.js b/scripts/sync-jsr-version.js deleted file mode 100644 index 07ec1e079ae..00000000000 --- a/scripts/sync-jsr-version.js +++ /dev/null @@ -1,14 +0,0 @@ -import * as fs from 'node:fs/promises'; -import * as path from 'node:path'; - -const __dirname = path.dirname(new URL(import.meta.url).pathname); - -let packageJsonPath = path.resolve(__dirname, '../package.json'); -let jsrJsonPath = path.resolve(__dirname, '../jsr.json'); - -let packageVersion = JSON.parse(await fs.readFile(packageJsonPath)).version; - -let jsrJson = JSON.parse(await fs.readFile(jsrJsonPath)); -jsrJson.version = packageVersion; - -await fs.writeFile(jsrJsonPath, JSON.stringify(jsrJson, null, 2) + '\n'); diff --git a/scripts/version.js b/scripts/version.js new file mode 100644 index 00000000000..5b1a9f69165 --- /dev/null +++ b/scripts/version.js @@ -0,0 +1,37 @@ +import * as cp from 'node:child_process'; +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import * as process from 'node:process'; + +const __dirname = path.dirname(new URL(import.meta.url).pathname); +const packageVersion = process.env.npm_package_version; + +// Update jsr.json with the current version +let jsrJsonPath = path.resolve(__dirname, '../jsr.json'); +let jsrJson = JSON.parse(fs.readFileSync(jsrJsonPath, 'utf-8')); +jsrJson.version = packageVersion; +fs.writeFileSync(jsrJsonPath, JSON.stringify(jsrJson, null, 2) + '\n'); +cp.execSync('git add jsr.json'); + +// Update CHANGELOG.md with the current version +let changelogPath = path.resolve(__dirname, '../CHANGELOG.md'); +let changelog = fs.readFileSync(changelogPath, 'utf-8'); +let match = /^## HEAD\n/m.exec(changelog); +if (match) { + let today = new Date().toLocaleDateString('en-US', { + month: 'short', + day: 'numeric', + year: 'numeric', + }); + + changelog = + changelog.slice(0, match.index) + + `## v${packageVersion} (${today})\n` + + changelog.slice(match.index + match[0].length); + + fs.writeFileSync(changelogPath, changelog); + cp.execSync('git add CHANGELOG.md'); +} else { + console.error('Could not find "## HEAD" in CHANGELOG.md'); + process.exit(1); +} From c381545352c206905d6e9d3b6d11f8b855a8414f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 12 Aug 2024 22:46:30 -0700 Subject: [PATCH 215/730] Version 0.4.0 --- CHANGELOG.md | 2 +- jsr.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca420691f51..af3a69f6516 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # `multipart-parser` CHANGELOG -## HEAD +## v0.4.0 (Aug 12, 2024) - Switch dependency from `fetch-super-headers` to `@mjackson/headers` - Use `for await...of` to iterate over `ReadableStream` internally. This will also cancel the stream when the loop exits from e.g. an error in a user-defined `part` handler. diff --git a/jsr.json b/jsr.json index 548e3069c6b..619585ab866 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.3.2", + "version": "0.4.0", "exports": "./src/multipart-parser.ts", "publish": { "include": [ diff --git a/package.json b/package.json index bb682ff3f27..168a108a291 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.3.2", + "version": "0.4.0", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "repository": { From ef0d38d7431cbad5a6779633ffe42220101314a0 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 12 Aug 2024 23:08:33 -0700 Subject: [PATCH 216/730] Simplify some examples --- examples/bun/global.d.ts | 6 ++++++ examples/bun/server.ts | 16 +--------------- examples/node/server.js | 20 ++------------------ 3 files changed, 9 insertions(+), 33 deletions(-) create mode 100644 examples/bun/global.d.ts diff --git a/examples/bun/global.d.ts b/examples/bun/global.d.ts new file mode 100644 index 00000000000..b8041179bc5 --- /dev/null +++ b/examples/bun/global.d.ts @@ -0,0 +1,6 @@ +// See https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62651 + +interface ReadableStream { + values(options?: { preventCancel?: boolean }): AsyncIterableIterator; + [Symbol.asyncIterator](): AsyncIterableIterator; +} diff --git a/examples/bun/server.ts b/examples/bun/server.ts index 5dfa6f287dc..98cc44092a2 100644 --- a/examples/bun/server.ts +++ b/examples/bun/server.ts @@ -77,7 +77,7 @@ async function writeFile(file: BunFile, stream: ReadableStream): Pro let writer = file.writer(); let bytesWritten = 0; - for await (let chunk of readStream(stream)) { + for await (let chunk of stream) { writer.write(chunk); bytesWritten += chunk.byteLength; } @@ -86,17 +86,3 @@ async function writeFile(file: BunFile, stream: ReadableStream): Pro return bytesWritten; } - -async function* readStream(stream: ReadableStream): AsyncGenerator { - let reader = stream.getReader(); - - try { - while (true) { - const { done, value } = await reader.read(); - if (done) break; - yield value; - } - } finally { - reader.releaseLock(); - } -} diff --git a/examples/node/server.js b/examples/node/server.js index f9bc2d2a46b..909ce19487c 100644 --- a/examples/node/server.js +++ b/examples/node/server.js @@ -72,6 +72,7 @@ const server = http.createServer(async (req, res) => { res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end('Internal Server Error'); + return; } } @@ -83,14 +84,12 @@ server.listen(PORT, () => { console.log(`Server listening on http://localhost:${PORT} ...`); }); -// Some lil' helpers - /** @type (filename: string, stream: ReadableStream) => Promise */ async function writeFile(filename, stream) { let fileStream = fs.createWriteStream(filename); let bytesWritten = 0; - for await (let chunk of readStream(stream)) { + for await (let chunk of stream) { fileStream.write(chunk); bytesWritten += chunk.byteLength; } @@ -99,18 +98,3 @@ async function writeFile(filename, stream) { return bytesWritten; } - -/** @type (stream: ReadableStream) => AsyncGenerator */ -async function* readStream(stream) { - let reader = stream.getReader(); - - try { - while (true) { - const { done, value } = await reader.read(); - if (done) break; - yield value; - } - } finally { - reader.releaseLock(); - } -} From 1023a95e931189c6694ae2b62b3d296aae1c1244 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 12 Aug 2024 23:10:20 -0700 Subject: [PATCH 217/730] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af3a69f6516..0551d5e21c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # `multipart-parser` CHANGELOG +## HEAD + +- Add `type` keyword to `MultipartParserOptions` export for Deno (#11) + ## v0.4.0 (Aug 12, 2024) - Switch dependency from `fetch-super-headers` to `@mjackson/headers` From 60151cec822b3f76e80e17123cce006c3159bc1e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 12 Aug 2024 23:10:26 -0700 Subject: [PATCH 218/730] Version 0.4.1 --- CHANGELOG.md | 2 +- jsr.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0551d5e21c1..16885439198 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # `multipart-parser` CHANGELOG -## HEAD +## v0.4.1 (Aug 12, 2024) - Add `type` keyword to `MultipartParserOptions` export for Deno (#11) diff --git a/jsr.json b/jsr.json index 619585ab866..c0ddbba69c1 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.4.0", + "version": "0.4.1", "exports": "./src/multipart-parser.ts", "publish": { "include": [ diff --git a/package.json b/package.json index 168a108a291..f87448386ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.4.0", + "version": "0.4.1", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "repository": { From 85440f4798cbb5f21a983b02319caf1ec1dcb61d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 12 Aug 2024 23:31:39 -0700 Subject: [PATCH 219/730] Add version script --- package.json | 3 ++- scripts/version.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 scripts/version.js diff --git a/package.json b/package.json index 87e8c192d92..902f7ea72f9 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "clean": "git clean -fdX .", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", - "prepare": "npm run build" + "prepare": "npm run build", + "version": "node scripts/version.js" }, "packageManager": "pnpm@9.4.0", "keywords": [ diff --git a/scripts/version.js b/scripts/version.js new file mode 100644 index 00000000000..960e20efa91 --- /dev/null +++ b/scripts/version.js @@ -0,0 +1,30 @@ +import * as cp from 'node:child_process'; +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import * as process from 'node:process'; + +const __dirname = path.dirname(new URL(import.meta.url).pathname); +const packageVersion = process.env.npm_package_version; + +// Update CHANGELOG.md with the current version +let changelogPath = path.resolve(__dirname, '../CHANGELOG.md'); +let changelog = fs.readFileSync(changelogPath, 'utf-8'); +let match = /^## HEAD\n/m.exec(changelog); +if (match) { + let today = new Date().toLocaleDateString('en-US', { + month: 'short', + day: 'numeric', + year: 'numeric', + }); + + changelog = + changelog.slice(0, match.index) + + `## v${packageVersion} (${today})\n` + + changelog.slice(match.index + match[0].length); + + fs.writeFileSync(changelogPath, changelog); + cp.execSync('git add CHANGELOG.md'); +} else { + console.error('Could not find "## HEAD" in CHANGELOG.md'); + process.exit(1); +} From 39a8bab3cf1eec3440576f706cddb7e6acb6ffe9 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 12 Aug 2024 23:32:01 -0700 Subject: [PATCH 220/730] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 31f73313ba8..cdb61d6bc91 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The [built-in JavaScript `Headers` interface](https://developer.mozilla.org/en-U ## Installation ```sh -$ npm install @mjackson/headers +npm install @mjackson/headers ``` ## Overview From 4bcc6363625c49f907b2e31edd30ba9dfe2b7595 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 12 Aug 2024 23:35:41 -0700 Subject: [PATCH 221/730] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4588b73ba86..ba5c15bfb9c 100644 --- a/README.md +++ b/README.md @@ -193,7 +193,7 @@ Deno 1.45.5 I encourage you to run the benchmarks yourself. You'll probably get different results! ```sh -$ pnpm run bench +pnpm run bench ``` ## Credits From 3058ee504caced7f78ae6e40e0c7fbb779086929 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 00:26:47 -0700 Subject: [PATCH 222/730] Update CHANGELOG --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aac72383a37..516937cfaf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,10 @@ # `headers` CHANGELOG -## v0.5.1 - Aug 6, 2024 +## v0.5.1 (Aug 6, 2024) - Added `CookieInit` support to `headers.cookie=` setter -## v0.5.0 - Aug 6, 2024 +## v0.5.0 (Aug 6, 2024) - Added the ability to initialize a `SuperHeaders` instance with object config instead of just strings or header object instances. From a1dfd150491f9c600e987886e78d2e95b2cbf8dd Mon Sep 17 00:00:00 2001 From: Alex Anderson Date: Tue, 13 Aug 2024 08:14:49 -0400 Subject: [PATCH 223/730] Address PR feedback. --- src/headers.ts | 2 +- src/lib/cache-control.spec.ts | 1 + src/lib/cache-control.ts | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/headers.ts b/src/headers.ts index 740a182be19..fb2233f55f9 100644 --- a/src/headers.ts +++ b/src/headers.ts @@ -1,7 +1,7 @@ +export { CacheControlInit, CacheControl } from './lib/cache-control.js'; export { ContentDispositionInit, ContentDisposition } from './lib/content-disposition.js'; export { ContentTypeInit, ContentType } from './lib/content-type.js'; export { CookieInit, Cookie } from './lib/cookie.js'; export { SetCookieInit, SetCookie } from './lib/set-cookie.js'; -export { CacheControlInit, CacheControl } from './lib/cache-control.js'; export { SuperHeaders as default, SuperHeadersInit, SuperHeaders } from './lib/super-headers.js'; diff --git a/src/lib/cache-control.spec.ts b/src/lib/cache-control.spec.ts index d4f6fc6a88e..0b8c9527d77 100644 --- a/src/lib/cache-control.spec.ts +++ b/src/lib/cache-control.spec.ts @@ -1,5 +1,6 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; + import { CacheControl } from './cache-control.js'; describe('CacheControl', () => { diff --git a/src/lib/cache-control.ts b/src/lib/cache-control.ts index 36048ae603d..367f1c7b076 100644 --- a/src/lib/cache-control.ts +++ b/src/lib/cache-control.ts @@ -303,6 +303,7 @@ export class CacheControl implements HeaderValue, CacheControlInit { if (typeof this.minFresh === 'number') { parts.push(`min-fresh=${this.minFresh}`); } + return parts.join(', '); } } From afbf6070c653e8871e36d9fec53da153919ff631 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 09:28:01 -0700 Subject: [PATCH 224/730] Update README and src import order --- README.md | 34 +++++++++++++++++++++++----------- src/lib/cache-control.spec.ts | 7 +++++++ src/lib/super-headers.spec.ts | 2 +- src/lib/super-headers.ts | 4 ++-- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index cdb61d6bc91..f0d43ebe41a 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,7 @@ All individual header classes may be initialized with either a) the string value The following headers are currently supported: +- [`Cache-Control`](#cache-control) - [`Content-Disposition`](#content-disposition) - [`Content-Type`](#content-type) - [`Cookie`](#cookie) @@ -162,20 +163,15 @@ The following headers are currently supported: If you need support for a header that isn't listed here, please [send a PR](https://github.com/mjackson/headers/pulls)! The goal is to have first-class support for all common HTTP headers. -### Content-Type +### Cache-Control ```ts -import { ContentType } from '@mjackson/headers'; - -let header = new ContentType('text/html; charset=utf-8'); -header.mediaType; // "text/html" -header.boundary; // undefined -header.charset; // "utf-8" +import { CacheControl } from '@mjackson/headers'; -let header = new ContentType({ - mediaType: 'multipart/form-data', - boundary: '------WebKitFormBoundary12345', -}); +let header = new CacheControl('public, max-age=3600, s-maxage=3600'); +header.public; // true +header.maxAge; // 3600 +header.sMaxage; // 3600 ``` ### Content-Disposition @@ -190,6 +186,22 @@ header.filename; // "file1.txt" header.preferredFilename; // "file1.txt" ``` +### Content-Type + +```ts +import { ContentType } from '@mjackson/headers'; + +let header = new ContentType('text/html; charset=utf-8'); +header.mediaType; // "text/html" +header.boundary; // undefined +header.charset; // "utf-8" + +let header = new ContentType({ + mediaType: 'multipart/form-data', + boundary: '------WebKitFormBoundary12345', +}); +``` + ### Cookie ```ts diff --git a/src/lib/cache-control.spec.ts b/src/lib/cache-control.spec.ts index 0b8c9527d77..2bf72ebe207 100644 --- a/src/lib/cache-control.spec.ts +++ b/src/lib/cache-control.spec.ts @@ -10,30 +10,35 @@ describe('CacheControl', () => { assert.equal(header.public, undefined); assert.equal(`${header}`, ''); }); + it('initializes with a string', () => { let header = new CacheControl('public, max-age=3600, s-maxage=3600'); assert.equal(header.maxAge, 3600); assert.equal(header.sMaxage, 3600); assert.equal(header.public, true); }); + it('initializes with an object', () => { let header = new CacheControl({ public: true, maxAge: 3600, sMaxage: 3600 }); assert.equal(header.maxAge, 3600); assert.equal(header.sMaxage, 3600); assert.equal(header.public, true); }); + it('initializes with another CacheControl', () => { let header = new CacheControl(new CacheControl('public, max-age=3600, s-maxage=3600')); assert.equal(header.maxAge, 3600); assert.equal(header.sMaxage, 3600); assert.equal(header.public, true); }); + it('handles whitespace in initial value', () => { let header = new CacheControl(' public , max-age = 3600, s-maxage=3600 '); assert.equal(header.maxAge, 3600); assert.equal(header.sMaxage, 3600); assert.equal(header.public, true); }); + it('sets and gets attributes', () => { let header = new CacheControl(''); header.maxAge = 3600; @@ -43,10 +48,12 @@ describe('CacheControl', () => { assert.equal(header.sMaxage, 3600); assert.equal(header.public, true); }); + it('converts to a string properly', () => { let header = new CacheControl('public, max-age=3600, s-maxage=3600'); assert.equal(header.toString(), 'public, max-age=3600, s-maxage=3600'); }); + it('sets numerical values to 0 instead of omitting them', () => { let header = new CacheControl(); header.maxAge = 0; diff --git a/src/lib/super-headers.spec.ts b/src/lib/super-headers.spec.ts index b02b5608666..0182d10b51c 100644 --- a/src/lib/super-headers.spec.ts +++ b/src/lib/super-headers.spec.ts @@ -1,11 +1,11 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; +import { CacheControl } from './cache-control.js'; import { ContentDisposition } from './content-disposition.js'; import { ContentType } from './content-type.js'; import { Cookie } from './cookie.js'; import { SuperHeaders } from './super-headers.js'; -import { CacheControl } from './cache-control.js'; describe('SuperHeaders', () => { it('is an instance of Headers', () => { diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index 1cbde87355e..cf07cdaebd6 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -1,4 +1,4 @@ -import { CacheControl, CacheControlInit } from './cache-control.js'; +import { CacheControlInit, CacheControl } from './cache-control.js'; import { ContentDispositionInit, ContentDisposition } from './content-disposition.js'; import { ContentTypeInit, ContentType } from './content-type.js'; import { CookieInit, Cookie } from './cookie.js'; @@ -12,6 +12,7 @@ const SetCookieKey = 'set-cookie'; interface SuperHeadersPropertyInit { age?: string | number; + cacheControl?: string | CacheControlInit; contentDisposition?: string | ContentDispositionInit; contentLength?: string | number; contentType?: string | ContentTypeInit; @@ -22,7 +23,6 @@ interface SuperHeadersPropertyInit { ifUnmodifiedSince?: string | Date; lastModified?: string | Date; setCookie?: string | (string | SetCookieInit)[]; - cacheControl?: string | CacheControlInit; } export type SuperHeadersInit = From dac7f91ab2bc30c1e542c93a14094fb39b417ebb Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 09:28:11 -0700 Subject: [PATCH 225/730] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 516937cfaf0..23c00a1765e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # `headers` CHANGELOG +## HEAD + +- Added support for `Cache-Control` header (#7, thanks @alexanderson1993) + ## v0.5.1 (Aug 6, 2024) - Added `CookieInit` support to `headers.cookie=` setter From 32adcfccab6b542c7ba4387b3a3f02d9267767eb Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 09:31:48 -0700 Subject: [PATCH 226/730] Update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23c00a1765e..b5bdba5d573 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## HEAD -- Added support for `Cache-Control` header (#7, thanks @alexanderson1993) +- Added support for `Cache-Control` header (https://github.com/mjackson/headers/pull/7, thanks [@alexanderson1993](https://github.com/alexanderson1993)) ## v0.5.1 (Aug 6, 2024) From 07c4477a96ce5b82303c7eda5eb20bbd1c6852b4 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 09:34:11 -0700 Subject: [PATCH 227/730] Version 0.6.0 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5bdba5d573..b5e59f66167 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # `headers` CHANGELOG -## HEAD +## v0.6.0 (Aug 13, 2024) - Added support for `Cache-Control` header (https://github.com/mjackson/headers/pull/7, thanks [@alexanderson1993](https://github.com/alexanderson1993)) diff --git a/package.json b/package.json index 902f7ea72f9..453d33d818a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/headers", - "version": "0.5.1", + "version": "0.6.0", "description": "A toolkit for working with HTTP headers in JavaScript", "author": "Michael Jackson ", "license": "MIT", From e4500e5605098bda7618bbc397d2122b2ceef532 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 09:35:27 -0700 Subject: [PATCH 228/730] Ran npm pkg fix --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 453d33d818a..0dad4800b6e 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/mjackson/headers" + "url": "git+https://github.com/mjackson/headers.git" }, "files": [ "dist", From b6dd94cde48e085440b17cfd9e2f61c9cadf9943 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 09:35:59 -0700 Subject: [PATCH 229/730] Ran npm pkg fix --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f87448386ac..b1e7db4d97c 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "author": "Michael Jackson ", "repository": { "type": "git", - "url": "https://github.com/mjackson/multipart-parser" + "url": "git+https://github.com/mjackson/multipart-parser.git" }, "license": "MIT", "files": [ From 0827d46466b248bb9df702084441d89565199ac2 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 09:38:37 -0700 Subject: [PATCH 230/730] Update issue link --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16885439198..64a9b267db4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## v0.4.1 (Aug 12, 2024) -- Add `type` keyword to `MultipartParserOptions` export for Deno (#11) +- Add `type` keyword to `MultipartParserOptions` export for Deno (https://github.com/mjackson/multipart-parser/pull/11) ## v0.4.0 (Aug 12, 2024) From 1ca37471fb095a3368ec79c5d9c103f0bd28bdff Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 10:15:56 -0700 Subject: [PATCH 231/730] Doc comment tweaks --- CHANGELOG.md | 4 ++++ src/lib/cache-control.ts | 46 ++++++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5e59f66167..b8aeaa609e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # `headers` CHANGELOG +## HEAD + +- Associate `CacheControl` doc comments with the class instead of the constructor function + ## v0.6.0 (Aug 13, 2024) - Added support for `Cache-Control` header (https://github.com/mjackson/headers/pull/7, thanks [@alexanderson1993](https://github.com/alexanderson1993)) diff --git a/src/lib/cache-control.ts b/src/lib/cache-control.ts index 367f1c7b076..6a82516e59b 100644 --- a/src/lib/cache-control.ts +++ b/src/lib/cache-control.ts @@ -3,7 +3,7 @@ import { parseParams } from './param-values.js'; // Taken from https://github.com/jjenzz/pretty-cache-header by jjenzz // License: MIT https://github.com/jjenzz/pretty-cache-header/blob/main/LICENSE -export type CacheControlInit = { +export interface CacheControlInit { /** * The `max-age=N` **request directive** indicates that the client allows a stored response that * is generated on the origin server within _N_ seconds — where _N_ may be any non-negative @@ -13,7 +13,7 @@ export type CacheControlInit = { * [fresh](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age) * until _N_ seconds after the response is generated. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#max-age + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#max-age) */ maxAge?: number; /** @@ -21,7 +21,7 @@ export type CacheControlInit = { * that is [stale](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age) * within _N_ seconds. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#max-stale + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#max-stale) */ maxStale?: number; /** @@ -29,7 +29,7 @@ export type CacheControlInit = { * that is [fresh](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age) * for at least _N_ seconds. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#min-fresh + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#min-fresh) */ minFresh?: number; /** @@ -37,7 +37,7 @@ export type CacheControlInit = { * [fresh](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age) for (similar to `max-age`) — * but it is specific to shared caches, and they will ignore `max-age` when it is present. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#s-maxage + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#s-maxage) */ sMaxage?: number; /** @@ -53,7 +53,7 @@ export type CacheControlInit = { * [fresh](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age) * response. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#no-cache + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#no-cache) */ noCache?: true; /** @@ -64,21 +64,21 @@ export type CacheControlInit = { * The `no-store` **response directive** indicates that any caches of any kind (private or shared) * should not store this response. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#no-store + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#no-store) */ noStore?: true; /** * `no-transform` indicates that any intermediary (regardless of whether it implements a cache) * shouldn't transform the response contents. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#no-transform + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#no-transform) */ noTransform?: true; /** * The client indicates that cache should obtain an already-cached response. If a cache has * stored a response, it's reused. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#only-if-cached + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#only-if-cached) */ onlyIfCached?: true; /** @@ -87,14 +87,14 @@ export type CacheControlInit = { * If the response becomes [stale](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age), * it must be validated with the origin server before reuse. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#must-revalidate + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#must-revalidate) */ mustRevalidate?: true; /** * The `proxy-revalidate` **response directive** is the equivalent of `must-revalidate`, but * specifically for shared caches only. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#proxy-revalidate + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#proxy-revalidate) */ proxyRevalidate?: true; /** @@ -103,7 +103,7 @@ export type CacheControlInit = { * * `must-understand` should be coupled with `no-store` for fallback behavior. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#must-understand + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#must-understand) */ mustUnderstand?: true; /** @@ -113,7 +113,7 @@ export type CacheControlInit = { * You should add the `private` directive for user-personalized content, especially for responses * received after login and for sessions managed via cookies. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#private + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#private) */ private?: true; /** @@ -122,21 +122,21 @@ export type CacheControlInit = { * shared cache; however, the `public` directive will cause such responses to be stored in a * shared cache. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#public + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#public) */ public?: true; /** * The `immutable` **response directive** indicates that the response will not be updated while * it's [fresh](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#fresh_and_stale_based_on_age). * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#public + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#public) */ immutable?: true; /** * The `stale-while-revalidate` **response directive** indicates that the cache could reuse a * stale response while it revalidates it to a cache. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate) */ staleWhileRevalidate?: number; /** @@ -145,11 +145,16 @@ export type CacheControlInit = { * when an upstream server generates an error, or when the error is generated locally. Here, an * error is considered any response with a status code of 500, 502, 503, or 504. * - * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-if-error + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-if-error) */ staleIfError?: number; -}; +} +/** + * The value of a `Cache-Control` HTTP header. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) + */ export class CacheControl implements HeaderValue, CacheControlInit { maxAge?: number; maxStale?: number; @@ -168,11 +173,6 @@ export class CacheControl implements HeaderValue, CacheControlInit { staleWhileRevalidate?: number; staleIfError?: number; - /** - * The value of a `Cache-Control` HTTP header. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) - */ constructor(init?: string | CacheControlInit) { if (init) { if (typeof init === 'string') { From 30617b913a38b923afc5c5e2b958d37cc4af1d5f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 10:17:17 -0700 Subject: [PATCH 232/730] Version 0.6.1 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8aeaa609e0..50f18ba859d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # `headers` CHANGELOG -## HEAD +## v0.6.1 (Aug 13, 2024) - Associate `CacheControl` doc comments with the class instead of the constructor function diff --git a/package.json b/package.json index 0dad4800b6e..0784530bcb2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/headers", - "version": "0.6.0", + "version": "0.6.1", "description": "A toolkit for working with HTTP headers in JavaScript", "author": "Michael Jackson ", "license": "MIT", From 755bb795ef0a8a76017bd4dd952535822cdfe9a4 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 18:05:10 -0700 Subject: [PATCH 233/730] Update examples --- examples/bun/server.ts | 2 +- examples/deno/main.ts | 98 +++++++++++++++++++++-------------------- examples/node/server.js | 6 +-- 3 files changed, 54 insertions(+), 52 deletions(-) diff --git a/examples/bun/server.ts b/examples/bun/server.ts index 98cc44092a2..58662783e4e 100644 --- a/examples/bun/server.ts +++ b/examples/bun/server.ts @@ -1,4 +1,4 @@ -import type { BunFile } from 'bun'; +import { type BunFile } from 'bun'; import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser'; import tmp from 'tmp'; diff --git a/examples/deno/main.ts b/examples/deno/main.ts index a3fb88ba406..01b49a9dcf1 100644 --- a/examples/deno/main.ts +++ b/examples/deno/main.ts @@ -5,17 +5,10 @@ import tmp from 'npm:tmp'; const PORT = 3000; -Deno.serve( - { - port: PORT, - onListen() { - console.log(`Server listening on http://localhost:${PORT}`); - }, - }, - async (request) => { - if (request.method === 'GET') { - return new Response( - ` +async function requestHandler(request: Request): Promise { + if (request.method === 'GET') { + return new Response( + ` @@ -31,51 +24,60 @@ Deno.serve( `, - { - headers: { 'Content-Type': 'text/html' }, - }, - ); - } + { + headers: { 'Content-Type': 'text/html' }, + }, + ); + } - if (request.method === 'POST') { - try { - // deno-lint-ignore no-explicit-any - let parts: any[] = []; + if (request.method === 'POST') { + try { + // deno-lint-ignore no-explicit-any + let parts: any[] = []; - for await (let part of parseMultipartRequest(request)) { - if (part.isFile) { - let tmpfile = tmp.fileSync(); - await Deno.writeFile(tmpfile.name, part.body); + for await (let part of parseMultipartRequest(request)) { + if (part.isFile) { + let tmpfile = tmp.fileSync(); + await Deno.writeFile(tmpfile.name, part.body); - parts.push({ - name: part.name, - filename: part.filename, - mediaType: part.mediaType, - size: Deno.statSync(tmpfile.name).size, - file: tmpfile.name, - }); - } else { - parts.push({ - name: part.name, - value: await part.text(), - }); - } + parts.push({ + name: part.name, + filename: part.filename, + mediaType: part.mediaType, + size: Deno.statSync(tmpfile.name).size, + file: tmpfile.name, + }); + } else { + parts.push({ + name: part.name, + value: await part.text(), + }); } + } - return new Response(JSON.stringify({ parts }, null, 2), { - headers: { 'Content-Type': 'application/json' }, - }); - } catch (error) { - if (error instanceof MultipartParseError) { - return new Response(`Error: ${error.message}`, { status: 400 }); - } + return new Response(JSON.stringify({ parts }, null, 2), { + headers: { 'Content-Type': 'application/json' }, + }); + } catch (error) { + if (error instanceof MultipartParseError) { + return new Response(`Error: ${error.message}`, { status: 400 }); + } - console.error(error); + console.error(error); - return new Response('Internal Server Error', { status: 500 }); - } + return new Response('Internal Server Error', { status: 500 }); } + } - return new Response('Method Not Allowed', { status: 405 }); + return new Response('Method Not Allowed', { status: 405 }); +} + +Deno.serve( + { + port: PORT, + onListen() { + console.log(`Server listening on http://localhost:${PORT} ...`); + }, }, + requestHandler, ); diff --git a/examples/node/server.js b/examples/node/server.js index 909ce19487c..332d0e27232 100644 --- a/examples/node/server.js +++ b/examples/node/server.js @@ -86,15 +86,15 @@ server.listen(PORT, () => { /** @type (filename: string, stream: ReadableStream) => Promise */ async function writeFile(filename, stream) { - let fileStream = fs.createWriteStream(filename); + let file = fs.createWriteStream(filename); let bytesWritten = 0; for await (let chunk of stream) { - fileStream.write(chunk); + file.write(chunk); bytesWritten += chunk.byteLength; } - fileStream.end(); + file.end(); return bytesWritten; } From fa438c0898a1725550c0994f60feffc1e60253c5 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 18:42:09 -0700 Subject: [PATCH 234/730] Catch file size exceeded errors properly Fixes #8 --- CHANGELOG.md | 4 ++++ src/lib/multipart.spec.ts | 18 ++++++++++++------ src/lib/multipart.ts | 16 +++++++++++++--- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64a9b267db4..978614fb3e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # `multipart-parser` CHANGELOG +## HEAD + +- Fix bug where max file size exceeded error would crash Node.js servers (https://github.com/mjackson/multipart-parser/issues/8) + ## v0.4.1 (Aug 12, 2024) - Add `type` keyword to `MultipartParserOptions` export for Deno (https://github.com/mjackson/multipart-parser/pull/11) diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 53f31e11825..8f63c547d3f 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -248,8 +248,10 @@ describe('parseMultipartRequest', async () => { }); await assert.rejects(async () => { - for await (let _ of parseMultipartRequest(request, { maxHeaderSize: 4 * 1024 })) { - // Consume all parts + for await (let part of parseMultipartRequest(request, { maxHeaderSize: 4 * 1024 })) { + for await (let _ of part.body) { + // Consume all parts + } } }, MultipartParseError); }); @@ -269,8 +271,10 @@ describe('parseMultipartRequest', async () => { }); await assert.rejects(async () => { - for await (let _ of parseMultipartRequest(request, { maxFileSize: 10 * 1024 * 1024 })) { - // Consume all parts + for await (let part of parseMultipartRequest(request, { maxFileSize: 10 * 1024 * 1024 })) { + for await (let _ of part.body) { + // Consume all parts + } } }, MultipartParseError); }); @@ -308,8 +312,10 @@ describe('parseMultipartRequest', async () => { }); await assert.rejects(async () => { - for await (let _ of parseMultipartRequest(request)) { - // Consume all parts + for await (let part of parseMultipartRequest(request)) { + for await (let _ of part.body) { + // Consume all parts + } } }, MultipartParseError); }); diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index ad08c310d3c..c677f38cdf1 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -56,9 +56,10 @@ export async function* parseMultipart( let parts: MultipartPart[] = []; let resolveNext: (() => void) | null = null; + let error: Error | null = null; let done = false; - let parse = parser + parser .parse(data, (part) => { parts.push(part); if (resolveNext) { @@ -66,6 +67,9 @@ export async function* parseMultipart( resolveNext = null; } }) + .catch((err) => { + error = err; + }) .finally(() => { done = true; if (resolveNext) resolveNext(); @@ -83,7 +87,9 @@ export async function* parseMultipart( } } - await parse; + if (error) { + throw error; + } } const HYPHEN = 45; @@ -376,9 +382,13 @@ export class MultipartParser { #writeBody(chunks: Uint8Array[]): void { for (let chunk of chunks) { if (this.#bodyLength + chunk.length > this.#maxFileSize) { - throw new MultipartParseError( + let error = new MultipartParseError( `File size exceeds maximum allowed size of ${this.#maxFileSize} bytes`, ); + + this.#bodyController!.error(error); + + throw error; } this.#bodyController!.enqueue(chunk); From df524463fe5a4a02bf236c60371a3dfc417f62dd Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 18:43:15 -0700 Subject: [PATCH 235/730] Version 0.4.2 --- CHANGELOG.md | 2 +- jsr.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 978614fb3e7..b779ac75927 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # `multipart-parser` CHANGELOG -## HEAD +## v0.4.2 (Aug 13, 2024) - Fix bug where max file size exceeded error would crash Node.js servers (https://github.com/mjackson/multipart-parser/issues/8) diff --git a/jsr.json b/jsr.json index c0ddbba69c1..fd637ad381c 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.4.1", + "version": "0.4.2", "exports": "./src/multipart-parser.ts", "publish": { "include": [ diff --git a/package.json b/package.json index b1e7db4d97c..6fd3413c2b9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.4.1", + "version": "0.4.2", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "repository": { From b74a8b1b019cdbf08334390f3580f0433ca16288 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 18:53:55 -0700 Subject: [PATCH 236/730] Update benchmarks --- README.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index ba5c15bfb9c..394b041abd7 100644 --- a/README.md +++ b/README.md @@ -144,49 +144,49 @@ Important: Benchmarking can be tricky, and results vary greatly depending on pla The results of running the benchmarks on my laptop: ``` -> @mjackson/multipart-parser@0.3.2 bench:node /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.4.2 bench:node /Users/michael/Projects/multipart-parser > node --import tsimp/import ./bench/runner.ts Platform: Darwin (23.5.0) -CPU: Apple M2 Pro -Date: 8/4/2024, 9:45:08 PM -Node.js v20.15.1 +CPU: Apple M1 Pro +Date: 8/13/2024, 6:47:34 PM +Node.js v22.1.0 ┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ multipart-parser │ '0.02 ms ± 0.09' │ '1.04 ms ± 0.15' │ '0.32 ms ± 0.13' │ '10.39 ms ± 1.77' │ -│ busboy │ '0.03 ms ± 0.08' │ '4.26 ms ± 0.09' │ '0.24 ms ± 0.03' │ '43.00 ms ± 0.71' │ -│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.09 ms ± 0.06' │ '0.38 ms ± 0.03' │ '10.89 ms ± 0.14' │ +│ multipart-parser │ '0.01 ms ± 0.08' │ '1.17 ms ± 0.27' │ '0.12 ms ± 0.03' │ '10.94 ms ± 0.24' │ +│ busboy │ '0.03 ms ± 0.08' │ '3.00 ms ± 0.09' │ '0.21 ms ± 0.03' │ '30.10 ms ± 2.73' │ +│ @fastify/busboy │ '0.02 ms ± 0.07' │ '1.19 ms ± 0.07' │ '0.38 ms ± 0.07' │ '12.15 ms ± 2.30' │ └──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ -> @mjackson/multipart-parser@0.3.2 bench:bun /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.4.2 bench:bun /Users/michael/Projects/multipart-parser > bun run ./bench/runner.ts Platform: Darwin (23.5.0) -CPU: Apple M2 Pro -Date: 8/4/2024, 9:47:10 PM +CPU: Apple M1 Pro +Date: 8/13/2024, 6:49:45 PM Bun 1.1.21 ┌──────────────────┬────────────────┬────────────────┬─────────────────┬─────────────────┐ │ │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼────────────────┼────────────────┼─────────────────┼─────────────────┤ -│ multipart-parser │ 0.01 ms ± 0.04 │ 0.85 ms ± 0.04 │ 0.13 ms ± 0.17 │ 8.31 ms ± 0.25 │ -│ busboy │ 0.02 ms ± 0.13 │ 3.29 ms ± 0.10 │ 0.34 ms ± 0.15 │ 33.09 ms ± 1.72 │ -│ @fastify/busboy │ 0.04 ms ± 0.13 │ 6.61 ms ± 0.11 │ 0.60 ms ± 0.22 │ 67.90 ms ± 4.82 │ +│ multipart-parser │ 0.01 ms ± 0.07 │ 0.95 ms ± 0.12 │ 0.13 ms ± 0.09 │ 9.13 ms ± 0.29 │ +│ busboy │ 0.03 ms ± 0.10 │ 3.55 ms ± 0.10 │ 0.35 ms ± 0.17 │ 35.54 ms ± 2.57 │ +│ @fastify/busboy │ 0.04 ms ± 0.10 │ 7.17 ms ± 0.10 │ 0.62 ms ± 0.13 │ 71.99 ms ± 3.01 │ └──────────────────┴────────────────┴────────────────┴─────────────────┴─────────────────┘ -> @mjackson/multipart-parser@0.3.2 bench:deno /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.4.2 bench:deno /Users/michael/Projects/multipart-parser > deno --unstable-byonm --unstable-sloppy-imports run --allow-sys ./bench/runner.ts Platform: Darwin (23.5.0) -CPU: Apple M2 Pro -Date: 8/4/2024, 9:50:01 PM +CPU: Apple M1 Pro +Date: 8/13/2024, 6:52:51 PM Deno 1.45.5 ┌──────────────────┬──────────────────┬───────────────────┬──────────────────┬────────────────────┐ │ (idx) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼───────────────────┼──────────────────┼────────────────────┤ -│ multipart-parser │ "0.02 ms ± 0.19" │ "1.01 ms ± 1.00" │ "0.10 ms ± 0.44" │ "10.02 ms ± 0.70" │ -│ busboy │ "0.03 ms ± 0.25" │ "2.85 ms ± 0.99" │ "0.27 ms ± 0.69" │ "29.03 ms ± 2.07" │ -│ @fastify/busboy │ "0.04 ms ± 0.29" │ "11.23 ms ± 0.98" │ "0.72 ms ± 0.96" │ "115.38 ms ± 6.64" │ +│ multipart-parser │ "0.02 ms ± 0.18" │ "1.18 ms ± 1.07" │ "0.10 ms ± 0.43" │ "11.00 ms ± 1.18" │ +│ busboy │ "0.04 ms ± 0.27" │ "3.02 ms ± 1.00" │ "0.29 ms ± 0.71" │ "30.22 ms ± 2.61" │ +│ @fastify/busboy │ "0.05 ms ± 0.31" │ "12.32 ms ± 0.73" │ "0.77 ms ± 0.97" │ "125.04 ms ± 8.39" │ └──────────────────┴──────────────────┴───────────────────┴──────────────────┴────────────────────┘ ``` From 6cedbe9cddf9dfe691233eb19a1607d6eceb8aa9 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 18:55:38 -0700 Subject: [PATCH 237/730] Update version script --- scripts/version.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/version.js b/scripts/version.js index 5b1a9f69165..08ef09d9768 100644 --- a/scripts/version.js +++ b/scripts/version.js @@ -6,13 +6,6 @@ import * as process from 'node:process'; const __dirname = path.dirname(new URL(import.meta.url).pathname); const packageVersion = process.env.npm_package_version; -// Update jsr.json with the current version -let jsrJsonPath = path.resolve(__dirname, '../jsr.json'); -let jsrJson = JSON.parse(fs.readFileSync(jsrJsonPath, 'utf-8')); -jsrJson.version = packageVersion; -fs.writeFileSync(jsrJsonPath, JSON.stringify(jsrJson, null, 2) + '\n'); -cp.execSync('git add jsr.json'); - // Update CHANGELOG.md with the current version let changelogPath = path.resolve(__dirname, '../CHANGELOG.md'); let changelog = fs.readFileSync(changelogPath, 'utf-8'); @@ -35,3 +28,10 @@ if (match) { console.error('Could not find "## HEAD" in CHANGELOG.md'); process.exit(1); } + +// Update jsr.json with the current version +let jsrJsonPath = path.resolve(__dirname, '../jsr.json'); +let jsrJson = JSON.parse(fs.readFileSync(jsrJsonPath, 'utf-8')); +jsrJson.version = packageVersion; +fs.writeFileSync(jsrJsonPath, JSON.stringify(jsrJson, null, 2) + '\n'); +cp.execSync('git add jsr.json'); From 026874de852ec38a8ca3aa0ad8ab20b41b0dfaf7 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 23:32:47 -0700 Subject: [PATCH 238/730] Move global.d.ts into repo root --- src/lib/global.d.ts => global.d.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/lib/global.d.ts => global.d.ts (100%) diff --git a/src/lib/global.d.ts b/global.d.ts similarity index 100% rename from src/lib/global.d.ts rename to global.d.ts From 78585ab52eac1cba7eeea4c40def5193cf02343e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 13 Aug 2024 23:44:54 -0700 Subject: [PATCH 239/730] Rename var --- src/lib/multipart.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index c677f38cdf1..5773b40a041 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -56,7 +56,7 @@ export async function* parseMultipart( let parts: MultipartPart[] = []; let resolveNext: (() => void) | null = null; - let error: Error | null = null; + let parseError: Error | null = null; let done = false; parser @@ -67,8 +67,8 @@ export async function* parseMultipart( resolveNext = null; } }) - .catch((err) => { - error = err; + .catch((error) => { + parseError = error; }) .finally(() => { done = true; @@ -87,8 +87,8 @@ export async function* parseMultipart( } } - if (error) { - throw error; + if (parseError) { + throw parseError; } } From 8e24bf870073aaa38d3bd77b45b9da69cc392fed Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 14 Aug 2024 11:33:19 -0700 Subject: [PATCH 240/730] Revert "Move global.d.ts into repo root" This reverts commit 026874de852ec38a8ca3aa0ad8ab20b41b0dfaf7. --- global.d.ts => src/lib/global.d.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename global.d.ts => src/lib/global.d.ts (100%) diff --git a/global.d.ts b/src/lib/global.d.ts similarity index 100% rename from global.d.ts rename to src/lib/global.d.ts From cc676c2e91bb98c039f6eabacfa82d0c28687e8d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 14 Aug 2024 14:22:46 -0700 Subject: [PATCH 241/730] Use const enum --- src/lib/multipart.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 5773b40a041..2b2a6f4be4f 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -109,12 +109,12 @@ export interface MultipartParserOptions { maxFileSize?: number; } -enum MultipartParserState { - Start = 0, - AfterBoundary = 1, - Header = 2, - Body = 3, - Done = 4, +const enum MultipartParserState { + Start, + AfterBoundary, + Header, + Body, + Done, } /** From eccba0229348bd8537671c06838ec544fb399482 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 15 Aug 2024 11:57:58 -0700 Subject: [PATCH 242/730] Better test for large file uploads --- src/lib/multipart.node.spec.ts | 47 +++++---------------- src/lib/multipart.spec.ts | 61 +++++++-------------------- src/test/fixtures.ts | 10 ----- src/test/fixtures/Tesla-Roadster.jpg | Bin 91897 -> 0 bytes src/test/utils.ts | 29 ++++++++++++- 5 files changed, 54 insertions(+), 93 deletions(-) delete mode 100644 src/test/fixtures.ts delete mode 100644 src/test/fixtures/Tesla-Roadster.jpg diff --git a/src/lib/multipart.node.spec.ts b/src/lib/multipart.node.spec.ts index 245dde314dd..20293db5e92 100644 --- a/src/lib/multipart.node.spec.ts +++ b/src/lib/multipart.node.spec.ts @@ -1,9 +1,9 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { readFixture } from '../test/fixtures.js'; -import { createMultipartMockRequest } from '../test/utils.node.js'; import { parseMultipartRequest } from './multipart.node.js'; +import { getRandomBytes } from '../test/utils.js'; +import { createMultipartMockRequest } from '../test/utils.node.js'; describe('parseMultipartRequest (node)', () => { let boundary = 'boundary123'; @@ -35,41 +35,12 @@ describe('parseMultipartRequest (node)', () => { }); it('parses large file uploads correctly', async () => { - const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); - - let request = createMultipartMockRequest(boundary, { - file1: { - filename: 'tesla.jpg', - mediaType: 'image/jpeg', - content: TeslaRoadster, - }, - }); - - let parts = []; - for await (let part of parseMultipartRequest(request)) { - parts.push(part); - } - - assert.equal(parts.length, 1); - assert.equal(parts[0].name, 'file1'); - assert.equal(parts[0].filename, 'tesla.jpg'); - assert.equal(parts[0].mediaType, 'image/jpeg'); - assert.deepEqual(await parts[0].bytes(), TeslaRoadster); - }); - - it('allows buffering part contents while parsing', async () => { - const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); - + let content = getRandomBytes(1024 * 1024 * 10); // 10 MB file let request = createMultipartMockRequest(boundary, { file1: { filename: 'tesla.jpg', mediaType: 'image/jpeg', - content: TeslaRoadster, - }, - file2: { - filename: 'tesla.jpg', - mediaType: 'image/jpeg', - content: TeslaRoadster, + content, }, }); @@ -77,14 +48,16 @@ describe('parseMultipartRequest (node)', () => { for await (let part of parseMultipartRequest(request)) { parts.push({ name: part.name, + filename: part.filename, + mediaType: part.mediaType, content: await part.bytes(), }); } - assert.equal(parts.length, 2); + assert.equal(parts.length, 1); assert.equal(parts[0].name, 'file1'); - assert.deepEqual(parts[0].content, TeslaRoadster); - assert.equal(parts[1].name, 'file2'); - assert.deepEqual(parts[1].content, TeslaRoadster); + assert.equal(parts[0].filename, 'tesla.jpg'); + assert.equal(parts[0].mediaType, 'image/jpeg'); + assert.deepEqual(parts[0].content, content); }); }); diff --git a/src/lib/multipart.spec.ts b/src/lib/multipart.spec.ts index 8f63c547d3f..b0aa85d5799 100644 --- a/src/lib/multipart.spec.ts +++ b/src/lib/multipart.spec.ts @@ -1,14 +1,13 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { readFixture } from '../test/fixtures.js'; -import { createMockRequest, createMultipartMockRequest } from '../test/utils.js'; import { isMultipartRequest, parseMultipartRequest, MultipartParseError, getMultipartBoundary, } from './multipart.js'; +import { createMockRequest, createMultipartMockRequest, getRandomBytes } from '../test/utils.js'; const CRLF = '\r\n'; @@ -162,19 +161,13 @@ describe('parseMultipartRequest', async () => { assert.equal(await parts[2].text(), 'File content'); }); - it('allows buffering part contents while parsing', async () => { - const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); - + it('parses large file uploads correctly', async () => { + let content = getRandomBytes(10 * 1024 * 1024); // 10 MB file let request = createMultipartMockRequest(boundary, { file1: { - filename: 'tesla.jpg', - mediaType: 'image/jpeg', - content: TeslaRoadster, - }, - file2: { - filename: 'tesla.jpg', - mediaType: 'image/jpeg', - content: TeslaRoadster, + filename: 'random.dat', + mediaType: 'application/octet-stream', + content, }, }); @@ -182,34 +175,17 @@ describe('parseMultipartRequest', async () => { for await (let part of parseMultipartRequest(request)) { parts.push({ name: part.name, + filename: part.filename, + mediaType: part.mediaType, content: await part.bytes(), }); } - assert.equal(parts.length, 2); - }); - - it('parses large file uploads correctly', async () => { - const TeslaRoadster = readFixture('Tesla-Roadster.jpg'); - - let request = createMultipartMockRequest(boundary, { - file1: { - filename: 'tesla.jpg', - mediaType: 'image/jpeg', - content: TeslaRoadster, - }, - }); - - let parts = []; - for await (let part of parseMultipartRequest(request)) { - parts.push(part); - } - assert.equal(parts.length, 1); assert.equal(parts[0].name, 'file1'); - assert.equal(parts[0].filename, 'tesla.jpg'); - assert.equal(parts[0].mediaType, 'image/jpeg'); - assert.deepEqual(await parts[0].bytes(), TeslaRoadster); + assert.equal(parts[0].filename, 'random.dat'); + assert.equal(parts[0].mediaType, 'application/octet-stream'); + assert.deepEqual(parts[0].content, content); }); it('throws when Content-Type is not multipart/form-data', async () => { @@ -257,17 +233,12 @@ describe('parseMultipartRequest', async () => { }); it('throws when file exceeds maximum size', async () => { - let request = createMockRequest({ - headers: { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, + let request = createMultipartMockRequest(boundary, { + file1: { + filename: 'random.dat', + mediaType: 'application/octet-stream', + content: getRandomBytes(11 * 1024 * 1024), // 11 MB file }, - body: [ - `--${boundary}`, - 'Content-Disposition: form-data; name="field1"', - '', - 'X'.repeat(11 * 1024 * 1024), // 11 MB file - `--${boundary}--`, - ].join(CRLF), }); await assert.rejects(async () => { diff --git a/src/test/fixtures.ts b/src/test/fixtures.ts deleted file mode 100644 index 34de0e0c57a..00000000000 --- a/src/test/fixtures.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as fs from 'node:fs'; -import * as path from 'node:path'; - -const __dirname = path.dirname(new URL(import.meta.url).pathname); - -export function readFixture(name: string): Uint8Array { - let file = path.resolve(__dirname, `./fixtures/${name}`); - let buffer = fs.readFileSync(file); - return new Uint8Array(buffer); -} diff --git a/src/test/fixtures/Tesla-Roadster.jpg b/src/test/fixtures/Tesla-Roadster.jpg deleted file mode 100644 index 03243d39b9e515eede32b440341c2f833234cf1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91897 zcmb@tWmsEl(=eLgUfiKb(BKlh8;799y~Tos;8vs?cPIqc;;zAi6nA$oP@s4Vw9uBy zVL$u5-sk&qzF+6uD|4+`b5CX__sX@#?)7K=&mMqOLlvqD00IF3;Nt=KbAZ7JRZ@ES zTwhles-^Ou2@E1vJA^j|DFA?Q^YPMGQ)DqUGiSlwe&nYEU;=mmQZ{zp9tzK&YXSbR z<8JjI=>WhI|39++uWbMC69o1!Z@b5-pO5gu&cn;+(OAnzoY3FL;~(7V5vR0;{|68L z2lsk3@R6SK5AOIcUiKfJfAP-$@EGbVJ@QOH;_{CF2X6a+;Qyodkp+NhC-Tqf|KH&Q z3wX3208mu~0RCCif2IF-t^P~Hq<%C(6ac^|`!CJC1OSly`bbatFU>Xw0O*JU0BAS= zO9K@F08b(Tfc7~%UoXFZbpYre&r`q&Ogn5O9-Q!w^e-ws1~Jxao)i&U8Kf$t~ocj&iP%)($J~UpFe-L07?Ly$AOE3i-(6xK=^n(At53nc|uJ}_IOaUQPEL7 ze%P2n%#4o!;pODyg*+1z5qqYktgQ9Y{AF-(G6hQ10To#{K&_(0RS)Qw zl9bq#aja%SogU~oyXRCxlOg*m!V+QHXnAGL87(>aVFPOkdDAEQPq0mz@dxD1?lo-Z zpL_D)7SWEum^Ot1GX^oLoe6Nxj&gGrFhZ-C+z3qL^o3IltYuS3nAIp1SQ(#ds%t6( zuhT}YpRhrDD;*fqAWpi7-% zQar}-H|_@|x9WTix_a(x?}m|IUuQKG4MrTpUzPjcYW1o5HkbB3<Oh%yf{zemK+_>3V#JvoeU)MAs^_2;8q1iXv@1}K>F>|l< z(|l+Izu$r-Ua^XrG#^mnR_awxK4evWEet^Bh$P@0Xhf4!#8e0xaq{K4V#siyYKRB( zG?J)9PSQP;pK$0s!7Hkh%rk&R~)ISM1oLB_nNXj|+SWB!Kyvgyx5K7Q@v`^8$~wK}SX8l#g~RKda>`u$Sa z`R8_KvgtsS5Ql01)=7D{v)+uWNbh8Mb%)FDrMf6Tg_IYiCSpL1_#1euwZl0-hpy1> z;yE8`v7ayU6chh#(kJ1&~|m7j7X-^OR1JL=6myIB_H&K>H78xFe) zC{TL=-1Y91IHHe#RqUQ+*BwFvWBuV>=VpoAOmnKV=<=ip{p>lsm42S81&YB;DyA>S zogS!&8e2xgWhe3pGd!I&Co=l;8f^QfYFoy^;Phts&*d-?#iYS@ybba6E2%29`ud`! zJf^-;lX%*`slk^t`_Yf8o8tv6XA!=$-Iaz9V`8d&OL@(NoOM(ACVv;dPXTnXV83ud zYXm$MYY}d4wd~9fB^*Lq-4)rgtnT_L*YXEv$a!a-ir9-)C{twbN$QtoT*Xfbd^-2u6OJk^XXp08jagXo>%AKRe8-u|js2PANOw{5uiAeAxQm8Q zoxfOU)Ot(|yERX2SSDMp{*(#C-&U_7X>a#kn_`}8IpylYF^*0YAn6padavf>SIawO zM@IVaOd$k#`Ek9q?aT|AF0Bcf`1<{+{L-Z{gY^tT$%4I3-O`A`Iub~V~ZF=|y6B^*0-o(sGI%?3Cge#_%WcI@p z3FY=Bhk_y>Ar!j!_*m3I0{?-uvVQ@DRL4R>S^k;U;7I!SF)0xqeK|R(PEg)(Xs8K2 zu1_)4b-`#L&%=<3J&f_eBBZe9j;jleCNG>NfPO1tkF6Yj6lRMK!m5+vYLbVL8WLHT zY)%YfDc`IBFR*mNj|odKXx&STuk-NoEaN>NKJL zeNBQUT7zhQ2TEX_KEE-h47s;!OP>DGd;>#nHeM1O*^F-+zV}+LrrhKys;bnyutgyhI5E+==J$oImCo}tX6%CU#T6QUVl0}Q0k*- z-kH|}5+C_MJcbcK6(zB$O<~_k*-&lMN5>kZsU01-VMOQZ9nfh~*0^P`$oE!dT;HcY zL$7(JGRRUD!7kKl)_R=slQw9f!WsH3MiF}6ws39kZM=G0wp9SI1R7yM{<*V~t0b1is0edOCcF zqglw?i)=udnT1$3i1?+}%o@0;qz_Zh1n^q#D4qwE24~kJOVR46!nSqqA{0bz4S&>Z#X~bcDwG2*(n7FrCWN4`6!TLIOi_>&x0mdmq zOMW>$&rHifGM9*6>>q%vz1h|V%xr}iUYtHUwr67E^s!xk?Z zEF*I)(q#J0Vy*c#sDLME;nbJG%T#N+rVz*4+M~O_cU5)nG~wyHoSUnXq&woEm>#L9 zJ)5^{uhnYT?d4C@|A>{SF!{ zX=z$6u$>ga*V&l&gPr|-yn<*RNZFEbpXGy5R>>9x%q(S-1!+aM{VbR3-FTnA4p-yl_VRh)uv`98k%=^5OjBj5>VC&D-0eJhEb%+Hd;$7*kH?VB zCW(z#sw-2Th2eLnyJCbAzE5(Qc4ks^rir?jx4B?sGCblWJGvt9jB8vTmzu>*y|?i-CUR?2MkF_G)|c_V5FQiL z%?DY&=@74t2^1=Y9O?TNFikVD`f4gzvmKm$@x777m0DMGxjCap$D8te$V4ZOKIz*F zc_1OEg!=vTP}12Xs1=f-jOxlGF*#`Fv1y!68l*)nwv}##ln;sg%)(y0N}XY3p3}IE zSHsD>#x*(|x}>k*%_$tsG2e$zc&PcJEMbmNNQU8T>f$l9BmM)Q>5`t`?0SIrIrqW| zYKn?VTc+bV`gqRoOX{|3mv*`SX=T-J$U>i=ltoP7FkeV zfF-D-51xN5AeI52zhs1zeR3<}5_VTo?u_~^FyfoMVKLTT0wvD5ceCy-*z$dYSwc?1 z?U!ToakFkTq#>yHx_N_ei+$7B_Tl$vS?^j}Rr0&_l4KOJLS8g!JzHdI!dqZ-MG>DB zyOa6mBZG?uljc)0B=uBWcB8{vpF$f0SJN1d4#@Nvv0xCvWcc{CRoVM}w)3)+HTANM zuimob^dLkF9c<`}WwJs1-JsVxXEy9yjyC%%M*J&BCo2iAn?2FaXVr;8SW^^c!fHvE#Qx% z@vZk=MTDfaRGl%euO9%Ym@{!iWh}X@j%xZR`)TtI?b#qM-EQh^ zxxyPBxyv}!&Q6nxBiUPcn@nEyWbqwfUJw49{ z8Xq0^uY?>WOO7XJP*8N_fBZHlh=qv*<8a^v160CD+315=mLp9H1tEd|hi8X^3IG#J zj{yJ|6iD%!KvIKE9Y}r0nwhLI3AX|oh9aBHixdGSnj9jO9_g4Ha%q4gFeL{5MOL^E z#sruP3Ru;(ek+!O;Z3Qjt~Mhqk1=r(YtC1q2n_eo*BHmZ#g}Vb-;88#ep5c91*gcizBkq+ zD8p-Z>7l91PH&bpvfjb+P(IL)!T2nprsm8OZl&L`P#UxOi}XnavWAu|=c2VlQrK!> z^v>fiJi@Y#<%S^Zd`ztyB`W|%|26ge`&{P1Q&Dce3`;7bA#iY$aAE(9_ui!Xj?5rzg3E5P|4G8 zkmjvfo&0P`zt)QU{EGVMJxs0?D?~pY7;#(;p!b@8%mW}*_{M*ydQ%eJkLKl5{HS)HXAM**dd`r zF?Am)s;yv@Db1IWtKxf}2o#w7WJU$Fbh=eNKRQ+bxHWH5{@oHjSXe{g#CY7zFq*YA zI{pBLOP2_J6e4`oOh)Zv_0wNTr>z z+FVWHFHMM%oaX6KP#)Ob!Tf0T2v)4wesWeaMkl=Av*^v1g0qiGp2(AKboZ5n=a503qTZ60rqma4XOgf~X?yk2xSJ3kv8){`jpy^ zy26=nClYzPPLC%eAJT7nezRd5UVE&4RD;Dl#zcI5F;(J+XNtKuJiiw&J&8efy=!L3 zUnPi`_c*5!g;X=ww3^*Nn5c2UKVv$&Y7!Slz*Cmk^#$J=3DPR^yu3bKMim7YVNXmg zS=G7N3s&X!TO72%#_P9_;UbXO&I6l43W41 zmjx6^zdq&~oH#ml{yny^#bPY0$?sa1I_JU1Ppit{q;L@NtbcvQ!rExrK=nI2oX9?j z5IWZu&=bPF2_og?8X0~WFDk8MZpjSig!i|_8GO?H68pKHR~x>3Z`Ta5%&@JWPSjX% zKo5QxvA&cG|5Yvo)7t+W>d{s*i(9Z(IJStWqQ`W}haS%x!cLRlM~%)UCa;zp#D8xMt3h?u@@RB zvR}Te2>ujAS0qcVwCSFw;azccN_VI<(}%v7lX~m4*q*8WlE^*vVEvYwD|fi+R5rbZ zpdb$~>?qrTP73A!X2w$n=}pX?6uw#4HL)_0DU@iSA^mE(1? z>{I&pn;#Xd%ex7xupvX@Pl$GflcjCJmBlA=yG(M9-NVA@ZyB>A?9D`=_qpfQcfSmH zA{ZC0-ozej40jcjtM2Uw4$d_GqC+{5?LF}%xo<#tPH~hgEQI8!o;FfSc)sfsroJPr z(@yQ+<;b}V&X%Xa)U5Zrd>QE2c_6h;kz$#frN;GDW{k{NFTS$57H7I5$erjSwr#_$ z|EWs73Ww};u)Al_x~ukD`ay2RtEX6_5)Q75iWXp(<%=I(5{pQtU=vy6Od|7bYB z!pc%au8ZGNXIoB~S3sj&RbjH^>kF&3>GUm4cf;kL2(GSv?8!MWl*2{n0(xLYUBi(y z+tq}gtmea+@qI|QbnvrDW{=jibMOglak3h@h$~I_DmUP}2sZYphJKN1PmRSO)5#$e z*zaX<)o&MJkV!V_qmJs(T?oW`F(f+l)Z)_(F;VJZRfT+=KXm4) zE=onYtFy~&ey_SDxV&zckR%o;2MHWkPXOo}YE2vo%I4uV z0gsi?zM2DDpdsbO{)m>;z*9^^tEV7Le9FksDjQZQr^8TgmTR3*%Api2D2u-0|5lw@ zK__?&x7uFf%36xRFl?wA0fLkQDlesRf(r$u;Da9nv!=*8in7q8bamNOa(SF1a5@}o z6%QC*R&I^N;Nby5$s~G-|yhwKYRRa{97nthH$Vxt0 z0JHRI&UyMdNtdGxwx&N59)>5pJjSkob5D@}ph5dKG$JADh8YeOCDBuFHzyygQ8SCR z48;v>?qj4r&F+js*-|pF$}T8n`tmx(;)O{PSaWX}m$?>BJ{CL}aHEtX;jHKZ1^HNR za^*2o^oF-aU=hS8_Sf)XN3V}$Zre)mY%;f$!b26ATMWH z%&}EqJl3xu09Y0|iNDsN`Ii%iXL5PZW-7x{tZR|hL`SPOaFHf=4Ezk70s_1qTS(Z#2VQDXALwT(jN?*hoPH##g=qF6r@L4A^ zwLEjVJO^H!v#$j9$!jIFy_9bHW?fT{yz(4js2h7}seBDy^7HY6`P<4eiph2H#|F|h zF+D%a9c>Ae?}o8#Zf7o?{g6>3vvV<3rv`@q0Vrqk87Hf!4y-JmZzd8K%ej(jipvJA zwY3vXZ!?b^8+QL)mSVgh;)l*@%$>=Yk@QF#=}nkF+L|BJWikD*`6{ipw04{| z|78==p@gNh$<;kta<7+F(G3v{XS*^1Pc>3t7oMlhC^wf6&R}^oS;9ta`_lW=0zR8+ z*18}2--Z;=0=N4Yroat>-4zx(z2ztg0b?LcO&R~b!1~RF&)!F`&M5|JEBiU+fMD9Q z5^pM*$h6xz6zY8UViJSp{NUIczpeFDdQQZj>Dlt*9yB=Pz3u(uQcs;wl zE}pZu%nXL)I`+6PCVw$6KOu3Qn+v1oKSZuhdmAmOrU#KAX>jS9O%JKw!a{q_5ToPF z3uM+392gq&{jRR$We=$8^2LPk==g8B1D=Iupc9+%>`nfIu1Z8rxF*8-3DzG#Yxyf+ zD$=;i-HXqtxy3+MsQnT#=ck!gU5iv>*l}4^1DDbu*Y+?*LPW>N>&R8Pc!U(a7F?D6 z*y${;iOg>FU=V+)T8mnM$03cHnploe*o`FP*W)^kiChtnTb0;B{5`!FCtl6C1AMJ8 z>d8y1!J%uhzLJIm3$8{9Zp#$p8+dDgRswc7DRY^6xv1R$KH z(`xeCQ6$=w9~qa$4SC{kB+KHd1?-Ex1gtYZekmV2d}K!M2S3hA7{yR2u;&Rw-A~ra z=V~skoH!!WfT|gOAbx>|0;-$JGRZFL>s~<3MR~>{V2Z?%qf{3a&6&e7`8~8WU89sg zzQQ~@y0?MIV{gS+iT&y$xrr5@1ut!XzaYXFoLO7Q%1U;EDtA|Q9?a6u%jZww{_@o@ z)pmC=rqI6TNp^;(0qK%c);l*sp18u{aZXsyK4Kk3EpMO zPsE*_YIsM*xqdnCrE4;!aNm;$-4NOmH&a?OSl*&;J7H1nW3gQpA)4EAqp};G0h-=5 z!$C|TCeTV}HqPV+E9+&Wl}miSTbtP_MqPshA+@MfCceF3WhfLFJsS0tV^UR^{pm6G|#-5H$%1!T!}4;vt)m5%K{{_lUAvmEN6 zVJm5MJR2Q)N~B`^1PDp`*q$H|@j)sQ75oq5>SLdxE_V{j!fM}8ksXQUM*i4iSe2Js z+EHLTXTkSL#|#fv0D{six#UHR|KZiwwND{K2URv{3;-q`YaNtzWd%S&PE@WsuwsUM z0L+3TQ0{Z5F^-G&Wxz@y*JG8o-6JI%%t(2vzq-4Z;IUk%afNi9xTYpz9%djTzPBT0sH)CqHHKly&tgo}~-cmy% z0dNmB|K%DtLDW^gQP@`+%M6apDkGoaQ-v*}!uNlWhj~LSv|cKp^*A^<`cQomM5CQ`|m_B3zkzwdx!>!mHHQdy*8OYeVO+ zatp1`pdg|~l6%^D9k@f<>+$XH6+UlXJ5on9`SG2hC(6PVh%f_p=vCf?jE4CoRCpi} zG%UV8i8iFx&NPzs$X?y&A6R31XoyucvkOsnI&8`H4|kBGejCTQ*P3%NTIYVx7W3}X z7~yR^g1Px7|!+a+XosVbtqU*NX=p09aHq+67eI{L6NC&}blJ~Wyj zY9CT{N$2P*ZkhgVC@LvI;ITwQW4U#M&}f@H`C-;+crE7n!sHL2`jCv~6F%U@kWqmI z6wJwgXEuef^=#iCN-=GzakpE4t4AU3K~UNrX){d7AV`;0nN)TU&nNx^NLPyO5HflD zC8pAs%2toqGIgv}De%{!Q%f%QJBpJxrDuUEL?o;itUXp9@}E$*zmXxO3MzDW&N=)8 z?U==kYcmFjvu@;MoLOPmFrV}JQEKPQPksf#%X51*6d^BSN)d%`jS-Mdwb*UR_QTZC zvpi`VY}wAz$Vs9ARjyQbj*t9VTo_MaT}3p{zGLSF6TUgxRuBzz~!ayn80@7!= z9EE4S4K8Lv)gHn1P4}(NlN+DSh=Pm9J_)_oCl?Ta2txX5%<5|GUL;sUx>gVfxav{y zD!+v9*Ck}PN^`rN^F4Bgy@JHseEfn>HCbZWj}OR#2nE655jmffpLn{X?_ovgWc|<1 zAh$7MF|Qus?EI5DC@@kIj{JhiS!C~wN?lSOize)v6C8mZ@(aicZW@+X<5>m;O|LhjF}*QWNph!Aof&iu6A~{R;4qZfjhOw?6*ERzF}dA>~Xms>{no<3I+)XkUAD>vUHYaO$^w6G%E5|06l zx(}Z;5Xb1yGjE38-ej!pt?wIbpH!b0WhD6^1V8OHs(#l&U>yI*&*T>qUc$v`%Q`S` z95L3+#j%_qOtWB0FK}_~=N(@NbxwI#t$OF&02N#-G&WQT$u~cOwS`Ty2LcWWW< zffp=Y`}9r;5erarIR$~z$t4UJJi{n}z%2ckuZfx1EUz#bH}xTyNd-Hv8} zQfz}B@z#jydQ>rw)g%5Rvbu76Dq_73fM#{(*6I`DtM95Lpx`E*pU-}_Nky|$g>Yce z0rMzEWZhM@9Wp%^(~WgXk2T#rI4E0_bRsonS^;WF%NuK|WOj{(XXBENW3hZd7!Ei| zaGp^o1-b-^D5N7psJ~EAQV!1d5577x;hdPMTa9!;Ddn*E^R*pre)bU;op=@?e?iD= zwmXo`3i#mECwyQW{FTH{xg@UQ3zwWy94MpkyJjn%`|Ch%IH!G;RI%+P^sqZB)lU*|onZ zXAqDpu`p<7qSzuOi4GRZ>(+Gk9lESCd$|bYFndy-h+iZm)O9qJ&`Gx5!=~LF@BEaX zQUo{cx`WQ?C&yU0fzJ{`0nDIcChIXgE!6f63P-@5b7#v|m~WpgA`6o8C`DFgz$!9K zbcsz&n71r`JN^dKKjKxJw9z0Uonh?mtjPx&_ybI>9l?a!7iBzUW?ud18bkC4z|qSe z;WiU_|2=<9ilzV zibuzD%PsQV=!+Z;0-+IiTEh#5V7jm}nri98s)O9rnWmD8YRl_wf*(|tlaimaMRqOX z5;_5X8MfcPRni*gsI4wQie4SthlTCz5#|ZX2n&f)_|k_P@&Ena;JwYM!-#!yDbmb_ z|7p)_>+kvDm)z~6GcX2aohLRl)CYaquEh<*{cd>d15Q)zeu>fZ+WPC8TQ<8-CnwYR zvXoA6d}a$Nc*@FsT4GY}dZM?YNdxZqW6?I6t&Bfj+Oi&t95COt5BpQy)ETYFXT}kF zN?*wat$aHN6KnEf>v?Y#d;t-)nTXR(@Xr;)f9P2dgKQyc;O2d&q}8A&2Q0@@4PM<9 z2l(cohM;7N{%HY;HA45IPcP)C7ph=}X=o_p8U~?eOY@~(O-)&9N^EtLRO$OyzEg9e zzTRo+Zw-1jdxa_*)2Cfrl$&~J839;gi3794QIonIXO5{ToqI!SBtHwzULE5L0*=vh z0Ysjur-EZ`@Eb1dZhS5Qvtsf0#Qkg=2~HUUpp+zvyb0LELTl>c#qSK0rG1ffI=ZEP=)+8g66O#BPdY8ZK8GCDb)k!uC)YQ7vlm{baD7M{nU1n2}1uyEt zab>uCV>?wGT15#h#k=%`uL-_8vqTw=?q^b|8x3Cyl)B#X4wcNQFwOC;%ttEWbfELh zrLY|O&s{3mQedIQ@@^A{iKEFbL$tSLdmml%TvE=A#{l0FYY@;0bhE@RLPTm@VE(E)k_Pr+LEi6;>3-eHX zJug|;>MWP^2e9ciz2Ibu%TP*imPYI3n~S5kYIfacfM@UdFs1}g_asVW578ez3UX;$ zSdr-F9@FIUPAHX1v(?eqJ*soY`nX-!ZaTrvG>2(_<>WiQ;!rNtvbt!_)N(Kc?^j9WbY zWGA5~(wXA`)iI5yJ~MGj0*z5?wFDVeIW)J}4!Gg*{C z*1uDbBhHJ8lF-t~qLTuxOXqyNoSDsr-Gq`LHfr%%r&pNzZjta}kM6<`yGETHl{xLB zLCpdpBYDzw+@*zEV#|6O^V1MqdFqCl&2%Bf)po8J??K~;yAaXd4>p_PDz1k0PH_5z zR~cDxo*Fql@mG@>RAeiVV=l7s!zxH@*KoXP|Ho>JH}(iO+usBcXS##)rcxU=66>4l zrR*=MjX&dY;%dF`!7gT2&(&c!mNm#e-IhCz=rNAB&+NlxTKe>sJWSmFaQ)!3xyYj8 zQtY!2&DgWCWKoqpiJ5E5LoeCVZT<7JZ#OIX48(%^`HgiJ7a|F3iTMI%Ar#XUj!k+N z`6^oE6bZ!L8E2xbuu#t{uuDm<6uz@>ccy<6L?Q@@L_4;rGBat+I~Yvdqu(L7m5XxWwoBYc{4~+$s6V)NGcolo z$_lp{@fk|bTglG1dl@1^j3e3l=kSoz5-!3pZ0^%m-aM>cCLx=J|-XZHFrU2Lx&cD{VXRW?KqdyZ_b*N4;=9#uuxTYt}_-Vv%+6Yg-~kqM@@yd z^>~W|Rpy?IleW07sM*G#m+b2cH9nl)bODWsX~51K(N(`#prCU{Va~@~`5*Y-9RiQ} z^Z&Sc5K<%TU-CS@$bTY%6nqf!zvXQx2+OU+GR}Tg9t&9lRb@Mq3?c=9D$v5t&j;&s zoWha8yx24D!+SC_DMl3Npc<{lQly%2TJtP@s9r~NA&&yojrsJdmM$B6LTfWN-<26( zgD&%^2WrXtFfhY^uAku4;uDdfrZZ3*`ib}5C4mVI&Kw=fdgz|ITn*8bkBhA)t?At6 zbBS+Bw}v&4PB^1&OTpv`Kf{u-fszeq+S#)S>o_Ro=}QfU*x7!mG}vJX`>BzN%+u~j z3^xm&CL8a7m$Gx%M+^q#UyVG_62_T0(c|OS+cB6G5kjTTbTeEFPjzM%iIJmHv-Pn6 z^{xPn4xg8fy$CQjZ zm=~U(gv8-$w1-$C@%#$-Ql-#ha;~^s!LS+Th zbUq;3CDkqqK-Bl|sJ@{zBAfh}nVA;>|G{5*nbUiHaj}iGTot3<=Q8j+&PmdnT6V3O zG`rVVaSRK>U`n|%uBxo72=W*wROrKX5Zq4UH-Kf#d0Sc@XkP_H)i^ zzmYEywb*oazMqBotVxM6xgtD_VcwuTr={KpEtG^hX2jv>Nz{cairepMxzsL)vV#Pa z;uc`$NIk(S;IX`;Nfq+Ovo67At|dz5E=fk+i5PkDuKUXit2So{1IXc^ZBe%46W@D( z8k;^ic4`6Hu!04?W-rDcK$+9{Q%YR*?ak3c>SAg<6`%v5DA$#x$6i%R|td$N~ui)wEan6 z%A#yl)!`CXDN7ya%(4;22^kZju1}dmNP42$C*?(ZS3(!H2Y|$TnAen8kz}SjMHyte zq+L@J%A{iGOfC7eJpBVBLKl19S@NEIoQ6|me>}aM8!I)I=Xic zzK%wL)4V72;9IVFxhSlLwoTMb+0)H3X+nSdY}v%yYh`;n%W(`aw{3btpW5FVGo>y> z6)t!Zz1>EgF6QS}X9MdCNI<+=K)t%OoLux-M(>pbuheiY3G@yODbEC$Ze{D+-=tl& zTKS}h(AK2Q~clbsPuaTF<N>xN zi~!13OqKEaq`_go_R5H|U}0tzq1HTW|GYUO3{yPiY%-4Nllq5UFDoC5XUP>xse`gq ze*hanJUMt#58A8g2i>?dA-dxE>e|=bs;6V7jY?S#7klo117WIGSrmvpG`rVcOZ5P~!-=$LFOdSvz)?@uFx&aZW$ z{rFvP$jtS|`?v61gVv;im}okGuW(P{$(2vGY`+M3AR7~_NSeb6U0A0w(3X12U32MOEQLpbi)VVIPFpU$R{7_wK;E!I6TFca(6I_ z?NA+VsBCAkq$bvy0d3H(jfkp`?jGe{<8$pufS>EgY0YYAYVfI9-X-#Tx-3;}0^amU zb{mTci={eUwdUvyU8}hrAoa++#9n+W6zu7+ZO~-Oh|?Kob#7@qXlPO#6oQ=R`S{kZ zPx|Qe$$u;3vE0+SEW4}Enmu=pG3dUH?!Cop z%iW)mXi@wSSJZmP?@e^GFd|L9}#0U_W%&?I77n+u+Pd%BkLU`4Bn18`(g6w@SG|K0IH9p3h>^^ub`chY!J9oK-(M4q0Cftroi zo?#B7)`whB)W@h4WfQ6NwQjH`3Up1;=0QLlEr69F*Dq~F*DPLrOSKR5fHb*jv|r%z zvrV@?)9Ay{Nzk)L{-wC6m62sP2|7(HBKMhK`42q$V4sP9)9uB7)9lAgd@}5xlsJt` zE7T{A>+v-wC?4qFGXQA>23KfUvjy9cml5qHxOME~Ay(UYMzp!{$Jq2y>iWFQj4G z(n61HY3Du;w}qc3(m}_B*ScfZ^Nno1owZbLq4MDd?Iw?Q+MiMXnn)+QO_s0qEPiA znNO;#fv)hN#jo6{#v^->jYNWax~|K7A@6x0XRG)e^nCMId0>s=FWMMXCwIIONi?;~MO)|QC7EurMQtwWu` zxAGkC6T{H@!J=eDZaYj={VAs-pIR;uK4zreuC&roLMqm1_wowUjq#!&k|9CzrdgL{ zuJG>|fvu`|0I#ClR3)E;?ii(!E}I#u#-f#Gph$9edm@g}@owanEw&g3&X||4 z;%hFVhSZ%T;-C5sY!}h$=HP?o=@LT5E3(4`aA2yQ9*AOj2UHD{VkcO`4*TFnLnX_Q9+U!`{&MeKdM68 z9fqUcB4sN;A;|TUI!r; z0U!E|Mr|bnj(WIXTOcuHAg;WVCs)Qq6K5Qb@K{)X+{@^Cn!!Hnd`I~PGoU}1Mn!XB zydR+UL*Q82)Q);;LPK%&jgNra3r%;FRA)P*@J~~7s$)nvWA10Gjoc{Zi#dkSE6cB{ z%fgmwU-U0lO}0-QHhr$eeyVi}_?04P(9^NscWmZbVSWKB4;g+&%VZ(DWOFLzm{5@W z>xD*k?h6?WqLr`3eczb{jBG@v7yXO;YgQ;5Ru*@ZGtS_O1=^N#bSbzFPFhvj?F0LY z>U7ySCq$L-0(h7IH?M^`3vrgJJT3pL3Det)xkk1Ja<%oYt{SwP=A?i*Kp&I`qzZ3f zW|vCrUQwsw$W%?_50w~zO~Y`$H$=_BW6&!a8c@)?P7`%ByK$m}HoNYyUP%3p1Li^9 zUyfRWHYe46IsL~SpIhDzM}D{S%VOpQCi|1hEc+`dcj(g7fHj*swxvQdkMF**Ktkm< z$%6>UD4Gs6WPSBp-!F4K8(i~&K8UC$T)l<8mbyV|Y1k!D z)n)rbG&2N3_Q}e?$Km(oS|DpBHA!sW&vaN>Dcb=Cm1!Z~=b!mFr$6IkTE+v*8gAqY z7+Rc|HC{}QO0Nq9sbn0p%QkZ1Gs$GT*{SirYBvV@E5U|@=J4ds>hiFYBuF|hSSoy^ z5I&Ba;{`(;&Jq5$o>WUJ&Ft*=aevurJ)`j4MIGlDnoI4Q4!W8je)3Lsg~%lo#lU8n z^0np8H8)t2`hKxPk1>YQO_UK_JNbk)U|_Q+s*N&i=sjZc)M4X#{Gxb}VyxNu1tMvN z`-rKk%f37RAwi`{EYkF26@7kpmgXNo1!voa;g(+%jjP7$IzBt(7`3g@JFVIEW5!(t zH#X1fBMra*1)cr31pEtbos;3!7Sm4{B~x9#pS=tw2+NwBOsqZFW@tX6cmDtuGe|nN z|9Yov8VG(#)=hhTfR-AmSw1dV>Q>{|Lwzh*Ym0G!%GjyWS>Hz-(-bQ;x2MT7BoxA& z6q?Tizx4Z?+2w#t7@yS_%3em8Y99nU_At~SUHKb!iP@V3gWU!MR)yp!trq+#JRbaB zoNLkt(RmDRe`alg=Upp)*e+<6%aNhIU=2Ds83`M{`_8-Qqm!(3pB(ECp2-SG6L{*( z%*ZNuU{v9HqpFM5Xz#Av4%fc_fL>E!qTWy#*jgjm!|;|Be*Q}>S;BtV<#qfQ3!yE! zR~tcMK~HUmakwblU}i9Z0h`VUvTLw_R}jsfRn7;*M*dYW6_1~6L)v!I*g(*SzwA5q zN}p~f@;WnoUK9(!HZ1Edky80>9JmPu^@ZI={--_hZ>+TR*q-YSAEj?|P4a=va<7L2J<<^q+0={o! zKeJnq!1K4>!F?Fa;{&C8V>LOPX!8UpzL*BI7x)qfz;rTymHs~fk3ew0ZJni1_!)te z%zfJ2Al$b{8{K%`(X5t77ro)maV6dAReMJhh+}LnZFduw1(fNrWLn$tD=|;2>Qs_N zIVv7saQyod)6`8H+~!E;laV7|0-VM%To9jkV~|~RA*cI$Yq^bxR@7l=x9=UD^UpMD zZMC&vsBF!umv{w(i;2sYYay*9lt9;L30Y}uN?RNCeIeTwk#47~d!r973^ujO#Ff%W zZd^(2OLpUHDQ=y_B1pAe5K3vE8=73{EyoM2O^~H?Un}0$7Kan=-+|zY7;KP?6Pi|_ zsw2nwtSWsnqG5w-50c5bvA8*Q3_XyB+T1{8!&It6X4MZ;i8 z9!i2R)5;oi0j9{zV2tPQ0C*`0oLPjn>MUd4Y}JZo&@AH15N#z~|O1I}S?}YRb|?ORg*~uF%H|W&87x z(&r+tQqsXF!WeP!yRt@~WK|5}z;D5}DmJeN{@>;ZYu+vxyiCj4oaI1P~M77k;r`XkTHyq%3 zk!1&B5?B_I$hfUtr?qLGz#S9Z-Z_Sa$;(|BaS)3Gz?-P8i8#lhr&BF0vuM9zSwaU6_w;VzTfy|373VIh@39vT&NW_j>bu^>k<&7+d5oLwDRHC>97iJfHHf0l=fu!k~ z(Q}(eW%xx^Ku4DsyVb)YsetC zUI9)=)jVfwDN_O@ZP|X!7fRS6b1vuz?bRhJtpsCz&QXjc+1mH57-M@}1)6+S+L+*D zMge>9vIBR`0EUY!xmj}2Zb%4@_*ydHv&3LKHDS{^!#66gcDE?3u7OlU#yAjD#^|!U zP^AFc$gHO&po^7nLU%5SA_CYz9MPM13kDK9HASSP%o83Zu^l@^mpOJ_bCi-g#x`d} z*ueLqbGt0AF@V@Mn(t!VWrWYv=lEzc%| zK|D+Z-^~kkB$}7~6S|h2zZm@1MucRpWr-g5g_cb9GRR0T3><>JER^jwU_MJ4sio)K ziNvKERA*KQS_uzvJ@;Jfv%H+Z^0MpTf?<)Tw`nQP$r3vhj*NBywy7GlabihG_hTLb zP?%Lb*tOPPi!@a5$A=j10cQIYQo7_7r7r}1I-HF>6;7~dD*Ti+ZD=xLw{q-Zq>ca! z7y<3gS#wOSw6bN&$(i3lX?Hx;(Hnr#>vgk9LnE1-d0UFd`byU}5b@=5QA4|Mq|Qby@=#y~}q zDuL8vdoOZ_?+l$C&tf83T+xs@q5CWI`<9X3wqs+Rt9_%@y4o-sR5sqn0z+a!AtE zxMt`_jn{8a(Ch>k$~%Bt5%g}AquwN?OJgq*E4k)O+0qg3$Uo8$-$7CxXp7zcmFsQT zR4q5%`ITw36tU?W0=Z;onvW-gXI8q{qMN`4qRoL{CT(FI;d*FnEXwT(86q8EnS7I) z_Bcp7HBvu#FXFTZN6!W@dajw(FgIBTm{p&&D4VS8AL3 z;Fm8TjU_(@f8v{S7}7VN8!KY6Gt^V|hMgD_O~ta1Z_5Djav&1?j2;(Ox2`%j(Ldgv z30_6`DHh6q*eGCsYS7)kii?`Y{7(bCsg;W}$bU2k2@hPW u0_@<0_s#0xjnH}#_ z81+*tG@pP58|qwBdo+I{t1n2lYj0`E?h7(rkM z$?5LeTQ!=zp5DA$!`~ZV&`cx!C$eNbRXL0hS%(ein!O$@;WDR72_^o`2 z!CHT~ux_fUgm0#EiyVFYSb%GLFLf%;p6pGZoleqgr8=>O;8^GfBvs%x1p4%t?0M+!hRMO0A;bkq2+}50Dff?wW=yqcyk4N4|a51*$Ow=7b zEFd~Yf^-D(UpVb=w8}H>Fw=^N8xu%?w%g2OpJ#gV`p%W@im61>*34csIFFB-&pE!4 zCRTliUD92dMqDMGpp8K`%b4a7;oJKzb~W+UF~PuE$C~(FeXUV5uKDDB$+#rjK0!2l zZncv&?5dTo4Z_kKZU&Z2_`VC5PN&_+Yf%AnGc9v$`5-~ID5Wkj)I#QiVgdJo?OzEU zty&!6?Gl_{7ragHs?^!LPD)yrO$^y#%siG8bEa3hRnC2B1s^E;Vp{r9D`j<9jjXsW z!~#wWKRRK!jq*)3O+6tL&;s{jIW z3gcmC5T(0l(KH221-gYI%&}wN4!$DT(laLU+oB1xbhoN04ts~lYHCvf%obiB;;7DHOKGKzqbByJn3zKt@ zSkLJO(uu}FG>vanoO|7WqUS7F_rHPd|CID8S)z_kK$3e`EFS7CTm(!Z)u_ znp&tGX>pF;3Jt9%_=R`m`93Ez!RC$oAg^n~hSsOZ+`!(B5c=jo&gLysf*U5T& zY6s4I(FI52K5IXBkCS})S7XXg+22W}AN3EQaRc47j`jCbGwk=Jae^b0X0ZIh?!W&4 zlD%=YANL9>vLCm3z3T zJi?f$zQ0v@E6F*Y5%axo*@sEw(vBxv<*9Gx0>hK+!=;UOdm>^#1hF5@eNH9^iBk`6 z%&#df?3w%{<&n@`w@(k=Y>M`t#^e70@-B`xHANg@(|cGyA*YaG@v{1aJCRbx@0hH- z8}4ah*JI{EM(hFZtaE=1g2UFztl*ZMY%gfj1Aj1A)GiEov)IRfPzUO$%d&P%z=?Kk zGq11RxAI)y4*N-c4vUCg;?I~FQ43h&MgTr%8?2f3l^d=JX&=<Ld7ag7iwKH|(ag z-&Q%z^u3l9Z`pT8Y6sm^)xbD37P+Iqg;oPYoSE}`{fXeYvXJggZc3BQ*=#PqJLJ8_ zuk2Rt#YeWA{W8UGR+Z0H{gQO53z~CHIQ%l#9ebMGrtODZ$N#;u3rZq1( zT=;`K)%vc7^rDX9qhnNnHFG204>nz3?wbVIXQz}qkp;embDT}WMVg{F8Y>GkGJD>?yh|{8yS#?!XqbeHNy~2$A`9Lgy@1 z(#@27owB6EOy^XikY%+odk$qOa`jk7}iN~~~iSLsmzoO09D@9KWK(h_|mB^Vl zRinow;zCAl0alRM{_v^P7Y#(sHgRH$iGRf-h~x#8J?wV){E{^c1LJaK7G7wDqumF@ zrgX0Y%nb`6)$p|Yt#glYNtKl{W$f+)$!SEE%`qg0;(721VZ=0g&km3};4!`0sk%zb zd!U~b%7wDqV!8Maif7U==II_gjg6R{0&m!H-uQ}TdlNF;!*iemFyr2V?J>0bv4h~cPuVoX z;&=)tW^Dem$?i&JQb# ^+=QqrnPE-qCktx~A;s>ihVqUc&scxOE8s0OPp# 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
` element. + * + * The major difference between this function and using the built-in `request.formData()` API is the + * ability to customize the handling of file uploads. Instead of buffering the entire file in memory, + * the `handleFileUpload` function allows you to store the file on disk or in a cloud storage service. + */ +export async function parseFormData( + request: Request, + handleFileUpload: FileUploadHandler = defaultFileUploadHandler +): Promise { + if (isUrlEncodedRequest(request)) { + let formData = new FormData(); + let params = new URLSearchParams(await request.text()); + + for (let [key, value] of params) { + formData.append(key, value); + } + + return formData; + } + + if (isMultipartRequest(request)) { + let formData = new FormData(); + + for await (let part of parseMultipartRequest(request)) { + if (!part.name) continue; + + if (part.isFile) { + formData.append(part.name, await handleFileUpload(part)); + } else { + formData.append(part.name, await part.text()); + } + } + + return formData; + } + + throw new Error( + `Cannot parse form data from request Content-Type "${request.headers.get( + "Content-Type" + )}"` + ); +} From 349bd8bbf4a231e873116ee093ea781962ba1921 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 19 Aug 2024 14:16:29 -0700 Subject: [PATCH 263/730] Build and get test passing --- package.json | 28 ++++++++++++++++++--------- src/form-data-parser.ts | 6 +----- src/lib/form-data.spec.ts | 40 +++++++++++++++++++++++++++------------ src/lib/form-data.ts | 33 +++----------------------------- tsconfig.json | 8 ++++++++ tsconfig.lib.json | 9 +++++++++ tsconfig.spec.json | 8 ++++++++ 7 files changed, 76 insertions(+), 56 deletions(-) create mode 100644 tsconfig.json create mode 100644 tsconfig.lib.json create mode 100644 tsconfig.spec.json diff --git a/package.json b/package.json index 53a619bc4bd..e50f913182a 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,11 @@ { - "name": "form-data-parser", + "name": "@mjackson/form-data-parser", "version": "1.0.0", - "description": "", + "description": "A request.formData() replacement with pluggable file upload handling", "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", + "author": "Michael Jackson ", + "license": "MIT", + "type": "module", "dependencies": { "@mjackson/multipart-parser": "^0.6.1" }, @@ -17,5 +14,18 @@ "prettier": "^3.3.3", "tsimp": "^2.0.11", "typescript": "^5.5.4" - } + }, + "scripts": { + "build": "tsc --outDir dist --project tsconfig.lib.json", + "test": "node --import tsimp/import --test ./src/**/*.spec.ts", + "prepare": "pnpm run build", + "version": "node scripts/version.js" + }, + "packageManager": "pnpm@9.7.1", + "keywords": [ + "form-data", + "FormData", + "multipart", + "parser" + ] } diff --git a/src/form-data-parser.ts b/src/form-data-parser.ts index 63fdc81a1ab..cd1863ef275 100644 --- a/src/form-data-parser.ts +++ b/src/form-data-parser.ts @@ -1,5 +1 @@ -export { - isUrlEncodedRequest, - type FileUploadHandler, - parseFormData -} from "./lib/form-data.js"; +export { type FileUploadHandler, parseFormData } from "./lib/form-data.js"; diff --git a/src/lib/form-data.spec.ts b/src/lib/form-data.spec.ts index cf49ddb18c1..4c73da7b55a 100644 --- a/src/lib/form-data.spec.ts +++ b/src/lib/form-data.spec.ts @@ -1,22 +1,38 @@ import * as assert from "node:assert/strict"; import { describe, it } from "node:test"; -import { isUrlEncodedRequest, parseFormData } from "./form-data.js"; +import { parseFormData } from "./form-data.js"; -describe("isUrlEncodedRequest", () => { - it('returns true for "application/x-www-form-urlencoded" requests', () => { - let request = new Request("https://example.com", { - headers: { "Content-Type": "application/x-www-form-urlencoded" } +describe("parseFormData", () => { + it("should parse a multipart request", async () => { + let request = new Request("http://localhost:8080", { + method: "POST", + headers: { + "Content-Type": + "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" + }, + body: [ + "------WebKitFormBoundary7MA4YWxkTrZu0gW", + 'Content-Disposition: form-data; name="text"', + "", + "Hello, World!", + "------WebKitFormBoundary7MA4YWxkTrZu0gW", + 'Content-Disposition: form-data; name="file"; filename="example.txt"', + "Content-Type: text/plain", + "", + "This is an example file.", + "------WebKitFormBoundary7MA4YWxkTrZu0gW--" + ].join("\r\n") }); - assert.ok(isUrlEncodedRequest(request)); - }); + let formData = await parseFormData(request); - it('returns false for "multipart/form-data" requests', () => { - let request = new Request("https://example.com", { - headers: { "Content-Type": "multipart/form-data" } - }); + assert.equal(formData.get("text"), "Hello, World!"); - assert.ok(!isUrlEncodedRequest(request)); + let file = formData.get("file"); + assert.ok(file instanceof File); + assert.equal(file.name, "example.txt"); + assert.equal(file.type, "text/plain"); + assert.equal(await file.text(), "This is an example file."); }); }); diff --git a/src/lib/form-data.ts b/src/lib/form-data.ts index bf05d0c68b5..ec54b2bedf5 100644 --- a/src/lib/form-data.ts +++ b/src/lib/form-data.ts @@ -4,17 +4,6 @@ import { type MultipartPart } from "@mjackson/multipart-parser"; -/** - * Returns true if the request is URL encoded. - */ -export function isUrlEncodedRequest(request: Request): boolean { - let contentType = request.headers.get("Content-Type"); - return ( - contentType != null && - contentType.startsWith("application/x-www-form-urlencoded") - ); -} - /** * A function used for handling file uploads. */ @@ -23,9 +12,8 @@ export interface FileUploadHandler { } async function defaultFileUploadHandler(part: MultipartPart): Promise { - return new File([await part.arrayBuffer()], part.filename ?? "", { - type: part.mediaType - }); + let buffer = await part.arrayBuffer(); + return new File([buffer], part.filename ?? "", { type: part.mediaType }); } /** @@ -40,17 +28,6 @@ export async function parseFormData( request: Request, handleFileUpload: FileUploadHandler = defaultFileUploadHandler ): Promise { - if (isUrlEncodedRequest(request)) { - let formData = new FormData(); - let params = new URLSearchParams(await request.text()); - - for (let [key, value] of params) { - formData.append(key, value); - } - - return formData; - } - if (isMultipartRequest(request)) { let formData = new FormData(); @@ -67,9 +44,5 @@ export async function parseFormData( return formData; } - throw new Error( - `Cannot parse form data from request Content-Type "${request.headers.get( - "Content-Type" - )}"` - ); + return request.formData(); } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000000..d8aaef54f9d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "lib": ["DOM", "ES2020"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true + } +} diff --git a/tsconfig.lib.json b/tsconfig.lib.json new file mode 100644 index 00000000000..8e712f7d6c8 --- /dev/null +++ b/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.spec.ts"], + "compilerOptions": { + "composite": true, + "rootDir": "src" + } +} diff --git a/tsconfig.spec.json b/tsconfig.spec.json new file mode 100644 index 00000000000..ccfefc4d957 --- /dev/null +++ b/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.spec.ts"], + "compilerOptions": { + "composite": true, + "types": ["node"] + } +} From e15394a81f40e7492d957d3fea6bdb7be3d805bf Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 19 Aug 2024 14:37:55 -0700 Subject: [PATCH 264/730] Add LICENSE --- LICENSE | 21 +++++++++++++++++ package.json | 16 +++++++++++-- src/lib/form-data.spec.ts | 49 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..717984c0442 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Michael Jackson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package.json b/package.json index e50f913182a..4bfbbeb3f71 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,23 @@ { "name": "@mjackson/form-data-parser", "version": "1.0.0", - "description": "A request.formData() replacement with pluggable file upload handling", - "main": "index.js", + "description": "A request.formData() wrapper with pluggable file upload handling", "author": "Michael Jackson ", + "repository": { + "type": "git", + "url": "git+https://github.com/mjackson/form-data-parser.git" + }, "license": "MIT", + "files": [ + "dist", + "LICENSE", + "README.md" + ], "type": "module", + "exports": { + ".": "./dist/form-data-parser.js", + "./package.json": "./package.json" + }, "dependencies": { "@mjackson/multipart-parser": "^0.6.1" }, diff --git a/src/lib/form-data.spec.ts b/src/lib/form-data.spec.ts index 4c73da7b55a..06b9367e1cc 100644 --- a/src/lib/form-data.spec.ts +++ b/src/lib/form-data.spec.ts @@ -1,10 +1,24 @@ import * as assert from "node:assert/strict"; -import { describe, it } from "node:test"; +import { describe, it, mock } from "node:test"; -import { parseFormData } from "./form-data.js"; +import { type FileUploadHandler, parseFormData } from "./form-data.js"; describe("parseFormData", () => { - it("should parse a multipart request", async () => { + it("parses a application/x-www-form-urlencoded request", async () => { + let request = new Request("http://localhost:8080", { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded" + }, + body: "text=Hello%2C%20World!" + }); + + let formData = await parseFormData(request); + + assert.equal(formData.get("text"), "Hello, World!"); + }); + + it("parses a multipart/form-data request", async () => { let request = new Request("http://localhost:8080", { method: "POST", headers: { @@ -35,4 +49,33 @@ describe("parseFormData", () => { assert.equal(file.type, "text/plain"); assert.equal(await file.text(), "This is an example file."); }); + + it("calls the file upload handler for each file part", async () => { + let request = new Request("http://localhost:8080", { + method: "POST", + headers: { + "Content-Type": + "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" + }, + body: [ + "------WebKitFormBoundary7MA4YWxkTrZu0gW", + 'Content-Disposition: form-data; name="file1"; filename="example.txt"', + "Content-Type: text/plain", + "", + "This is an example file.", + "------WebKitFormBoundary7MA4YWxkTrZu0gW", + 'Content-Disposition: form-data; name="file2"; filename="example.txt"', + "Content-Type: text/plain", + "", + "This is another example file.", + "------WebKitFormBoundary7MA4YWxkTrZu0gW--" + ].join("\r\n") + }); + + let fileUploadHandler = mock.fn(); + + await parseFormData(request, fileUploadHandler); + + assert.equal(fileUploadHandler.mock.calls.length, 2); + }); }); From 5790dcbf34597df0f44b5eaff0a950894c7765d5 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 19 Aug 2024 14:43:46 -0700 Subject: [PATCH 265/730] Update CHANGELOG title --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5a07e0ecc4..98dd01fb610 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,9 @@ -# `multipart-parser` CHANGELOG +# multipart-parser CHANGELOG ## HEAD - Provide correct type for `part.arrayBuffer()` -- `part.isFile` now defaults to `true` if `part.mediaType === 'application/octet-stream'` +- `part.isFile` now correctly detects `part.mediaType === 'application/octet-stream'` ## v0.6.1 (Aug 18, 2024) From 92bb72152e2eee91215e2cb927e21e5ec94c1fc0 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 19 Aug 2024 14:45:19 -0700 Subject: [PATCH 266/730] Version 0.6.2 --- CHANGELOG.md | 2 +- jsr.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98dd01fb610..fcceb1e7503 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # multipart-parser CHANGELOG -## HEAD +## v0.6.2 (Aug 19, 2024) - Provide correct type for `part.arrayBuffer()` - `part.isFile` now correctly detects `part.mediaType === 'application/octet-stream'` diff --git a/jsr.json b/jsr.json index c25294a04c1..04f9ab7f050 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.6.1", + "version": "0.6.2", "exports": "./src/multipart-parser.ts", "publish": { "include": [ diff --git a/package.json b/package.json index 040cd63ca5e..061428895f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.6.1", + "version": "0.6.2", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "repository": { From 45008c6c5ba7d7d5acdb2ebdb48f1188427d8562 Mon Sep 17 00:00:00 2001 From: Arno Saine Date: Tue, 20 Aug 2024 18:56:15 +0300 Subject: [PATCH 267/730] Add Accept-Language header implementation --- README.md | 27 +++++++ src/headers.ts | 1 + src/lib/accept-language.spec.ts | 138 ++++++++++++++++++++++++++++++++ src/lib/accept-language.ts | 122 ++++++++++++++++++++++++++++ src/lib/super-headers.spec.ts | 25 ++++++ src/lib/super-headers.ts | 10 +++ 6 files changed, 323 insertions(+) create mode 100644 src/lib/accept-language.spec.ts create mode 100644 src/lib/accept-language.ts diff --git a/README.md b/README.md index f0d43ebe41a..ebd64e19931 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,14 @@ import Headers from '@mjackson/headers'; let headers = new Headers(); +// Accept-Language + +headers.acceptLanguage = 'en-US,en;q=0.9'; + +console.log(headers.acceptLanguage.languages); // [ 'en-US', 'en' ] +console.log(headers.acceptLanguage.entries()); +// [Map Entries] { [ 'en-US', 1 ], [ 'en', 0.9 ] } + // Content-Type headers.contentType = 'application/json; charset=utf-8'; @@ -155,6 +163,7 @@ All individual header classes may be initialized with either a) the string value The following headers are currently supported: +- [`Accept-Language`](#accept-language) - [`Cache-Control`](#cache-control) - [`Content-Disposition`](#content-disposition) - [`Content-Type`](#content-type) @@ -163,6 +172,24 @@ The following headers are currently supported: If you need support for a header that isn't listed here, please [send a PR](https://github.com/mjackson/headers/pulls)! The goal is to have first-class support for all common HTTP headers. +### Accept-Language + +```ts +let header = new AcceptLanguage('en-US,en;q=0.9'); +header.get('en-US'); // 1 +header.set('en-US', 0.8); +header.delete('en-US'); +header.has('en'); // true + +// Iterate over language/quality pairs +for (let [language, quality] of header) { + // ... +} + +let header = new AcceptLanguage(['en-US', ['en', 0.9]]); +let header = new AcceptLanguage({ 'en-US': 1, en: 0.9 }); +``` + ### Cache-Control ```ts diff --git a/src/headers.ts b/src/headers.ts index fb2233f55f9..e8a5376a279 100644 --- a/src/headers.ts +++ b/src/headers.ts @@ -1,3 +1,4 @@ +export { AcceptLanguageInit, AcceptLanguage } from './lib/accept-language.js'; export { CacheControlInit, CacheControl } from './lib/cache-control.js'; export { ContentDispositionInit, ContentDisposition } from './lib/content-disposition.js'; export { ContentTypeInit, ContentType } from './lib/content-type.js'; diff --git a/src/lib/accept-language.spec.ts b/src/lib/accept-language.spec.ts new file mode 100644 index 00000000000..676124398a7 --- /dev/null +++ b/src/lib/accept-language.spec.ts @@ -0,0 +1,138 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { AcceptLanguage } from './accept-language.js'; + +describe('Accept-Language', () => { + it('initializes with an empty string', () => { + let header = new AcceptLanguage(''); + assert.equal(header.size, 0); + }); + + it('initializes with a string', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + assert.equal(header.get('en-US'), 1); + assert.equal(header.get('en'), 0.9); + }); + + it('initializes with an array', () => { + let header = new AcceptLanguage(['en-US', ['en', 0.9], ['fi', undefined], ['fi-FI']]); + assert.equal(header.get('en-US'), 1); + assert.equal(header.get('en'), 0.9); + assert.equal(header.get('fi'), 1); + assert.equal(header.get('fi-FI'), 1); + }); + + it('initializes with an object', () => { + let header = new AcceptLanguage({ 'en-US': undefined, en: 0.9 }); + assert.equal(header.get('en-US'), 1); + assert.equal(header.get('en'), 0.9); + }); + + it('initializes with another Accept-Language', () => { + let header = new AcceptLanguage(new AcceptLanguage('en-US,en;q=0.9')); + assert.equal(header.get('en-US'), 1); + assert.equal(header.get('en'), 0.9); + }); + + it('handles whitespace in initial value', () => { + let header = new AcceptLanguage(' en-US , en;q= 0.9 '); + assert.equal(header.get('en-US'), 1); + assert.equal(header.get('en'), 0.9); + }); + + it('sets and gets languages', () => { + let header = new AcceptLanguage(''); + header.set('en', 0.9); + assert.equal(header.get('en'), 0.9); + }); + + it('deletes languages', () => { + let header = new AcceptLanguage('en-US'); + assert.equal(header.delete('en-US'), true); + assert.equal(header.delete('en'), false); + assert.equal(header.get('en-US'), undefined); + }); + + it('checks if language exists', () => { + let header = new AcceptLanguage('en-US'); + assert.equal(header.has('en-US'), true); + assert.equal(header.has('fs'), false); + }); + + it('clears all languages', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + header.clear(); + assert.equal(header.size, 0); + }); + + it('iterates over entries', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + let entries = Array.from(header.entries()); + assert.deepEqual(entries, [ + ['en-US', 1], + ['en', 0.9], + ]); + }); + + it('gets all languages', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + assert.deepEqual(header.languages, ['en-US', 'en']); + }); + + it('gets all qualities', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + assert.deepEqual(header.qualities, [1, 0.9]); + }); + + it('uses forEach correctly', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + let result: [string, number][] = []; + header.forEach((language, quality) => { + result.push([language, quality]); + }); + assert.deepEqual(result, [ + ['en-US', 1], + ['en', 0.9], + ]); + }); + + it('returns correct size', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + assert.equal(header.size, 2); + }); + + it('converts to string correctly', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + assert.equal(header.toString(), 'en-US,en;q=0.9'); + }); + + it('is directly iterable', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + let entries = Array.from(header); + assert.deepEqual(entries, [ + ['en-US', 1], + ['en', 0.9], + ]); + }); + + it('handles setting empty quality values', () => { + let header = new AcceptLanguage(''); + header.set('en-US'); + assert.equal(header.get('en-US'), 1); + assert.equal(header.toString(), 'en-US'); + }); + + it('overwrites existing quality values', () => { + let header = new AcceptLanguage('en;q=0.9'); + header.set('en', 1); + assert.equal(header.get('en'), 1); + }); + + it('handles setting wildcard value', () => { + let header = new AcceptLanguage(''); + header.set('*'); + assert.equal(header.get('*'), 1); + assert.equal(header.toString(), '*'); + }); +}); diff --git a/src/lib/accept-language.ts b/src/lib/accept-language.ts new file mode 100644 index 00000000000..5b0ed9aa065 --- /dev/null +++ b/src/lib/accept-language.ts @@ -0,0 +1,122 @@ +import { HeaderValue } from './header-value.js'; +import { parseParams } from './param-values.js'; +import { isIterable } from './utils.js'; + +export type AcceptLanguageInit = + | Iterable + | Record; + +/** + * The value of a `Accept-Language` HTTP header. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) + */ +export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { + #map: Map; + + constructor(init?: string | AcceptLanguageInit) { + this.#map = new Map(); + if (init) { + if (typeof init === 'string') { + let params = parseParams(init, ','); + for (let [language, quality] of params) { + if (typeof quality === 'string') { + language = language.slice(0, -2).trim(); + } else { + quality = '1'; + } + this.#map.set(language, Number(quality)); + } + } else if (isIterable(init)) { + for (let language of init) { + let quality; + if (Array.isArray(language)) { + [language, quality] = language; + } + this.#map.set(language, quality ?? 1); + } + } else { + for (let language in init) { + if (Object.prototype.hasOwnProperty.call(init, language)) { + this.#map.set(language, init[language] ?? 1); + } + } + } + } + } + + /** + * Gets the quality of a language with the given locale identifier from the `Accept-Language` header. + */ + get(language: string): number | undefined { + return this.#map.get(language); + } + + /** + * Sets a language with the given quality in the `Accept-Language` header. + */ + set(language: string, quality = 1): void { + this.#map.set(language, quality); + } + + /** + * Removes a language with the given locale identifier from the `Accept-Language` header. + */ + delete(language: string): boolean { + return this.#map.delete(language); + } + + /** + * True if a language with the given locale identifier in the `Accept-Language` header. + */ + has(language: string): boolean { + return this.#map.has(language); + } + + /** + * Removes all languages from the `Accept-Language` header. + */ + clear(): void { + this.#map.clear(); + } + + entries(): IterableIterator<[string, number]> { + return this.#map.entries(); + } + + get languages(): string[] { + return Array.from(this.#map.keys()); + } + + get qualities(): number[] { + return Array.from(this.#map.values()); + } + + [Symbol.iterator](): IterableIterator<[string, number]> { + return this.entries(); + } + + forEach( + callback: (language: string, quality: number, map: Map) => void, + thisArg?: any, + ): void { + this.#map.forEach((quality, language, map) => callback(language, quality, map), thisArg); + } + + /** + * The number of languages in the `Accept-Language` header. + */ + get size(): number { + return this.#map.size; + } + + toString(): string { + let pairs: string[] = []; + + for (let [language, quality] of this.#map) { + pairs.push(`${language}${quality === 1 ? '' : `;q=${quality}`}`); + } + + return pairs.join(','); + } +} diff --git a/src/lib/super-headers.spec.ts b/src/lib/super-headers.spec.ts index 0182d10b51c..c8bfee2edf8 100644 --- a/src/lib/super-headers.spec.ts +++ b/src/lib/super-headers.spec.ts @@ -1,6 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; +import { AcceptLanguage } from './accept-language.js'; import { CacheControl } from './cache-control.js'; import { ContentDisposition } from './content-disposition.js'; import { ContentType } from './content-type.js'; @@ -56,6 +57,13 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Content-Type'), 'text/plain'); }); + it('initializes with a AcceptLanguageInit', () => { + let headers = new SuperHeaders({ + acceptLanguage: { 'en-US': 1, en: 0.9 }, + }); + assert.equal(headers.get('Accept-Language'), 'en-US,en;q=0.9'); + }); + it('initializes with a CacheControlInit', () => { let headers = new SuperHeaders({ cacheControl: 'public, max-age=3600' }); assert.equal(headers.get('Cache-Control'), 'public, max-age=3600'); @@ -196,6 +204,20 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Age'), '42'); }); + it('handles Accept-Language header', () => { + let headers = new SuperHeaders(); + headers.acceptLanguage = 'en-US,en;q=0.9'; + + assert.ok(headers.acceptLanguage instanceof AcceptLanguage); + assert.deepStrictEqual(headers.acceptLanguage.languages, ['en-US', 'en']); + + headers.acceptLanguage.set('en', 0.8); + assert.equal(headers.get('Accept-Language'), 'en-US,en;q=0.8'); + + headers.acceptLanguage = { 'fi-FI': 1, fi: 0.9 }; + assert.equal(headers.get('Accept-Language'), 'fi-FI,fi;q=0.9'); + }); + it('handles Cache-Control header', () => { let headers = new SuperHeaders(); headers.cacheControl = 'public, max-age=3600'; @@ -306,6 +328,9 @@ describe('SuperHeaders', () => { it('creates empty header objects when accessed', () => { let headers = new SuperHeaders(); + assert.ok(headers.acceptLanguage instanceof AcceptLanguage); + assert.equal(headers.acceptLanguage.toString(), ''); + assert.ok(headers.cacheControl instanceof CacheControl); assert.equal(headers.cacheControl.toString(), ''); diff --git a/src/lib/super-headers.ts b/src/lib/super-headers.ts index cf07cdaebd6..305ecc9cbcf 100644 --- a/src/lib/super-headers.ts +++ b/src/lib/super-headers.ts @@ -1,3 +1,4 @@ +import { AcceptLanguageInit, AcceptLanguage } from './accept-language.js'; import { CacheControlInit, CacheControl } from './cache-control.js'; import { ContentDispositionInit, ContentDisposition } from './content-disposition.js'; import { ContentTypeInit, ContentType } from './content-type.js'; @@ -11,6 +12,7 @@ const CRLF = '\r\n'; const SetCookieKey = 'set-cookie'; interface SuperHeadersPropertyInit { + acceptLanguage?: AcceptLanguageInit; age?: string | number; cacheControl?: string | CacheControlInit; contentDisposition?: string | ContentDispositionInit; @@ -189,6 +191,14 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> // Header-specific getters and setters + get acceptLanguage(): AcceptLanguage { + return this.#getHeaderValue('accept-language', AcceptLanguage); + } + + set acceptLanguage(value: string | AcceptLanguageInit) { + this.#setHeaderValue('accept-language', AcceptLanguage, value); + } + get age(): number | undefined { return this.#getNumberValue('age'); } From bb8db2b6645051d132b8389f9682ccbf648ef78b Mon Sep 17 00:00:00 2001 From: Arno Saine Date: Wed, 21 Aug 2024 00:42:55 +0300 Subject: [PATCH 268/730] Sort initial and updated languages by quality --- src/lib/accept-language.spec.ts | 16 ++++++++++++++++ src/lib/accept-language.ts | 6 ++++++ 2 files changed, 22 insertions(+) diff --git a/src/lib/accept-language.spec.ts b/src/lib/accept-language.spec.ts index 676124398a7..f1ca9c96b67 100644 --- a/src/lib/accept-language.spec.ts +++ b/src/lib/accept-language.spec.ts @@ -135,4 +135,20 @@ describe('Accept-Language', () => { assert.equal(header.get('*'), 1); assert.equal(header.toString(), '*'); }); + + it('sorts initial value', () => { + let header = new AcceptLanguage('en;q=0.9,en-US'); + assert.equal(header.toString(), 'en-US,en;q=0.9'); + assert.deepEqual(header.languages, ['en-US', 'en']); + }); + + it('sorts updated value', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + header.set('fi'); + assert.equal(header.toString(), 'en-US,fi,en;q=0.9'); + assert.deepEqual(header.languages, ['en-US', 'fi', 'en']); + header.set('en-US', 0.8); + assert.equal(header.toString(), 'fi,en;q=0.9,en-US;q=0.8'); + assert.deepEqual(header.languages, ['fi', 'en', 'en-US']); + }); }); diff --git a/src/lib/accept-language.ts b/src/lib/accept-language.ts index 5b0ed9aa065..299aa41f271 100644 --- a/src/lib/accept-language.ts +++ b/src/lib/accept-language.ts @@ -42,9 +42,14 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { } } } + this.#sort(); } } + #sort() { + this.#map = new Map([...this.#map].sort(([, a], [, b]) => b - a)); + } + /** * Gets the quality of a language with the given locale identifier from the `Accept-Language` header. */ @@ -57,6 +62,7 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { */ set(language: string, quality = 1): void { this.#map.set(language, quality); + this.#sort(); } /** From 80d547d902558631258439ac9bc6b5ad9148f3f3 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 07:15:07 -0700 Subject: [PATCH 269/730] Initial commit --- .gitignore | 7 + package.json | 41 +++ pnpm-lock.yaml | 387 +++++++++++++++++++++++++ src/file-storage.ts | 1 + src/global.d.ts | 6 + src/lib/byte-range.ts | 29 ++ src/lib/disk-file-storage.node.spec.ts | 40 +++ src/lib/disk-file-storage.node.ts | 201 +++++++++++++ src/lib/file-storage.ts | 21 ++ src/lib/lazy-file.spec.ts | 141 +++++++++ src/lib/lazy-file.ts | 122 ++++++++ src/lib/memory-file-storage.ts | 24 ++ src/lib/range-stream.spec.ts | 67 +++++ src/lib/range-stream.ts | 35 +++ test.ts | 31 ++ tsconfig.json | 8 + tsconfig.lib.json | 9 + tsconfig.spec.json | 8 + 18 files changed, 1178 insertions(+) create mode 100644 .gitignore create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 src/file-storage.ts create mode 100644 src/global.d.ts create mode 100644 src/lib/byte-range.ts create mode 100644 src/lib/disk-file-storage.node.spec.ts create mode 100644 src/lib/disk-file-storage.node.ts create mode 100644 src/lib/file-storage.ts create mode 100644 src/lib/lazy-file.spec.ts create mode 100644 src/lib/lazy-file.ts create mode 100644 src/lib/memory-file-storage.ts create mode 100644 src/lib/range-stream.spec.ts create mode 100644 src/lib/range-stream.ts create mode 100644 test.ts create mode 100644 tsconfig.json create mode 100644 tsconfig.lib.json create mode 100644 tsconfig.spec.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..52d6954a864 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.tsimp +.wrangler +dist +node_modules +test-disk-storage + +*.tsbuildinfo \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000000..7079d52d1ce --- /dev/null +++ b/package.json @@ -0,0 +1,41 @@ +{ + "name": "@mjackson/file-storage", + "version": "0.1.0", + "description": "Key/value storage for JavaScript File objects", + "author": "Michael Jackson ", + "repository": { + "type": "git", + "url": "git+https://github.com/mjackson/file-storage.git" + }, + "license": "MIT", + "files": [ + "dist", + "LICENSE", + "README.md" + ], + "type": "module", + "exports": { + ".": "./dist/file-storage.js", + "./package.json": "./package.json" + }, + "devDependencies": { + "@types/node": "^20.14.10", + "prettier": "^3.3.3", + "tsimp": "^2.0.11", + "typescript": "^5.5.3" + }, + "scripts": { + "clean": "git clean -fdX .", + "build": "tsc --outDir dist --project tsconfig.lib.json", + "test": "node --import tsimp/import --test ./src/**/*.spec.ts", + "prepare": "npm run build", + "version": "node scripts/version.js" + }, + "packageManager": "pnpm@9.7.1", + "keywords": [ + "file", + "storage", + "stream", + "fs" + ] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000000..5cacec13ea8 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,387 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@types/node': + specifier: ^20.14.10 + version: 20.16.1 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + tsimp: + specifier: ^2.0.11 + version: 2.0.11(typescript@5.5.4) + typescript: + specifier: ^5.5.3 + version: 5.5.4 + +packages: + + '@isaacs/cached@1.0.1': + resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} + + '@isaacs/catcher@1.0.4': + resolution: {integrity: sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@types/node@20.16.1': + resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sock-daemon@1.4.2: + resolution: {integrity: sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg==} + engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} + + socket-post-message@1.0.3: + resolution: {integrity: sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + tsimp@2.0.11: + resolution: {integrity: sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==} + engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.1.0 + + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + walk-up-path@3.0.1: + resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + +snapshots: + + '@isaacs/cached@1.0.1': + dependencies: + '@isaacs/catcher': 1.0.4 + + '@isaacs/catcher@1.0.4': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@types/node@20.16.1': + dependencies: + undici-types: 6.19.8 + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + balanced-match@1.0.2: {} + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 1.11.1 + + is-fullwidth-code-point@3.0.0: {} + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + lru-cache@10.4.3: {} + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + + mkdirp@3.0.1: {} + + package-json-from-dist@1.0.0: {} + + path-key@3.1.1: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + pirates@4.0.6: {} + + prettier@3.3.3: {} + + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + sock-daemon@1.4.2: + dependencies: + rimraf: 5.0.10 + signal-exit: 4.1.0 + socket-post-message: 1.0.3 + + socket-post-message@1.0.3: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + tsimp@2.0.11(typescript@5.5.4): + dependencies: + '@isaacs/cached': 1.0.1 + '@isaacs/catcher': 1.0.4 + foreground-child: 3.3.0 + mkdirp: 3.0.1 + pirates: 4.0.6 + rimraf: 5.0.10 + signal-exit: 4.1.0 + sock-daemon: 1.4.2 + typescript: 5.5.4 + walk-up-path: 3.0.1 + + typescript@5.5.4: {} + + undici-types@6.19.8: {} + + walk-up-path@3.0.1: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 diff --git a/src/file-storage.ts b/src/file-storage.ts new file mode 100644 index 00000000000..d558de6cddc --- /dev/null +++ b/src/file-storage.ts @@ -0,0 +1 @@ +export { type FileStorage } from "./lib/file-storage.js"; diff --git a/src/global.d.ts b/src/global.d.ts new file mode 100644 index 00000000000..b8041179bc5 --- /dev/null +++ b/src/global.d.ts @@ -0,0 +1,6 @@ +// See https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62651 + +interface ReadableStream { + values(options?: { preventCancel?: boolean }): AsyncIterableIterator; + [Symbol.asyncIterator](): AsyncIterableIterator; +} diff --git a/src/lib/byte-range.ts b/src/lib/byte-range.ts new file mode 100644 index 00000000000..ace08357e66 --- /dev/null +++ b/src/lib/byte-range.ts @@ -0,0 +1,29 @@ +export interface ByteRange { + /** + * The start index of the range (inclusive). + */ + start: number; + /** + * The end index of the range (exclusive). + */ + end: number; +} + +export function validateByteRange(range: ByteRange): void { + if ( + (range.start < 0 && + (range.end < range.start || range.end >= 0) && + range.end !== Infinity) || + (range.end >= 0 && range.end < range.start) || + range.start === Infinity + ) { + throw new Error(`Invalid byte range: ${range.start}-${range.end}`); + } +} + +export function addByteRanges(a: ByteRange, b: ByteRange): ByteRange { + return { + start: a.start + b.start, + end: a.end === Infinity ? b.end : a.end + b.end + }; +} diff --git a/src/lib/disk-file-storage.node.spec.ts b/src/lib/disk-file-storage.node.spec.ts new file mode 100644 index 00000000000..80ad2f37628 --- /dev/null +++ b/src/lib/disk-file-storage.node.spec.ts @@ -0,0 +1,40 @@ +import * as assert from "node:assert/strict"; +import { describe, it } from "node:test"; +import * as path from "node:path"; + +import { DiskFileStorage } from "./disk-file-storage.node.js"; + +const __dirname = new URL(".", import.meta.url).pathname; + +describe("DiskFileStorage (node)", () => { + let directory = path.resolve(__dirname, "../../test-disk-storage"); + + it("stores and retrieves files", async () => { + let storage = new DiskFileStorage(directory); + let file = new File(["Hello, world!"], "hello.txt", { type: "text/plain" }); + + await storage.put("hello", file); + + assert.ok(await storage.has("hello")); + + let retrieved = await storage.get("hello"); + + assert.ok(retrieved); + assert.equal(retrieved.name, "hello.txt"); + assert.equal(retrieved.type, "text/plain"); + assert.equal(retrieved.size, 13); + + let buffer = await retrieved.arrayBuffer(); + + assert.equal(buffer.byteLength, 13); + + let text = new TextDecoder().decode(buffer); + + assert.equal(text, "Hello, world!"); + + await storage.remove("hello"); + + assert.ok(!(await storage.has("hello"))); + assert.equal(await storage.get("hello"), null); + }); +}); diff --git a/src/lib/disk-file-storage.node.ts b/src/lib/disk-file-storage.node.ts new file mode 100644 index 00000000000..078e1252ef2 --- /dev/null +++ b/src/lib/disk-file-storage.node.ts @@ -0,0 +1,201 @@ +import * as fs from "node:fs"; +import * as fsp from "node:fs/promises"; +import * as path from "node:path"; + +import { type FileStorage } from "./file-storage.js"; +import { type LazyFileContent, LazyFile } from "./lazy-file.js"; + +type FileWithoutSize = Omit; + +/** + * A `FileStorage` that is backed by the local filesystem. + * + * Note: Keys have no correlation to file names on disk, so they may be any string including + * characters that are not valid in file names. Additionally, individual `File` names have no + * correlation to names of files on disk, so multiple files with the same name may be stored in the + * same storage. + */ +export class DiskFileStorage implements FileStorage { + #directory: string; + #metadata: FileMetadataIndex; + + /** + * @param directory The directory where files are stored + */ + constructor(directory: string) { + try { + fs.accessSync(directory); + } catch (error) { + fs.mkdirSync(directory, { recursive: true }); + } + + this.#directory = directory; + this.#metadata = new FileMetadataIndex( + path.join(directory, ".metadata.json") + ); + } + + has(key: string): Promise { + return this.#metadata.has(key); + } + + async put(key: string, file: FileWithoutSize): Promise { + let { name, size } = await createFile(this.#directory, file.stream()); + + await this.#metadata.set(key, { + file: name, + name: file.name, + size: size, + type: file.type + }); + } + + async get(key: string): Promise { + let metadata = await this.#metadata.get(key); + + if (metadata == null) { + return null; + } + + let file = path.join(this.#directory, metadata.file); + let content: LazyFileContent = { + byteLength: metadata.size, + read(start, end) { + return readFile(file, start, end); + } + }; + + return new LazyFile(content, metadata.name, { type: metadata.type }); + } + + async remove(key: string): Promise { + let metadata = await this.#metadata.get(key); + + if (metadata == null) { + return; + } + + try { + let file = path.join(this.#directory, metadata.file); + await fsp.unlink(file); + } catch (error) { + if ((error as NodeJS.ErrnoException).code !== "ENOENT") { + throw error; + } + } + + await this.#metadata.remove(key); + } +} + +function randomFilename(): string { + return `${new Date().getTime().toString(36)}.${Math.random().toString(36).slice(2, 6)}`; +} + +function createFile( + directory: string, + content: ReadableStream +): Promise<{ name: string; size: number }> { + let filename = randomFilename(); + let file = path.join(directory, filename); + + return new Promise((resolve, reject) => { + fs.open(file, "w", async (error, fd) => { + if (error) { + if (error.code === "EEXIST") { + // Try again with a different filename + return resolve(createFile(directory, content)); + } else { + return reject(error); + } + } + + let writeStream = fs.createWriteStream(file, { fd }); + let bytesWritten = 0; + + try { + for await (let chunk of content) { + writeStream.write(chunk); + bytesWritten += chunk.length; + } + + writeStream.end(); + + resolve({ name: filename, size: bytesWritten }); + } catch (error) { + reject(error); + } + }); + }); +} + +function readFile( + filename: string, + start?: number, + end = Infinity +): ReadableStream { + let read = fs.createReadStream(filename, { start, end: end - 1 }).iterator(); + + return new ReadableStream({ + async pull(controller) { + let { done, value } = await read.next(); + + if (done) { + controller.close(); + } else { + controller.enqueue(value); + } + } + }); +} + +interface FileMetadata { + file: string; + name: string; + size: number; + type: string; +} + +class FileMetadataIndex { + #path: string; + + constructor(path: string) { + this.#path = path; + } + + async #getAll(): Promise> { + try { + return JSON.parse(await fsp.readFile(this.#path, { encoding: "utf-8" })); + } catch (error) { + if ((error as NodeJS.ErrnoException).code === "ENOENT") { + return {}; + } + + throw error; + } + } + + async #save(info: Record): Promise { + await fsp.writeFile(this.#path, JSON.stringify(info)); + } + + async has(key: string): Promise { + let info = await this.#getAll(); + return key in info; + } + + async set(key: string, metadata: FileMetadata): Promise { + let info = await this.#getAll(); + await this.#save({ ...info, [key]: metadata }); + } + + async get(key: string): Promise { + let info = await this.#getAll(); + return info[key] ?? null; + } + + async remove(key: string): Promise { + let info = await this.#getAll(); + await this.#save({ ...info, [key]: undefined }); + } +} diff --git a/src/lib/file-storage.ts b/src/lib/file-storage.ts new file mode 100644 index 00000000000..4a1c18899b5 --- /dev/null +++ b/src/lib/file-storage.ts @@ -0,0 +1,21 @@ +/** + * The `FileStorage` interface provides methods for storing and retrieving `File` objects. + */ +export interface FileStorage { + /** + * Returns `true` if a file with the given key exists, `false` otherwise. + */ + has(key: string): boolean | Promise; + /** + * Stores a file with the given key. + */ + put(key: string, file: File): void | Promise; + /** + * Returns the file with the given key, or `null` if no such key exists. + */ + get(key: string): File | null | Promise; + /** + * Removes the file with the given key from storage. + */ + remove(key: string): void | Promise; +} diff --git a/src/lib/lazy-file.spec.ts b/src/lib/lazy-file.spec.ts new file mode 100644 index 00000000000..67b84a7d95c --- /dev/null +++ b/src/lib/lazy-file.spec.ts @@ -0,0 +1,141 @@ +import * as assert from "node:assert/strict"; +import { describe, it } from "node:test"; + +import { type LazyFileContent, LazyFile } from "./lazy-file.js"; + +function createContent(value = ""): LazyFileContent { + let buffer = new TextEncoder().encode(value); + return { + byteLength: buffer.byteLength, + read() { + return new ReadableStream({ + start(controller) { + controller.enqueue(buffer); + controller.close(); + } + }); + } + }; +} + +describe("LazyFile", () => { + it("has the correct name, size, type, and lastModified timestamp", () => { + let now = Date.now(); + let file = new LazyFile(createContent("X".repeat(100)), "example.txt", { + type: "text/plain", + lastModified: now + }); + + assert.equal(file.name, "example.txt"); + assert.equal(file.size, 100); + assert.equal(file.type, "text/plain"); + assert.equal(file.lastModified, now); + }); + + it("returns the file's contents as a stream", async () => { + let content = createContent("hello world"); + let file = new LazyFile(content, "hello.txt", { + type: "text/plain" + }); + + let decoder = new TextDecoder(); + let result = ""; + for await (let chunk of file.stream()) { + result += decoder.decode(chunk, { stream: true }); + } + result += decoder.decode(); + + assert.equal(result, "hello world"); + }); + + it("returns the file's contents as a string", async () => { + let content = createContent("hello world"); + let file = new LazyFile(content, "hello.txt", { + type: "text/plain" + }); + + assert.equal(await file.text(), "hello world"); + }); + + describe("slice()", () => { + it("returns a file with the same name, type, and lastModified timestamp when slicing a file", () => { + let file = new LazyFile(createContent(), "hello.txt", { + type: "text/plain", + lastModified: Date.now() + }); + let slice = file.slice(0, 5, file.type); + assert.equal(slice.name, file.name); + assert.equal(slice.type, file.type); + assert.equal(slice.lastModified, file.lastModified); + }); + + it("returns a file with the same size as the original when slicing from 0 to the end", () => { + let file = new LazyFile(createContent("hello world"), "hello.txt", { + type: "text/plain" + }); + let slice = file.slice(0); + assert.equal(slice.size, file.size); + }); + + it('returns a file with size 0 when the "start" index is greater than the content length', () => { + let file = new LazyFile(createContent("hello world"), "hello.txt", { + type: "text/plain" + }); + let slice = file.slice(100); + assert.equal(slice.size, 0); + }); + + it('returns a file with size 0 when the "start" index is greater than the "end" index', () => { + let file = new LazyFile(createContent("hello world"), "hello.txt", { + type: "text/plain" + }); + let slice = file.slice(5, 0); + assert.equal(slice.size, 0); + }); + + it("calls content.read() with the correct range", t => { + let content = createContent("X".repeat(100)); + let read = t.mock.method(content, "read"); + let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + file.slice(10, 20).stream(); + assert.equal(read.mock.calls.length, 1); + assert.deepEqual(read.mock.calls[0].arguments, [10, 20]); + }); + + it('calls content.read() with the correct range when slicing a file with a negative "start" index', t => { + let content = createContent("X".repeat(100)); + let read = t.mock.method(content, "read"); + let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + file.slice(-10).stream(); + assert.equal(read.mock.calls.length, 1); + assert.deepEqual(read.mock.calls[0].arguments, [90, 100]); + }); + + it('calls content.read() with the correct range when slicing a file with a negative "end" index', t => { + let content = createContent("X".repeat(100)); + let read = t.mock.method(content, "read"); + let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + file.slice(0, -10).stream(); + assert.equal(read.mock.calls.length, 1); + assert.deepEqual(read.mock.calls[0].arguments, [0, 90]); + }); + + it('calls content.read() with the correct range when slicing a file with negative "start" and "end" indexes', t => { + let content = createContent("X".repeat(100)); + let read = t.mock.method(content, "read"); + let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + file.slice(-20, -10).stream(); + assert.equal(read.mock.calls.length, 1); + assert.deepEqual(read.mock.calls[0].arguments, [80, 90]); + }); + + it('calls content.read() with the correct range when slicing a file with a "start" index greater than the "end" index', t => { + let content = createContent("X".repeat(100)); + let read = t.mock.method(content, "read"); + let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + file.slice(20, 10).stream(); + assert.equal(read.mock.calls.length, 1); + assert.deepEqual(read.mock.calls[0].arguments, [20, 20]); + }); + }); +}); diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts new file mode 100644 index 00000000000..dbfdb994e12 --- /dev/null +++ b/src/lib/lazy-file.ts @@ -0,0 +1,122 @@ +import { ByteRange } from "./byte-range.js"; + +export interface LazyFileContent { + /** + * The total length of the content. + */ + byteLength: number; + /** + * Returns a stream that can be used to read the content, optionally within a given `start` + * (inclusive) and `end` (exclusive) index. + */ + read(start?: number, end?: number): ReadableStream; +} + +/** + * A `File` that is backed by a stream of data. This is useful for working with large files that + * would be impractical to load into memory all at once. + */ +export class LazyFile extends File { + #content: LazyFileContent; + #props?: FilePropertyBag; + #range?: ByteRange; + + constructor( + content: LazyFileContent, + name: string, + props?: FilePropertyBag, + range?: ByteRange + ) { + super([], name, props); + this.#content = content; + this.#props = props; + this.#range = range; + } + + /** + * The size of the file in bytes. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/size) + */ + get size(): number { + return this.#range != null + ? this.#range.end - this.#range.start + : this.#content.byteLength; + } + + /** + * Returns the file's contents as an array buffer. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer) + */ + async arrayBuffer(): Promise { + return (await this.bytes()).buffer; + } + + /** + * Returns the file's contents as a byte array. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/bytes) + */ + async bytes(): Promise { + let result = new Uint8Array(this.size); + + let offset = 0; + for await (let chunk of this.stream()) { + result.set(chunk, offset); + offset += chunk.length; + } + + return result; + } + + /** + * Returns a new `File` object that contains the data in the specified range. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) + */ + slice(start = 0, end = this.size, contentType = ""): File { + let startIndex: number, endIndex: number; + if (this.#range != null) { + startIndex = this.#range.start; + endIndex = this.#range.end; + } else { + startIndex = 0; + endIndex = this.#content.byteLength; + } + + start = + start < 0 + ? Math.max(endIndex + start, startIndex) + : Math.min(start, endIndex); + end = Math.max( + end < 0 ? Math.max(endIndex + end, startIndex) : Math.min(end, endIndex), + start + ); + + let props = { ...this.#props, type: contentType }; + let range = { start, end }; + + return new LazyFile(this.#content, this.name, props, range); + } + + /** + * Returns a stream that can be used to read the file's contents. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/stream) + */ + stream(): ReadableStream { + return this.#range != null + ? this.#content.read(this.#range.start, this.#range.end) + : this.#content.read(); + } + + /** + * Returns the file's contents as a string. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/text) + */ + async text(): Promise { + return new TextDecoder("utf-8").decode(await this.bytes()); + } +} diff --git a/src/lib/memory-file-storage.ts b/src/lib/memory-file-storage.ts new file mode 100644 index 00000000000..143318c34b8 --- /dev/null +++ b/src/lib/memory-file-storage.ts @@ -0,0 +1,24 @@ +import { type FileStorage } from "./file-storage.js"; + +/** + * A simple, in-memory implementation of the `FileStorage` interface. + */ +export class MemoryFileStorage implements FileStorage { + #files = new Map(); + + has(key: string): boolean { + return this.#files.has(key); + } + + put(key: string, file: File): void { + this.#files.set(key, file); + } + + get(key: string): File | null { + return this.#files.get(key) ?? null; + } + + remove(key: string): void { + this.#files.delete(key); + } +} diff --git a/src/lib/range-stream.spec.ts b/src/lib/range-stream.spec.ts new file mode 100644 index 00000000000..d3b0ea65959 --- /dev/null +++ b/src/lib/range-stream.spec.ts @@ -0,0 +1,67 @@ +import * as assert from "node:assert/strict"; +import { describe, it } from "node:test"; + +import { RangeStream } from "./range-stream.js"; + +function createStream( + content: string, + chunkSize = 2 +): ReadableStream { + let buffer = new TextEncoder().encode(content); + return new ReadableStream({ + start(controller) { + let offset = 0; + while (offset < buffer.byteLength) { + controller.enqueue(buffer.slice(offset, offset + chunkSize)); + offset += chunkSize; + } + + controller.close(); + } + }); +} + +async function readStream(stream: ReadableStream): Promise { + let decoder = new TextDecoder(); + + let result = ""; + for await (let chunk of stream) { + result += decoder.decode(chunk, { stream: true }); + } + result += decoder.decode(); + + return result; +} + +describe("RangeStream", () => { + it("passes all bytes through if no range is specified", async () => { + let stream = createStream("hello world").pipeThrough(new RangeStream()); + let result = await readStream(stream); + assert.equal(result, "hello world"); + }); + + it("filters out bytes that are outside of the specified range", async () => { + let stream = createStream("hello world").pipeThrough(new RangeStream(1, 9)); + let result = await readStream(stream); + assert.equal(result, "ello wor"); + }); + + it("filters out bytes that are before the start index", async () => { + let stream = createStream("hello world").pipeThrough(new RangeStream(6)); + let result = await readStream(stream); + assert.equal(result, "world"); + }); + + it("filters out bytes that are after the end index", async () => { + let stream = createStream("hello world").pipeThrough(new RangeStream(0, 5)); + let result = await readStream(stream); + assert.equal(result, "hello"); + }); + + it('throws a "RangeError" if the end index is less than the start index', () => { + assert.throws(() => new RangeStream(5, 3), { + name: "RangeError", + message: "The end index must be greater than or equal to the start index" + }); + }); +}); diff --git a/src/lib/range-stream.ts b/src/lib/range-stream.ts new file mode 100644 index 00000000000..0ab61ae9602 --- /dev/null +++ b/src/lib/range-stream.ts @@ -0,0 +1,35 @@ +/** + * A `RangeStream` is a transform stream that filters out bytes that are outside of a specified + * range. + */ +export class RangeStream extends TransformStream { + #bytesRead = 0; + + /** + * @param start The start index of the range (inclusive) + * @param end The end index of the range (exclusive) + */ + constructor(start = 0, end = Infinity) { + if (end < start) { + throw new RangeError( + "The end index must be greater than or equal to the start index" + ); + } + + super({ + transform: (chunk, controller) => { + let chunkLength = chunk.length; + + if ( + !(this.#bytesRead + chunkLength < start || this.#bytesRead >= end) + ) { + let startIndex = Math.max(start - this.#bytesRead, 0); + let endIndex = Math.min(end - this.#bytesRead, chunkLength); + controller.enqueue(chunk.subarray(startIndex, endIndex)); + } + + this.#bytesRead += chunkLength; + } + }); + } +} diff --git a/test.ts b/test.ts new file mode 100644 index 00000000000..e8d5f36c90b --- /dev/null +++ b/test.ts @@ -0,0 +1,31 @@ +import * as fs from "node:fs"; + +function readFile( + file: string, + start?: number, + end = Infinity +): ReadableStream { + let read = fs.createReadStream(file, { start, end: end - 1 }).iterator(); + + return new ReadableStream({ + async pull(controller) { + let { done, value } = await read.next(); + + if (done) { + controller.close(); + } else { + controller.enqueue(value); + } + } + }); +} + +let stream = readFile("test.ts", 0, 10); + +try { + for await (let chunk of stream) { + console.log(new TextDecoder().decode(chunk)); + } +} catch (error) { + console.error(error); +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000000..d8aaef54f9d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "lib": ["DOM", "ES2020"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true + } +} diff --git a/tsconfig.lib.json b/tsconfig.lib.json new file mode 100644 index 00000000000..c9819aa7ed5 --- /dev/null +++ b/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.spec.ts", "src/test/**/*.ts"], + "compilerOptions": { + "composite": true, + "rootDir": "src" + } +} diff --git a/tsconfig.spec.json b/tsconfig.spec.json new file mode 100644 index 00000000000..0dcc65f3ce6 --- /dev/null +++ b/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.spec.ts", "src/test/**/*.ts"], + "compilerOptions": { + "composite": true, + "types": ["node"] + } +} From c484d722955b71c8397c651b02a4c4c2046b34c9 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 10:08:15 -0700 Subject: [PATCH 270/730] Remove old file --- test.ts | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 test.ts diff --git a/test.ts b/test.ts deleted file mode 100644 index e8d5f36c90b..00000000000 --- a/test.ts +++ /dev/null @@ -1,31 +0,0 @@ -import * as fs from "node:fs"; - -function readFile( - file: string, - start?: number, - end = Infinity -): ReadableStream { - let read = fs.createReadStream(file, { start, end: end - 1 }).iterator(); - - return new ReadableStream({ - async pull(controller) { - let { done, value } = await read.next(); - - if (done) { - controller.close(); - } else { - controller.enqueue(value); - } - } - }); -} - -let stream = readFile("test.ts", 0, 10); - -try { - for await (let chunk of stream) { - console.log(new TextDecoder().decode(chunk)); - } -} catch (error) { - console.error(error); -} From 719b52bfa071e3c0de41102131080e5b604142b7 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 10:09:07 -0700 Subject: [PATCH 271/730] Remove unused RangeStream implementation --- src/lib/range-stream.spec.ts | 67 ------------------------------------ src/lib/range-stream.ts | 35 ------------------- 2 files changed, 102 deletions(-) delete mode 100644 src/lib/range-stream.spec.ts delete mode 100644 src/lib/range-stream.ts diff --git a/src/lib/range-stream.spec.ts b/src/lib/range-stream.spec.ts deleted file mode 100644 index d3b0ea65959..00000000000 --- a/src/lib/range-stream.spec.ts +++ /dev/null @@ -1,67 +0,0 @@ -import * as assert from "node:assert/strict"; -import { describe, it } from "node:test"; - -import { RangeStream } from "./range-stream.js"; - -function createStream( - content: string, - chunkSize = 2 -): ReadableStream { - let buffer = new TextEncoder().encode(content); - return new ReadableStream({ - start(controller) { - let offset = 0; - while (offset < buffer.byteLength) { - controller.enqueue(buffer.slice(offset, offset + chunkSize)); - offset += chunkSize; - } - - controller.close(); - } - }); -} - -async function readStream(stream: ReadableStream): Promise { - let decoder = new TextDecoder(); - - let result = ""; - for await (let chunk of stream) { - result += decoder.decode(chunk, { stream: true }); - } - result += decoder.decode(); - - return result; -} - -describe("RangeStream", () => { - it("passes all bytes through if no range is specified", async () => { - let stream = createStream("hello world").pipeThrough(new RangeStream()); - let result = await readStream(stream); - assert.equal(result, "hello world"); - }); - - it("filters out bytes that are outside of the specified range", async () => { - let stream = createStream("hello world").pipeThrough(new RangeStream(1, 9)); - let result = await readStream(stream); - assert.equal(result, "ello wor"); - }); - - it("filters out bytes that are before the start index", async () => { - let stream = createStream("hello world").pipeThrough(new RangeStream(6)); - let result = await readStream(stream); - assert.equal(result, "world"); - }); - - it("filters out bytes that are after the end index", async () => { - let stream = createStream("hello world").pipeThrough(new RangeStream(0, 5)); - let result = await readStream(stream); - assert.equal(result, "hello"); - }); - - it('throws a "RangeError" if the end index is less than the start index', () => { - assert.throws(() => new RangeStream(5, 3), { - name: "RangeError", - message: "The end index must be greater than or equal to the start index" - }); - }); -}); diff --git a/src/lib/range-stream.ts b/src/lib/range-stream.ts deleted file mode 100644 index 0ab61ae9602..00000000000 --- a/src/lib/range-stream.ts +++ /dev/null @@ -1,35 +0,0 @@ -/** - * A `RangeStream` is a transform stream that filters out bytes that are outside of a specified - * range. - */ -export class RangeStream extends TransformStream { - #bytesRead = 0; - - /** - * @param start The start index of the range (inclusive) - * @param end The end index of the range (exclusive) - */ - constructor(start = 0, end = Infinity) { - if (end < start) { - throw new RangeError( - "The end index must be greater than or equal to the start index" - ); - } - - super({ - transform: (chunk, controller) => { - let chunkLength = chunk.length; - - if ( - !(this.#bytesRead + chunkLength < start || this.#bytesRead >= end) - ) { - let startIndex = Math.max(start - this.#bytesRead, 0); - let endIndex = Math.min(end - this.#bytesRead, chunkLength); - controller.enqueue(chunk.subarray(startIndex, endIndex)); - } - - this.#bytesRead += chunkLength; - } - }); - } -} From c63278f81f0ad581d02ff852df958961efc8ed0f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 10:09:39 -0700 Subject: [PATCH 272/730] Add tests for MemoryFileStorage --- .gitignore | 2 +- src/lib/byte-range.ts | 41 +++++++++++-------- src/lib/lazy-file.ts | 38 ++++++++--------- ...ode.spec.ts => local-file-storage.spec.ts} | 21 +++++----- ...-storage.node.ts => local-file-storage.ts} | 10 ++--- src/lib/memory-file-storage.spec.ts | 31 ++++++++++++++ src/lib/memory-file-storage.ts | 12 +++--- 7 files changed, 94 insertions(+), 61 deletions(-) rename src/lib/{disk-file-storage.node.spec.ts => local-file-storage.spec.ts} (64%) rename src/lib/{disk-file-storage.node.ts => local-file-storage.ts} (94%) create mode 100644 src/lib/memory-file-storage.spec.ts diff --git a/.gitignore b/.gitignore index 52d6954a864..d8b18099d6f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,6 @@ .wrangler dist node_modules -test-disk-storage +test-local-file-storage *.tsbuildinfo \ No newline at end of file diff --git a/src/lib/byte-range.ts b/src/lib/byte-range.ts index ace08357e66..af36fa06c3d 100644 --- a/src/lib/byte-range.ts +++ b/src/lib/byte-range.ts @@ -1,29 +1,36 @@ export interface ByteRange { /** - * The start index of the range (inclusive). + * The start index of the range (inclusive). If this number is negative, it represents an offset + * from the end of the buffer. */ start: number; /** - * The end index of the range (exclusive). + * The end index of the range (exclusive). If this number is negative, it represents an offset + * from the end of the buffer. `Infinity` represents the end of the buffer. */ end: number; } -export function validateByteRange(range: ByteRange): void { - if ( - (range.start < 0 && - (range.end < range.start || range.end >= 0) && - range.end !== Infinity) || - (range.end >= 0 && range.end < range.start) || - range.start === Infinity - ) { - throw new Error(`Invalid byte range: ${range.start}-${range.end}`); - } +/** + * Returns the length of the byte range in a buffer of the given `size`. + */ +export function getByteLength(range: ByteRange, size: number): number { + let [start, end] = getIndexes(range, size); + return end - start; } -export function addByteRanges(a: ByteRange, b: ByteRange): ByteRange { - return { - start: a.start + b.start, - end: a.end === Infinity ? b.end : a.end + b.end - }; +/** + * Resolves a byte range to absolute indexes in a buffer of the given `size`. + */ +export function getIndexes(range: ByteRange, size: number): [number, number] { + let start = Math.min( + Math.max(0, range.start < 0 ? size + range.start : range.start), + size + ); + let end = Math.min( + Math.max(start, range.end < 0 ? size + range.end : range.end), + size + ); + + return [start, end]; } diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts index dbfdb994e12..af6af9b21b0 100644 --- a/src/lib/lazy-file.ts +++ b/src/lib/lazy-file.ts @@ -1,4 +1,4 @@ -import { ByteRange } from "./byte-range.js"; +import { ByteRange, getByteLength, getIndexes } from "./byte-range.js"; export interface LazyFileContent { /** @@ -40,7 +40,7 @@ export class LazyFile extends File { */ get size(): number { return this.#range != null - ? this.#range.end - this.#range.start + ? getByteLength(this.#range, this.#content.byteLength) : this.#content.byteLength; } @@ -75,27 +75,18 @@ export class LazyFile extends File { * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) */ - slice(start = 0, end = this.size, contentType = ""): File { - let startIndex: number, endIndex: number; + slice(start = 0, end = Infinity, contentType = ""): File { + let range = { start, end }; + if (this.#range != null) { - startIndex = this.#range.start; - endIndex = this.#range.end; - } else { - startIndex = 0; - endIndex = this.#content.byteLength; + // file.slice().slice() is additive + range = { + start: this.#range.start + start, + end: this.#range.end === Infinity ? end : this.#range.end + end + }; } - start = - start < 0 - ? Math.max(endIndex + start, startIndex) - : Math.min(start, endIndex); - end = Math.max( - end < 0 ? Math.max(endIndex + end, startIndex) : Math.min(end, endIndex), - start - ); - let props = { ...this.#props, type: contentType }; - let range = { start, end }; return new LazyFile(this.#content, this.name, props, range); } @@ -106,9 +97,12 @@ export class LazyFile extends File { * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/stream) */ stream(): ReadableStream { - return this.#range != null - ? this.#content.read(this.#range.start, this.#range.end) - : this.#content.read(); + if (this.#range != null) { + let [start, end] = getIndexes(this.#range, this.#content.byteLength); + return this.#content.read(start, end); + } + + return this.#content.read(); } /** diff --git a/src/lib/disk-file-storage.node.spec.ts b/src/lib/local-file-storage.spec.ts similarity index 64% rename from src/lib/disk-file-storage.node.spec.ts rename to src/lib/local-file-storage.spec.ts index 80ad2f37628..eb001b92103 100644 --- a/src/lib/disk-file-storage.node.spec.ts +++ b/src/lib/local-file-storage.spec.ts @@ -1,16 +1,21 @@ import * as assert from "node:assert/strict"; -import { describe, it } from "node:test"; +import { after, describe, it } from "node:test"; +import * as fs from "node:fs"; import * as path from "node:path"; -import { DiskFileStorage } from "./disk-file-storage.node.js"; +import { LocalFileStorage } from "./local-file-storage.js"; const __dirname = new URL(".", import.meta.url).pathname; -describe("DiskFileStorage (node)", () => { - let directory = path.resolve(__dirname, "../../test-disk-storage"); +describe("LocalFileStorage", () => { + let directory = path.resolve(__dirname, "../../test-local-file-storage"); + + after(() => { + fs.rmSync(directory, { recursive: true }); + }); it("stores and retrieves files", async () => { - let storage = new DiskFileStorage(directory); + let storage = new LocalFileStorage(directory); let file = new File(["Hello, world!"], "hello.txt", { type: "text/plain" }); await storage.put("hello", file); @@ -24,11 +29,7 @@ describe("DiskFileStorage (node)", () => { assert.equal(retrieved.type, "text/plain"); assert.equal(retrieved.size, 13); - let buffer = await retrieved.arrayBuffer(); - - assert.equal(buffer.byteLength, 13); - - let text = new TextDecoder().decode(buffer); + let text = await retrieved.text(); assert.equal(text, "Hello, world!"); diff --git a/src/lib/disk-file-storage.node.ts b/src/lib/local-file-storage.ts similarity index 94% rename from src/lib/disk-file-storage.node.ts rename to src/lib/local-file-storage.ts index 078e1252ef2..3e28dde2977 100644 --- a/src/lib/disk-file-storage.node.ts +++ b/src/lib/local-file-storage.ts @@ -2,8 +2,8 @@ import * as fs from "node:fs"; import * as fsp from "node:fs/promises"; import * as path from "node:path"; -import { type FileStorage } from "./file-storage.js"; -import { type LazyFileContent, LazyFile } from "./lazy-file.js"; +import { FileStorage } from "./file-storage.js"; +import { LazyFileContent, LazyFile } from "./lazy-file.js"; type FileWithoutSize = Omit; @@ -13,9 +13,9 @@ type FileWithoutSize = Omit; * Note: Keys have no correlation to file names on disk, so they may be any string including * characters that are not valid in file names. Additionally, individual `File` names have no * correlation to names of files on disk, so multiple files with the same name may be stored in the - * same storage. + * same storage object. */ -export class DiskFileStorage implements FileStorage { +export class LocalFileStorage implements FileStorage { #directory: string; #metadata: FileMetadataIndex; @@ -75,8 +75,8 @@ export class DiskFileStorage implements FileStorage { return; } + let file = path.join(this.#directory, metadata.file); try { - let file = path.join(this.#directory, metadata.file); await fsp.unlink(file); } catch (error) { if ((error as NodeJS.ErrnoException).code !== "ENOENT") { diff --git a/src/lib/memory-file-storage.spec.ts b/src/lib/memory-file-storage.spec.ts new file mode 100644 index 00000000000..8fd2bb35b16 --- /dev/null +++ b/src/lib/memory-file-storage.spec.ts @@ -0,0 +1,31 @@ +import * as assert from "node:assert/strict"; +import { describe, it } from "node:test"; + +import { MemoryFileStorage } from "./memory-file-storage.js"; + +describe("MemoryFileStorage", () => { + it("stores and retrieves files", async () => { + let storage = new MemoryFileStorage(); + let file = new File(["Hello, world!"], "hello.txt", { type: "text/plain" }); + + storage.put("hello", file); + + assert.ok(storage.has("hello")); + + let retrieved = storage.get("hello"); + + assert.ok(retrieved); + assert.equal(retrieved.name, "hello.txt"); + assert.equal(retrieved.type, "text/plain"); + assert.equal(retrieved.size, 13); + + let text = await retrieved.text(); + + assert.equal(text, "Hello, world!"); + + storage.remove("hello"); + + assert.ok(!storage.has("hello")); + assert.equal(storage.get("hello"), null); + }); +}); diff --git a/src/lib/memory-file-storage.ts b/src/lib/memory-file-storage.ts index 143318c34b8..e3d6459ae98 100644 --- a/src/lib/memory-file-storage.ts +++ b/src/lib/memory-file-storage.ts @@ -1,24 +1,24 @@ -import { type FileStorage } from "./file-storage.js"; +import { FileStorage } from "./file-storage.js"; /** * A simple, in-memory implementation of the `FileStorage` interface. */ export class MemoryFileStorage implements FileStorage { - #files = new Map(); + #map = new Map(); has(key: string): boolean { - return this.#files.has(key); + return this.#map.has(key); } put(key: string, file: File): void { - this.#files.set(key, file); + this.#map.set(key, file); } get(key: string): File | null { - return this.#files.get(key) ?? null; + return this.#map.get(key) ?? null; } remove(key: string): void { - this.#files.delete(key); + this.#map.delete(key); } } From cbc1587bd19631d44171de778d5d097f81fbd315 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 10:54:33 -0700 Subject: [PATCH 273/730] Add FileUpload API --- CHANGELOG.md | 5 ++++ README.md | 52 ++++++++++++++++++++++++++++++++ package.json | 2 +- src/lib/form-data.ts | 70 ++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 README.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000000..eb132f2be2d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# form-data-parser CHANGELOG + +## HEAD + +- Initial release diff --git a/README.md b/README.md new file mode 100644 index 00000000000..167aa658547 --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# form-data-parser + +`form-data-parser` is a wrapper around `request.formData()` that provides pluggable support for file upload handling. This is useful in server contexts where large files should be streamed to disk or some cloud storage service like [AWS S3](https://aws.amazon.com/s3/) or [Cloudflare R2](https://www.cloudflare.com/developer-platform/r2/) instead of being buffered in memory. + +## The Problem + +The web fetch API's built-in [`request.formData()` API](https://developer.mozilla.org/en-US/docs/Web/API/Request/formData) is not a great fit for server environments because it doesn't provide a way to stream file uploads. This means that when you call `request.formData()` in a server environment on a request that was submitted by a ``, any file uploads contained in the request are buffered in memory. For small files this may not be an issue, but it's a total non-starter for large files that exceed the server's memory capacity. + +`form-data-parser` fixes this issue by providing an API to handle streaming file data. + +## Installation + +Install from [npm](https://www.npmjs.com/): + +```sh +npm install @mjackson/form-data-parser +``` + +## Usage + +```ts +import { LocalFileStorage } from "@mjackson/file-storage"; +import { parseFormData } from "@mjackson/form-data-parser"; + +const fileStorage = new LocalFileStorage("/uploads/user-avatars"); + +async function handleRequest(request: Request) { + let formData = await parseFormData(request, async fileUpload => { + // Is this file upload from the in our ? + if (fileUpload.fieldName === "user-avatar") { + let storageKey = `user-${user.id}-avatar`; + + // Save the file to storage + await fileStorage.put(storageKey, fileUpload); + + // Return an instance of the file from storage for the FormData object + return fileStorage.get(storageKey); + } + + // Ignore any files we don't recognize the name of... + }); + + let file = formData.get("user-avatar"); // File + file.name; // "my-avatar.jpg" (name of the file on the user's computer) + file.size; // number + file.type; // "image/jpeg" +} +``` + +## License + +See [LICENSE](https://github.com/mjackson/form-data-parser/blob/main/LICENSE) diff --git a/package.json b/package.json index 4bfbbeb3f71..f0425d081ee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/form-data-parser", - "version": "1.0.0", + "version": "0.1.0", "description": "A request.formData() wrapper with pluggable file upload handling", "author": "Michael Jackson ", "repository": { diff --git a/src/lib/form-data.ts b/src/lib/form-data.ts index ec54b2bedf5..8956c891240 100644 --- a/src/lib/form-data.ts +++ b/src/lib/form-data.ts @@ -4,16 +4,71 @@ import { type MultipartPart } from "@mjackson/multipart-parser"; +/** + * A `File` that was uploaded as part of a `multipart/form-data` request. + * + * This object is intended to be used as an intermediary for handling file uploads. The file should + * be saved to disk or a cloud storage service as quickly as possible to avoid buffering and + * backpressure building up in the input stream. + * + * Note: Although this is a `File` object its `size` is unknown, so any attempt to access + * `file.size` or use `file.slice()` will throw an error. + */ +export class FileUpload extends File { + #part: MultipartPart; + + constructor(part: MultipartPart) { + super([], part.filename ?? "", { type: part.mediaType }); + this.#part = part; + } + + arrayBuffer(): Promise { + return this.#part.arrayBuffer(); + } + + bytes(): Promise { + return this.#part.bytes(); + } + + /** + * The name of the field used to upload the file. + */ + get fieldName(): string | undefined { + return this.#part.name; + } + + get size(): number { + throw new Error( + "Cannot get the size of a file upload without buffering the entire file" + ); + } + + slice(): Blob { + throw new Error( + "Cannot slice a file upload without buffering the entire file" + ); + } + + stream(): ReadableStream { + return this.#part.body; + } + + text(): Promise { + return this.#part.text(); + } +} + /** * A function used for handling file uploads. */ export interface FileUploadHandler { - (part: MultipartPart): Promise; + (file: FileUpload): File | void | Promise; } -async function defaultFileUploadHandler(part: MultipartPart): Promise { - let buffer = await part.arrayBuffer(); - return new File([buffer], part.filename ?? "", { type: part.mediaType }); +async function defaultFileUploadHandler(file: FileUpload): Promise { + // Do the slow thing and buffer the entire file in memory. + let buffer = await file.arrayBuffer(); + return new File([buffer], file.name, { type: file.type }); } /** @@ -26,7 +81,7 @@ async function defaultFileUploadHandler(part: MultipartPart): Promise { */ export async function parseFormData( request: Request, - handleFileUpload: FileUploadHandler = defaultFileUploadHandler + uploadHandler: FileUploadHandler = defaultFileUploadHandler ): Promise { if (isMultipartRequest(request)) { let formData = new FormData(); @@ -35,7 +90,10 @@ export async function parseFormData( if (!part.name) continue; if (part.isFile) { - formData.append(part.name, await handleFileUpload(part)); + let file = await uploadHandler(new FileUpload(part)); + if (file) { + formData.append(part.name, file); + } } else { formData.append(part.name, await part.text()); } From 113b305e83d154258d9923e4b7b6676ec68d4702 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 11:04:43 -0700 Subject: [PATCH 274/730] Update README --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 167aa658547..e14fcd3c58f 100644 --- a/README.md +++ b/README.md @@ -30,17 +30,21 @@ async function handleRequest(request: Request) { if (fileUpload.fieldName === "user-avatar") { let storageKey = `user-${user.id}-avatar`; - // Save the file to storage + // FileUpload objects are not meant to stick around for very long (they are + // streaming data from the request.body!) so we should store them as soon as + // possible. await fileStorage.put(storageKey, fileUpload); - // Return an instance of the file from storage for the FormData object + // Return a File for the FormData object. This is a LazyFile that knows how + // to access the file's content if needed (using e.g. file.stream()) but + // waits until it is requested to actually read anything. return fileStorage.get(storageKey); } // Ignore any files we don't recognize the name of... }); - let file = formData.get("user-avatar"); // File + let file = formData.get("user-avatar"); // File (LazyFile) file.name; // "my-avatar.jpg" (name of the file on the user's computer) file.size; // number file.type; // "image/jpeg" From b057c99e207007c1e7b5193002fe06f1bfde31eb Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 11:12:15 -0700 Subject: [PATCH 275/730] Update doc --- src/lib/file-storage.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/file-storage.ts b/src/lib/file-storage.ts index 4a1c18899b5..e86688ef1e4 100644 --- a/src/lib/file-storage.ts +++ b/src/lib/file-storage.ts @@ -1,5 +1,5 @@ /** - * The `FileStorage` interface provides methods for storing and retrieving `File` objects. + * A key/value interface for storing `File` objects. */ export interface FileStorage { /** @@ -7,7 +7,7 @@ export interface FileStorage { */ has(key: string): boolean | Promise; /** - * Stores a file with the given key. + * Puts a file in storage at the given key. */ put(key: string, file: File): void | Promise; /** From 305aa0dca1f2eaec2d61080801674286addb8444 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 11:16:29 -0700 Subject: [PATCH 276/730] Add ByteRange spec --- src/lib/byte-range.spec.ts | 40 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/lib/byte-range.spec.ts diff --git a/src/lib/byte-range.spec.ts b/src/lib/byte-range.spec.ts new file mode 100644 index 00000000000..c313eb5eb29 --- /dev/null +++ b/src/lib/byte-range.spec.ts @@ -0,0 +1,40 @@ +import * as assert from "node:assert/strict"; +import { describe, it } from "node:test"; + +import { ByteRange, getByteLength, getIndexes } from "./byte-range.js"; + +describe("getByteLength", () => { + it("returns the correct length", () => { + let size = 100; + + let range: ByteRange = { start: 10, end: 20 }; + assert.strictEqual(getByteLength(range, size), 10); + + range = { start: 10, end: -10 }; + assert.strictEqual(getByteLength(range, size), 80); + + range = { start: -10, end: -10 }; + assert.strictEqual(getByteLength(range, size), 0); + + range = { start: -10, end: 20 }; + assert.strictEqual(getByteLength(range, size), 0); + }); +}); + +describe("getIndexes", () => { + it("returns the correct indexes", () => { + let size = 100; + + let range: ByteRange = { start: 10, end: 20 }; + assert.deepStrictEqual(getIndexes(range, size), [10, 20]); + + range = { start: 10, end: -10 }; + assert.deepStrictEqual(getIndexes(range, size), [10, 90]); + + range = { start: -10, end: -10 }; + assert.deepStrictEqual(getIndexes(range, size), [90, 90]); + + range = { start: -10, end: 20 }; + assert.deepStrictEqual(getIndexes(range, size), [90, 90]); + }); +}); From c8545906d29a6a8496ae7eb372b15cfbdccdfbce Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 11:21:51 -0700 Subject: [PATCH 277/730] Export everything --- src/file-storage.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/file-storage.ts b/src/file-storage.ts index d558de6cddc..9194215cf33 100644 --- a/src/file-storage.ts +++ b/src/file-storage.ts @@ -1 +1,5 @@ +export { type ByteRange, getByteLength, getIndexes } from "./lib/byte-range.js"; export { type FileStorage } from "./lib/file-storage.js"; +export { LazyFile } from "./lib/lazy-file.js"; +export { LocalFileStorage } from "./lib/local-file-storage.js"; +export { MemoryFileStorage } from "./lib/memory-file-storage.js"; From f5c6d6c670f605442e75cc7f35b7c0e4e2afb596 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 11:35:05 -0700 Subject: [PATCH 278/730] Update arg name --- src/lib/local-file-storage.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/local-file-storage.ts b/src/lib/local-file-storage.ts index 3e28dde2977..3025d90a370 100644 --- a/src/lib/local-file-storage.ts +++ b/src/lib/local-file-storage.ts @@ -94,7 +94,7 @@ function randomFilename(): string { function createFile( directory: string, - content: ReadableStream + stream: ReadableStream ): Promise<{ name: string; size: number }> { let filename = randomFilename(); let file = path.join(directory, filename); @@ -104,7 +104,7 @@ function createFile( if (error) { if (error.code === "EEXIST") { // Try again with a different filename - return resolve(createFile(directory, content)); + return resolve(createFile(directory, stream)); } else { return reject(error); } @@ -114,7 +114,7 @@ function createFile( let bytesWritten = 0; try { - for await (let chunk of content) { + for await (let chunk of stream) { writeStream.write(chunk); bytesWritten += chunk.length; } From 95c29aab038bd4007a0e48040f36876ce9e3325b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 11:59:53 -0700 Subject: [PATCH 279/730] Make sure file is a directory --- src/lib/local-file-storage.ts | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/lib/local-file-storage.ts b/src/lib/local-file-storage.ts index 3025d90a370..3cf232b6dad 100644 --- a/src/lib/local-file-storage.ts +++ b/src/lib/local-file-storage.ts @@ -24,8 +24,16 @@ export class LocalFileStorage implements FileStorage { */ constructor(directory: string) { try { - fs.accessSync(directory); + let stat = fs.statSync(directory); + + if (!stat.isDirectory()) { + throw new Error(`Path "${directory}" is not a directory`); + } } catch (error) { + if (!isNoEntityError(error)) { + throw error; + } + fs.mkdirSync(directory, { recursive: true }); } @@ -79,7 +87,7 @@ export class LocalFileStorage implements FileStorage { try { await fsp.unlink(file); } catch (error) { - if ((error as NodeJS.ErrnoException).code !== "ENOENT") { + if (!isNoEntityError(error)) { throw error; } } @@ -167,11 +175,11 @@ class FileMetadataIndex { try { return JSON.parse(await fsp.readFile(this.#path, { encoding: "utf-8" })); } catch (error) { - if ((error as NodeJS.ErrnoException).code === "ENOENT") { - return {}; + if (!isNoEntityError(error)) { + throw error; } - throw error; + return {}; } } @@ -199,3 +207,14 @@ class FileMetadataIndex { await this.#save({ ...info, [key]: undefined }); } } + +function isNoEntityError( + obj: unknown +): obj is NodeJS.ErrnoException & { code: "ENOENT" } { + return ( + typeof obj === "object" && + obj !== null && + "code" in obj && + (obj as NodeJS.ErrnoException).code === "ENOENT" + ); +} From a32666caf6cffa1897c4bebf833a76f59ebf9c72 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 15:08:32 -0700 Subject: [PATCH 280/730] Rename storage.put => storage.set --- src/lib/file-storage.ts | 2 +- src/lib/lazy-file.spec.ts | 2 +- src/lib/local-file-storage.spec.ts | 2 +- src/lib/local-file-storage.ts | 2 +- src/lib/memory-file-storage.spec.ts | 2 +- src/lib/memory-file-storage.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib/file-storage.ts b/src/lib/file-storage.ts index e86688ef1e4..c895f37b0aa 100644 --- a/src/lib/file-storage.ts +++ b/src/lib/file-storage.ts @@ -9,7 +9,7 @@ export interface FileStorage { /** * Puts a file in storage at the given key. */ - put(key: string, file: File): void | Promise; + set(key: string, file: File): void | Promise; /** * Returns the file with the given key, or `null` if no such key exists. */ diff --git a/src/lib/lazy-file.spec.ts b/src/lib/lazy-file.spec.ts index 67b84a7d95c..4543af0ebb1 100644 --- a/src/lib/lazy-file.spec.ts +++ b/src/lib/lazy-file.spec.ts @@ -1,7 +1,7 @@ import * as assert from "node:assert/strict"; import { describe, it } from "node:test"; -import { type LazyFileContent, LazyFile } from "./lazy-file.js"; +import { LazyFileContent, LazyFile } from "./lazy-file.js"; function createContent(value = ""): LazyFileContent { let buffer = new TextEncoder().encode(value); diff --git a/src/lib/local-file-storage.spec.ts b/src/lib/local-file-storage.spec.ts index eb001b92103..af1a3b9a3eb 100644 --- a/src/lib/local-file-storage.spec.ts +++ b/src/lib/local-file-storage.spec.ts @@ -18,7 +18,7 @@ describe("LocalFileStorage", () => { let storage = new LocalFileStorage(directory); let file = new File(["Hello, world!"], "hello.txt", { type: "text/plain" }); - await storage.put("hello", file); + await storage.set("hello", file); assert.ok(await storage.has("hello")); diff --git a/src/lib/local-file-storage.ts b/src/lib/local-file-storage.ts index 3cf232b6dad..2cff5617775 100644 --- a/src/lib/local-file-storage.ts +++ b/src/lib/local-file-storage.ts @@ -47,7 +47,7 @@ export class LocalFileStorage implements FileStorage { return this.#metadata.has(key); } - async put(key: string, file: FileWithoutSize): Promise { + async set(key: string, file: FileWithoutSize): Promise { let { name, size } = await createFile(this.#directory, file.stream()); await this.#metadata.set(key, { diff --git a/src/lib/memory-file-storage.spec.ts b/src/lib/memory-file-storage.spec.ts index 8fd2bb35b16..6e1073277e2 100644 --- a/src/lib/memory-file-storage.spec.ts +++ b/src/lib/memory-file-storage.spec.ts @@ -8,7 +8,7 @@ describe("MemoryFileStorage", () => { let storage = new MemoryFileStorage(); let file = new File(["Hello, world!"], "hello.txt", { type: "text/plain" }); - storage.put("hello", file); + storage.set("hello", file); assert.ok(storage.has("hello")); diff --git a/src/lib/memory-file-storage.ts b/src/lib/memory-file-storage.ts index e3d6459ae98..8a30578f827 100644 --- a/src/lib/memory-file-storage.ts +++ b/src/lib/memory-file-storage.ts @@ -10,7 +10,7 @@ export class MemoryFileStorage implements FileStorage { return this.#map.has(key); } - put(key: string, file: File): void { + set(key: string, file: File): void { this.#map.set(key, file); } From 1a68501260f3cb06be827c3b88e4100ca395297c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 15:31:24 -0700 Subject: [PATCH 281/730] Initial commit --- .gitignore | 5 + LICENSE | 21 ++ package.json | 39 ++++ pnpm-lock.yaml | 387 +++++++++++++++++++++++++++++++++++++ src/global.d.ts | 6 + src/lazy-file.ts | 2 + src/lib/byte-range.spec.ts | 40 ++++ src/lib/byte-range.ts | 36 ++++ src/lib/lazy-file.spec.ts | 141 ++++++++++++++ src/lib/lazy-file.ts | 116 +++++++++++ tsconfig.json | 8 + tsconfig.lib.json | 9 + tsconfig.spec.json | 8 + 13 files changed, 818 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 src/global.d.ts create mode 100644 src/lazy-file.ts create mode 100644 src/lib/byte-range.spec.ts create mode 100644 src/lib/byte-range.ts create mode 100644 src/lib/lazy-file.spec.ts create mode 100644 src/lib/lazy-file.ts create mode 100644 tsconfig.json create mode 100644 tsconfig.lib.json create mode 100644 tsconfig.spec.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..c9282d7e5e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.tsimp +dist +node_modules + +*.tsbuildinfo \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..717984c0442 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Michael Jackson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package.json b/package.json new file mode 100644 index 00000000000..08c36e6fcc3 --- /dev/null +++ b/package.json @@ -0,0 +1,39 @@ +{ + "name": "lazy-file", + "version": "1.0.0", + "description": "Lazy, streaming files for JavaScript", + "author": "Michael Jackson ", + "repository": { + "type": "git", + "url": "git+https://github.com/mjackson/lazy-file.git" + }, + "license": "MIT", + "files": [ + "dist", + "LICENSE", + "README.md" + ], + "type": "module", + "exports": { + ".": "./dist/lazy-file.js", + "./package.json": "./package.json" + }, + "devDependencies": { + "@types/node": "^22.5.0", + "prettier": "^3.3.3", + "tsimp": "^2.0.11", + "typescript": "^5.5.4" + }, + "scripts": { + "clean": "git clean -fdX .", + "build": "tsc --outDir dist --project tsconfig.lib.json", + "test": "node --import tsimp/import --test ./src/**/*.spec.ts", + "prepare": "pnpm run build" + }, + "packageManager": "pnpm@9.7.1", + "keywords": [ + "file", + "buffer", + "blob" + ] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000000..c0178d428b8 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,387 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@types/node': + specifier: ^22.5.0 + version: 22.5.0 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + tsimp: + specifier: ^2.0.11 + version: 2.0.11(typescript@5.5.4) + typescript: + specifier: ^5.5.4 + version: 5.5.4 + +packages: + + '@isaacs/cached@1.0.1': + resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} + + '@isaacs/catcher@1.0.4': + resolution: {integrity: sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@types/node@22.5.0': + resolution: {integrity: sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sock-daemon@1.4.2: + resolution: {integrity: sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg==} + engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} + + socket-post-message@1.0.3: + resolution: {integrity: sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + tsimp@2.0.11: + resolution: {integrity: sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==} + engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.1.0 + + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + walk-up-path@3.0.1: + resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + +snapshots: + + '@isaacs/cached@1.0.1': + dependencies: + '@isaacs/catcher': 1.0.4 + + '@isaacs/catcher@1.0.4': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@types/node@22.5.0': + dependencies: + undici-types: 6.19.8 + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + balanced-match@1.0.2: {} + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 1.11.1 + + is-fullwidth-code-point@3.0.0: {} + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + lru-cache@10.4.3: {} + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + + mkdirp@3.0.1: {} + + package-json-from-dist@1.0.0: {} + + path-key@3.1.1: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + pirates@4.0.6: {} + + prettier@3.3.3: {} + + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + sock-daemon@1.4.2: + dependencies: + rimraf: 5.0.10 + signal-exit: 4.1.0 + socket-post-message: 1.0.3 + + socket-post-message@1.0.3: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + tsimp@2.0.11(typescript@5.5.4): + dependencies: + '@isaacs/cached': 1.0.1 + '@isaacs/catcher': 1.0.4 + foreground-child: 3.3.0 + mkdirp: 3.0.1 + pirates: 4.0.6 + rimraf: 5.0.10 + signal-exit: 4.1.0 + sock-daemon: 1.4.2 + typescript: 5.5.4 + walk-up-path: 3.0.1 + + typescript@5.5.4: {} + + undici-types@6.19.8: {} + + walk-up-path@3.0.1: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 diff --git a/src/global.d.ts b/src/global.d.ts new file mode 100644 index 00000000000..b8041179bc5 --- /dev/null +++ b/src/global.d.ts @@ -0,0 +1,6 @@ +// See https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62651 + +interface ReadableStream { + values(options?: { preventCancel?: boolean }): AsyncIterableIterator; + [Symbol.asyncIterator](): AsyncIterableIterator; +} diff --git a/src/lazy-file.ts b/src/lazy-file.ts new file mode 100644 index 00000000000..549c25cde07 --- /dev/null +++ b/src/lazy-file.ts @@ -0,0 +1,2 @@ +export { type ByteRange, getByteLength, getIndexes } from "./lib/byte-range.js"; +export { type LazyFileContent, LazyFile } from "./lib/lazy-file.js"; diff --git a/src/lib/byte-range.spec.ts b/src/lib/byte-range.spec.ts new file mode 100644 index 00000000000..c313eb5eb29 --- /dev/null +++ b/src/lib/byte-range.spec.ts @@ -0,0 +1,40 @@ +import * as assert from "node:assert/strict"; +import { describe, it } from "node:test"; + +import { ByteRange, getByteLength, getIndexes } from "./byte-range.js"; + +describe("getByteLength", () => { + it("returns the correct length", () => { + let size = 100; + + let range: ByteRange = { start: 10, end: 20 }; + assert.strictEqual(getByteLength(range, size), 10); + + range = { start: 10, end: -10 }; + assert.strictEqual(getByteLength(range, size), 80); + + range = { start: -10, end: -10 }; + assert.strictEqual(getByteLength(range, size), 0); + + range = { start: -10, end: 20 }; + assert.strictEqual(getByteLength(range, size), 0); + }); +}); + +describe("getIndexes", () => { + it("returns the correct indexes", () => { + let size = 100; + + let range: ByteRange = { start: 10, end: 20 }; + assert.deepStrictEqual(getIndexes(range, size), [10, 20]); + + range = { start: 10, end: -10 }; + assert.deepStrictEqual(getIndexes(range, size), [10, 90]); + + range = { start: -10, end: -10 }; + assert.deepStrictEqual(getIndexes(range, size), [90, 90]); + + range = { start: -10, end: 20 }; + assert.deepStrictEqual(getIndexes(range, size), [90, 90]); + }); +}); diff --git a/src/lib/byte-range.ts b/src/lib/byte-range.ts new file mode 100644 index 00000000000..af36fa06c3d --- /dev/null +++ b/src/lib/byte-range.ts @@ -0,0 +1,36 @@ +export interface ByteRange { + /** + * The start index of the range (inclusive). If this number is negative, it represents an offset + * from the end of the buffer. + */ + start: number; + /** + * The end index of the range (exclusive). If this number is negative, it represents an offset + * from the end of the buffer. `Infinity` represents the end of the buffer. + */ + end: number; +} + +/** + * Returns the length of the byte range in a buffer of the given `size`. + */ +export function getByteLength(range: ByteRange, size: number): number { + let [start, end] = getIndexes(range, size); + return end - start; +} + +/** + * Resolves a byte range to absolute indexes in a buffer of the given `size`. + */ +export function getIndexes(range: ByteRange, size: number): [number, number] { + let start = Math.min( + Math.max(0, range.start < 0 ? size + range.start : range.start), + size + ); + let end = Math.min( + Math.max(start, range.end < 0 ? size + range.end : range.end), + size + ); + + return [start, end]; +} diff --git a/src/lib/lazy-file.spec.ts b/src/lib/lazy-file.spec.ts new file mode 100644 index 00000000000..4543af0ebb1 --- /dev/null +++ b/src/lib/lazy-file.spec.ts @@ -0,0 +1,141 @@ +import * as assert from "node:assert/strict"; +import { describe, it } from "node:test"; + +import { LazyFileContent, LazyFile } from "./lazy-file.js"; + +function createContent(value = ""): LazyFileContent { + let buffer = new TextEncoder().encode(value); + return { + byteLength: buffer.byteLength, + read() { + return new ReadableStream({ + start(controller) { + controller.enqueue(buffer); + controller.close(); + } + }); + } + }; +} + +describe("LazyFile", () => { + it("has the correct name, size, type, and lastModified timestamp", () => { + let now = Date.now(); + let file = new LazyFile(createContent("X".repeat(100)), "example.txt", { + type: "text/plain", + lastModified: now + }); + + assert.equal(file.name, "example.txt"); + assert.equal(file.size, 100); + assert.equal(file.type, "text/plain"); + assert.equal(file.lastModified, now); + }); + + it("returns the file's contents as a stream", async () => { + let content = createContent("hello world"); + let file = new LazyFile(content, "hello.txt", { + type: "text/plain" + }); + + let decoder = new TextDecoder(); + let result = ""; + for await (let chunk of file.stream()) { + result += decoder.decode(chunk, { stream: true }); + } + result += decoder.decode(); + + assert.equal(result, "hello world"); + }); + + it("returns the file's contents as a string", async () => { + let content = createContent("hello world"); + let file = new LazyFile(content, "hello.txt", { + type: "text/plain" + }); + + assert.equal(await file.text(), "hello world"); + }); + + describe("slice()", () => { + it("returns a file with the same name, type, and lastModified timestamp when slicing a file", () => { + let file = new LazyFile(createContent(), "hello.txt", { + type: "text/plain", + lastModified: Date.now() + }); + let slice = file.slice(0, 5, file.type); + assert.equal(slice.name, file.name); + assert.equal(slice.type, file.type); + assert.equal(slice.lastModified, file.lastModified); + }); + + it("returns a file with the same size as the original when slicing from 0 to the end", () => { + let file = new LazyFile(createContent("hello world"), "hello.txt", { + type: "text/plain" + }); + let slice = file.slice(0); + assert.equal(slice.size, file.size); + }); + + it('returns a file with size 0 when the "start" index is greater than the content length', () => { + let file = new LazyFile(createContent("hello world"), "hello.txt", { + type: "text/plain" + }); + let slice = file.slice(100); + assert.equal(slice.size, 0); + }); + + it('returns a file with size 0 when the "start" index is greater than the "end" index', () => { + let file = new LazyFile(createContent("hello world"), "hello.txt", { + type: "text/plain" + }); + let slice = file.slice(5, 0); + assert.equal(slice.size, 0); + }); + + it("calls content.read() with the correct range", t => { + let content = createContent("X".repeat(100)); + let read = t.mock.method(content, "read"); + let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + file.slice(10, 20).stream(); + assert.equal(read.mock.calls.length, 1); + assert.deepEqual(read.mock.calls[0].arguments, [10, 20]); + }); + + it('calls content.read() with the correct range when slicing a file with a negative "start" index', t => { + let content = createContent("X".repeat(100)); + let read = t.mock.method(content, "read"); + let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + file.slice(-10).stream(); + assert.equal(read.mock.calls.length, 1); + assert.deepEqual(read.mock.calls[0].arguments, [90, 100]); + }); + + it('calls content.read() with the correct range when slicing a file with a negative "end" index', t => { + let content = createContent("X".repeat(100)); + let read = t.mock.method(content, "read"); + let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + file.slice(0, -10).stream(); + assert.equal(read.mock.calls.length, 1); + assert.deepEqual(read.mock.calls[0].arguments, [0, 90]); + }); + + it('calls content.read() with the correct range when slicing a file with negative "start" and "end" indexes', t => { + let content = createContent("X".repeat(100)); + let read = t.mock.method(content, "read"); + let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + file.slice(-20, -10).stream(); + assert.equal(read.mock.calls.length, 1); + assert.deepEqual(read.mock.calls[0].arguments, [80, 90]); + }); + + it('calls content.read() with the correct range when slicing a file with a "start" index greater than the "end" index', t => { + let content = createContent("X".repeat(100)); + let read = t.mock.method(content, "read"); + let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + file.slice(20, 10).stream(); + assert.equal(read.mock.calls.length, 1); + assert.deepEqual(read.mock.calls[0].arguments, [20, 20]); + }); + }); +}); diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts new file mode 100644 index 00000000000..af6af9b21b0 --- /dev/null +++ b/src/lib/lazy-file.ts @@ -0,0 +1,116 @@ +import { ByteRange, getByteLength, getIndexes } from "./byte-range.js"; + +export interface LazyFileContent { + /** + * The total length of the content. + */ + byteLength: number; + /** + * Returns a stream that can be used to read the content, optionally within a given `start` + * (inclusive) and `end` (exclusive) index. + */ + read(start?: number, end?: number): ReadableStream; +} + +/** + * A `File` that is backed by a stream of data. This is useful for working with large files that + * would be impractical to load into memory all at once. + */ +export class LazyFile extends File { + #content: LazyFileContent; + #props?: FilePropertyBag; + #range?: ByteRange; + + constructor( + content: LazyFileContent, + name: string, + props?: FilePropertyBag, + range?: ByteRange + ) { + super([], name, props); + this.#content = content; + this.#props = props; + this.#range = range; + } + + /** + * The size of the file in bytes. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/size) + */ + get size(): number { + return this.#range != null + ? getByteLength(this.#range, this.#content.byteLength) + : this.#content.byteLength; + } + + /** + * Returns the file's contents as an array buffer. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer) + */ + async arrayBuffer(): Promise { + return (await this.bytes()).buffer; + } + + /** + * Returns the file's contents as a byte array. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/bytes) + */ + async bytes(): Promise { + let result = new Uint8Array(this.size); + + let offset = 0; + for await (let chunk of this.stream()) { + result.set(chunk, offset); + offset += chunk.length; + } + + return result; + } + + /** + * Returns a new `File` object that contains the data in the specified range. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) + */ + slice(start = 0, end = Infinity, contentType = ""): File { + let range = { start, end }; + + if (this.#range != null) { + // file.slice().slice() is additive + range = { + start: this.#range.start + start, + end: this.#range.end === Infinity ? end : this.#range.end + end + }; + } + + let props = { ...this.#props, type: contentType }; + + return new LazyFile(this.#content, this.name, props, range); + } + + /** + * Returns a stream that can be used to read the file's contents. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/stream) + */ + stream(): ReadableStream { + if (this.#range != null) { + let [start, end] = getIndexes(this.#range, this.#content.byteLength); + return this.#content.read(start, end); + } + + return this.#content.read(); + } + + /** + * Returns the file's contents as a string. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/text) + */ + async text(): Promise { + return new TextDecoder("utf-8").decode(await this.bytes()); + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000000..d8aaef54f9d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "lib": ["DOM", "ES2020"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true + } +} diff --git a/tsconfig.lib.json b/tsconfig.lib.json new file mode 100644 index 00000000000..c9819aa7ed5 --- /dev/null +++ b/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.spec.ts", "src/test/**/*.ts"], + "compilerOptions": { + "composite": true, + "rootDir": "src" + } +} diff --git a/tsconfig.spec.json b/tsconfig.spec.json new file mode 100644 index 00000000000..0dcc65f3ce6 --- /dev/null +++ b/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.spec.ts", "src/test/**/*.ts"], + "compilerOptions": { + "composite": true, + "types": ["node"] + } +} From a3485464f4529c0763d66260e9de5ad58f61f072 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 15:42:28 -0700 Subject: [PATCH 282/730] Add publish workflow --- .github/workflows/publish.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000000..cbdc3b17796 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,32 @@ +name: Publish + +on: + push: + tags: + - v[0-9]* + +jobs: + build: + runs-on: ubuntu-latest + + permissions: + contents: write + id-token: write + + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '20.x' + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - run: pnpm install + + - name: Publish to npm + run: npm publish --provenance --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From 68b894e006f319ce8d6b509e151a79e0defadcfd Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 15:43:59 -0700 Subject: [PATCH 283/730] Add CHANGELOG and version script --- CHANGELOG.md | 5 +++++ package.json | 3 ++- scripts/version.js | 30 ++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG.md create mode 100644 scripts/version.js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000000..d6386926ae1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# lazy-file CHANGELOG + +## HEAD + +- Initial release diff --git a/package.json b/package.json index 08c36e6fcc3..93eea2fb4ba 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "clean": "git clean -fdX .", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", - "prepare": "pnpm run build" + "prepare": "pnpm run build", + "version": "node scripts/version.js" }, "packageManager": "pnpm@9.7.1", "keywords": [ diff --git a/scripts/version.js b/scripts/version.js new file mode 100644 index 00000000000..3c140ddd756 --- /dev/null +++ b/scripts/version.js @@ -0,0 +1,30 @@ +import * as cp from "node:child_process"; +import * as fs from "node:fs"; +import * as path from "node:path"; +import * as process from "node:process"; + +const __dirname = path.dirname(new URL(import.meta.url).pathname); +const packageVersion = process.env.npm_package_version; + +// Update CHANGELOG.md with the current version +let changelogPath = path.resolve(__dirname, "../CHANGELOG.md"); +let changelog = fs.readFileSync(changelogPath, "utf-8"); +let match = /^## HEAD\n/m.exec(changelog); +if (match) { + let today = new Date().toLocaleDateString("en-US", { + month: "short", + day: "numeric", + year: "numeric" + }); + + changelog = + changelog.slice(0, match.index) + + `## v${packageVersion} (${today})\n` + + changelog.slice(match.index + match[0].length); + + fs.writeFileSync(changelogPath, changelog); + cp.execSync("git add CHANGELOG.md"); +} else { + console.error('Could not find "## HEAD" in CHANGELOG.md'); + process.exit(1); +} From 01a7ae3899ba05d26150a269057e7b8d79a37263 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 15:48:06 -0700 Subject: [PATCH 284/730] Add clean script --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index f0425d081ee..1dd1ea6d5c1 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "typescript": "^5.5.4" }, "scripts": { + "clean": "git clean -fdX .", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", "prepare": "pnpm run build", From d75deabc5be5ee795f0aac75ead920375b924f27 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 15:48:14 -0700 Subject: [PATCH 285/730] Small wording update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e14fcd3c58f..001392f708a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## The Problem -The web fetch API's built-in [`request.formData()` API](https://developer.mozilla.org/en-US/docs/Web/API/Request/formData) is not a great fit for server environments because it doesn't provide a way to stream file uploads. This means that when you call `request.formData()` in a server environment on a request that was submitted by a ``, any file uploads contained in the request are buffered in memory. For small files this may not be an issue, but it's a total non-starter for large files that exceed the server's memory capacity. +The web fetch API's built-in [`request.formData()` method](https://developer.mozilla.org/en-US/docs/Web/API/Request/formData) is not a great fit for server environments because it doesn't provide a way to stream file uploads. This means that when you call `request.formData()` in a server environment on a request that was submitted by a ``, any file uploads contained in the request are buffered in memory. For small files this may not be an issue, but it's a total non-starter for large files that exceed the server's memory capacity. `form-data-parser` fixes this issue by providing an API to handle streaming file data. From e33b26e951876c200a3386f7297a0caced70f1e1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 16:02:49 -0700 Subject: [PATCH 286/730] Add README.md --- README.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000000..ba71fc2323e --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# lazy-file + +`lazy-file` is a lazy, streaming `File` implementation for JavaScript. It allows you to easily [create `File` objects](https://developer.mozilla.org/en-US/docs/Web/API/File) that defer reading their contents until needed, which is ideal for situations where a file's contents do not fit in memory all at once. + +## The Problem + +JavaScript's [`File` API](https://developer.mozilla.org/en-US/docs/Web/API/File) is useful, but it's not a great fit for streaming server environments where you don't want to buffer file contents. In particular, [the `File` constructor](https://developer.mozilla.org/en-US/docs/Web/API/File/File) requires the contents of a file to be supplied up front when the object is first created. + +A `LazyFile` improves this model by accepting a `LazyFileContent` in its constructor. All other `File` functionality work exactly the same as the original, including `instanceof File`. + +## Installation + +Install from [npm](https://www.npmjs.com/): + +```sh +npm install @mjackson/lazy-file +``` + +## Usage + +```ts +import { type LazyFileContent, LazyFile } from "@mjackson/lazy-file"; + +let content: LazyFileContent = { + // The total length of this file in bytes. + byteLength: 100, + // A "reader" function that provides a stream of data for the file contents, + // beginning at the `start` index and ending at `end`. + read(start, end) { + // ... read the file contents from somewhere and return a ReadableStream + return new ReadableStream({ + start(controller) { + controller.enqueue("X".repeat(100).slice(start, end)); + controller.close(); + } + }); + } +}; + +let file = new LazyFile(content, "example.txt", { type: "text/plain" }); +await file.arrayBuffer(); // ArrayBuffer of the file's content +file.name; // "example.txt" +file.type; // "text/plain" +``` + +## License + +See [LICENSE](https://github.com/mjackson/lazy-file/blob/main/LICENSE) From 60275759918cc1a6168bf0e51d5bc980fe1fcf85 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 16:04:45 -0700 Subject: [PATCH 287/730] Prep for release --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 93eea2fb4ba..83cda1fb4ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "lazy-file", - "version": "1.0.0", + "name": "@mjackson/lazy-file", + "version": "0.0.0", "description": "Lazy, streaming files for JavaScript", "author": "Michael Jackson ", "repository": { From 03d3b3aa36697aeddf936add7c9634cefbbc49c9 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 21 Aug 2024 16:15:18 -0700 Subject: [PATCH 288/730] Version 1.0.0 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6386926ae1..8fa078edd94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # lazy-file CHANGELOG -## HEAD +## v1.0.0 (Aug 21, 2024) - Initial release diff --git a/package.json b/package.json index 83cda1fb4ae..242e21d6a9e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/lazy-file", - "version": "0.0.0", + "version": "1.0.0", "description": "Lazy, streaming files for JavaScript", "author": "Michael Jackson ", "repository": { From 942c46cc68db0c8c53b7eac7a83a5b2d427296e5 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 22 Aug 2024 01:36:44 -0700 Subject: [PATCH 289/730] Add BlobPart[] to LazyFile constructor --- CHANGELOG.md | 5 ++ src/lib/lazy-file.spec.ts | 63 +++++++++++++---- src/lib/lazy-file.ts | 140 ++++++++++++++++++++++++++++++++------ 3 files changed, 176 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fa078edd94..651754dc809 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # lazy-file CHANGELOG +## HEAD + +- Add ability to initialize a LazyFile with `BlobPart[]`, just like a normal `File` +- Add async iterator support to LazyFile + ## v1.0.0 (Aug 21, 2024) - Initial release diff --git a/src/lib/lazy-file.spec.ts b/src/lib/lazy-file.spec.ts index 4543af0ebb1..6d059a5d80d 100644 --- a/src/lib/lazy-file.spec.ts +++ b/src/lib/lazy-file.spec.ts @@ -3,7 +3,7 @@ import { describe, it } from "node:test"; import { LazyFileContent, LazyFile } from "./lazy-file.js"; -function createContent(value = ""): LazyFileContent { +function createLazyContent(value = ""): LazyFileContent { let buffer = new TextEncoder().encode(value); return { byteLength: buffer.byteLength, @@ -21,7 +21,7 @@ function createContent(value = ""): LazyFileContent { describe("LazyFile", () => { it("has the correct name, size, type, and lastModified timestamp", () => { let now = Date.now(); - let file = new LazyFile(createContent("X".repeat(100)), "example.txt", { + let file = new LazyFile(createLazyContent("X".repeat(100)), "example.txt", { type: "text/plain", lastModified: now }); @@ -32,8 +32,30 @@ describe("LazyFile", () => { assert.equal(file.lastModified, now); }); + it("can be initialized with a string as the content", async () => { + let file = new LazyFile("hello world", "hello.txt", { type: "text/plain" }); + assert.equal(file.size, 11); + assert.equal("hello world", await file.text()); + }); + + it("can be initialized with a [Blob] as the content", async () => { + let content = [new Blob(["hello world"], { type: "text/plain" })]; + let file = new LazyFile(content, "hello.txt", { type: "text/plain" }); + assert.equal(file.size, 11); + assert.equal("hello world", await file.text()); + }); + + it("can be initialized with another LazyFile as the content", async () => { + let content = [ + new LazyFile("hello world", "hello.txt", { type: "text/plain" }) + ]; + let file = new LazyFile(content, "hello.txt", { type: "text/plain" }); + assert.equal(file.size, 11); + assert.equal("hello world", await file.text()); + }); + it("returns the file's contents as a stream", async () => { - let content = createContent("hello world"); + let content = createLazyContent("hello world"); let file = new LazyFile(content, "hello.txt", { type: "text/plain" }); @@ -49,7 +71,7 @@ describe("LazyFile", () => { }); it("returns the file's contents as a string", async () => { - let content = createContent("hello world"); + let content = createLazyContent("hello world"); let file = new LazyFile(content, "hello.txt", { type: "text/plain" }); @@ -57,9 +79,24 @@ describe("LazyFile", () => { assert.equal(await file.text(), "hello world"); }); + it("can be read using for await...of", async () => { + let file = new LazyFile(createLazyContent("hello world"), "hello.txt", { + type: "text/plain" + }); + + let decoder = new TextDecoder(); + let result = ""; + for await (let chunk of file) { + result += decoder.decode(chunk, { stream: true }); + } + result += decoder.decode(); + + assert.equal(result, "hello world"); + }); + describe("slice()", () => { it("returns a file with the same name, type, and lastModified timestamp when slicing a file", () => { - let file = new LazyFile(createContent(), "hello.txt", { + let file = new LazyFile(createLazyContent(), "hello.txt", { type: "text/plain", lastModified: Date.now() }); @@ -70,7 +107,7 @@ describe("LazyFile", () => { }); it("returns a file with the same size as the original when slicing from 0 to the end", () => { - let file = new LazyFile(createContent("hello world"), "hello.txt", { + let file = new LazyFile(createLazyContent("hello world"), "hello.txt", { type: "text/plain" }); let slice = file.slice(0); @@ -78,7 +115,7 @@ describe("LazyFile", () => { }); it('returns a file with size 0 when the "start" index is greater than the content length', () => { - let file = new LazyFile(createContent("hello world"), "hello.txt", { + let file = new LazyFile(createLazyContent("hello world"), "hello.txt", { type: "text/plain" }); let slice = file.slice(100); @@ -86,7 +123,7 @@ describe("LazyFile", () => { }); it('returns a file with size 0 when the "start" index is greater than the "end" index', () => { - let file = new LazyFile(createContent("hello world"), "hello.txt", { + let file = new LazyFile(createLazyContent("hello world"), "hello.txt", { type: "text/plain" }); let slice = file.slice(5, 0); @@ -94,7 +131,7 @@ describe("LazyFile", () => { }); it("calls content.read() with the correct range", t => { - let content = createContent("X".repeat(100)); + let content = createLazyContent("X".repeat(100)); let read = t.mock.method(content, "read"); let file = new LazyFile(content, "example.txt", { type: "text/plain" }); file.slice(10, 20).stream(); @@ -103,7 +140,7 @@ describe("LazyFile", () => { }); it('calls content.read() with the correct range when slicing a file with a negative "start" index', t => { - let content = createContent("X".repeat(100)); + let content = createLazyContent("X".repeat(100)); let read = t.mock.method(content, "read"); let file = new LazyFile(content, "example.txt", { type: "text/plain" }); file.slice(-10).stream(); @@ -112,7 +149,7 @@ describe("LazyFile", () => { }); it('calls content.read() with the correct range when slicing a file with a negative "end" index', t => { - let content = createContent("X".repeat(100)); + let content = createLazyContent("X".repeat(100)); let read = t.mock.method(content, "read"); let file = new LazyFile(content, "example.txt", { type: "text/plain" }); file.slice(0, -10).stream(); @@ -121,7 +158,7 @@ describe("LazyFile", () => { }); it('calls content.read() with the correct range when slicing a file with negative "start" and "end" indexes', t => { - let content = createContent("X".repeat(100)); + let content = createLazyContent("X".repeat(100)); let read = t.mock.method(content, "read"); let file = new LazyFile(content, "example.txt", { type: "text/plain" }); file.slice(-20, -10).stream(); @@ -130,7 +167,7 @@ describe("LazyFile", () => { }); it('calls content.read() with the correct range when slicing a file with a "start" index greater than the "end" index', t => { - let content = createContent("X".repeat(100)); + let content = createLazyContent("X".repeat(100)); let read = t.mock.method(content, "read"); let file = new LazyFile(content, "example.txt", { type: "text/plain" }); file.slice(20, 10).stream(); diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts index af6af9b21b0..365d3a9676a 100644 --- a/src/lib/lazy-file.ts +++ b/src/lib/lazy-file.ts @@ -17,33 +17,57 @@ export interface LazyFileContent { * would be impractical to load into memory all at once. */ export class LazyFile extends File { - #content: LazyFileContent; - #props?: FilePropertyBag; - #range?: ByteRange; + readonly #content: (Blob | Uint8Array)[] | LazyFileContent; + readonly #contentSize: number; + readonly #props?: FilePropertyBag; + readonly #range?: ByteRange; constructor( - content: LazyFileContent, + content: BlobPart[] | string | LazyFileContent, name: string, props?: FilePropertyBag, range?: ByteRange ) { super([], name, props); - this.#content = content; + + if (Array.isArray(content)) { + this.#content = []; + this.#contentSize = 0; + + for (let part of content) { + if (part instanceof Blob) { + this.#content.push(part); + this.#contentSize += part.size; + } else { + let array: Uint8Array; + if (typeof part === "string") { + array = new TextEncoder().encode(part); + } else if (ArrayBuffer.isView(part)) { + array = new Uint8Array( + part.buffer, + part.byteOffset, + part.byteLength + ); + } else { + array = new Uint8Array(part); + } + this.#content.push(array); + this.#contentSize += array.byteLength; + } + } + } else if (typeof content === "string") { + let array = new TextEncoder().encode(content); + this.#content = [array]; + this.#contentSize = array.byteLength; + } else { + this.#content = content; + this.#contentSize = content.byteLength; + } + this.#props = props; this.#range = range; } - /** - * The size of the file in bytes. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/size) - */ - get size(): number { - return this.#range != null - ? getByteLength(this.#range, this.#content.byteLength) - : this.#content.byteLength; - } - /** * Returns the file's contents as an array buffer. * @@ -70,6 +94,17 @@ export class LazyFile extends File { return result; } + /** + * The size of the file in bytes. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/size) + */ + get size(): number { + return this.#range != null + ? getByteLength(this.#range, this.#contentSize) + : this.#contentSize; + } + /** * Returns a new `File` object that contains the data in the specified range. * @@ -98,11 +133,15 @@ export class LazyFile extends File { */ stream(): ReadableStream { if (this.#range != null) { - let [start, end] = getIndexes(this.#range, this.#content.byteLength); - return this.#content.read(start, end); + let [start, end] = getIndexes(this.#range, this.#contentSize); + return Array.isArray(this.#content) + ? streamContent(this.#content, start, end) + : this.#content.read(start, end); } - return this.#content.read(); + return Array.isArray(this.#content) + ? streamContent(this.#content) + : this.#content.read(); } /** @@ -113,4 +152,67 @@ export class LazyFile extends File { async text(): Promise { return new TextDecoder("utf-8").decode(await this.bytes()); } + + [Symbol.asyncIterator](): AsyncIterableIterator { + return this.stream()[Symbol.asyncIterator](); + } +} + +function streamContent( + content: (Uint8Array | Blob)[], + start = 0, + end = Infinity +): ReadableStream { + if (end < start) { + throw new RangeError( + "The end index must be greater than or equal to the start index" + ); + } + + let index = 0; + let bytesRead = 0; + + return new ReadableStream({ + async pull(controller) { + if (index >= content.length) { + controller.close(); + return; + } + + let hasPushed = false; + + function pushChunk(chunk: Uint8Array) { + let chunkLength = chunk.byteLength; + + if (!(bytesRead + chunkLength < start || bytesRead >= end)) { + let startIndex = Math.max(start - bytesRead, 0); + let endIndex = Math.min(end - bytesRead, chunkLength); + controller.enqueue(chunk.subarray(startIndex, endIndex)); + hasPushed = true; + } + + bytesRead += chunkLength; + } + + async function pushPart(part: Blob | Uint8Array) { + if (part instanceof Blob) { + if (bytesRead + part.size <= start) { + // We can skip this part entirely. + bytesRead += part.size; + return; + } + + for await (let chunk of part.stream()) { + pushChunk(chunk); + } + } else { + pushChunk(part); + } + } + + while (!hasPushed && index < content.length) { + await pushPart(content[index++]); + } + } + }); } From 876c1cc917c0f3fc04fac2b37225c8add1167dbc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 22 Aug 2024 01:37:09 -0700 Subject: [PATCH 290/730] Update README --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ba71fc2323e..82637e0d5e4 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,13 @@ ## The Problem -JavaScript's [`File` API](https://developer.mozilla.org/en-US/docs/Web/API/File) is useful, but it's not a great fit for streaming server environments where you don't want to buffer file contents. In particular, [the `File` constructor](https://developer.mozilla.org/en-US/docs/Web/API/File/File) requires the contents of a file to be supplied up front when the object is first created. +JavaScript's [`File` API](https://developer.mozilla.org/en-US/docs/Web/API/File) is useful, but it's not a great fit for streaming server environments where you don't want to buffer file contents. In particular, [the `File` constructor](https://developer.mozilla.org/en-US/docs/Web/API/File/File) requires the contents of a file to be supplied up front when the object is first created, like this: -A `LazyFile` improves this model by accepting a `LazyFileContent` in its constructor. All other `File` functionality work exactly the same as the original, including `instanceof File`. +```ts +let file = new File(["hello world"], "hello.txt", { type: "text/plain" }); +``` + +A `LazyFile` improves this model by accepting an additional content type in its constructor: `LazyFileContent`. All other `File` functionality works exactly as you'd expect, including `instanceof File`. ## Installation @@ -23,14 +27,14 @@ import { type LazyFileContent, LazyFile } from "@mjackson/lazy-file"; let content: LazyFileContent = { // The total length of this file in bytes. - byteLength: 100, + byteLength: 100000, // A "reader" function that provides a stream of data for the file contents, // beginning at the `start` index and ending at `end`. read(start, end) { // ... read the file contents from somewhere and return a ReadableStream return new ReadableStream({ start(controller) { - controller.enqueue("X".repeat(100).slice(start, end)); + controller.enqueue("X".repeat(100000).slice(start, end)); controller.close(); } }); From a62e0481ff7740b7662195f51df4fb65c78a2f6d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 22 Aug 2024 01:37:26 -0700 Subject: [PATCH 291/730] Version 1.1.0 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 651754dc809..908fed3d060 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # lazy-file CHANGELOG -## HEAD +## v1.1.0 (Aug 22, 2024) - Add ability to initialize a LazyFile with `BlobPart[]`, just like a normal `File` - Add async iterator support to LazyFile diff --git a/package.json b/package.json index 242e21d6a9e..553f5a97915 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/lazy-file", - "version": "1.0.0", + "version": "1.1.0", "description": "Lazy, streaming files for JavaScript", "author": "Michael Jackson ", "repository": { From efe3c21070f5f4d726fb36c61df66b1244ffaba8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 22 Aug 2024 02:10:27 -0700 Subject: [PATCH 292/730] Small tweak --- src/lib/lazy-file.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts index 365d3a9676a..3a1e57017c2 100644 --- a/src/lib/lazy-file.ts +++ b/src/lib/lazy-file.ts @@ -159,7 +159,7 @@ export class LazyFile extends File { } function streamContent( - content: (Uint8Array | Blob)[], + content: (Blob | Uint8Array)[], start = 0, end = Infinity ): ReadableStream { From 45a6b8426c21a7391c6375285a3d3a3c03710961 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 22 Aug 2024 18:52:10 -0700 Subject: [PATCH 293/730] Small optimization for streaming content arrays --- src/lib/lazy-file.spec.ts | 12 ++++++++++++ src/lib/lazy-file.ts | 22 +++++++++++----------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/lib/lazy-file.spec.ts b/src/lib/lazy-file.spec.ts index 6d059a5d80d..e07d938734f 100644 --- a/src/lib/lazy-file.spec.ts +++ b/src/lib/lazy-file.spec.ts @@ -54,6 +54,18 @@ describe("LazyFile", () => { assert.equal("hello world", await file.text()); }); + it("can be initialized with multiple Blobs and strings as the content and can slice them correctly", async () => { + let content = [ + new Blob([" hello "], { type: "text/plain" }), + "world", + new Blob(["!", " "], { type: "text/plain" }), + "extra stuff" + ]; + let file = new LazyFile(content, "hello.txt", { type: "text/plain" }); + assert.equal(file.size, 27); + assert.equal("hello world!", await file.slice(2, -13, "text/plain").text()); + }); + it("returns the file's contents as a stream", async () => { let content = createLazyContent("hello world"); let file = new LazyFile(content, "hello.txt", { diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts index 3a1e57017c2..c15663bdc75 100644 --- a/src/lib/lazy-file.ts +++ b/src/lib/lazy-file.ts @@ -106,11 +106,11 @@ export class LazyFile extends File { } /** - * Returns a new `File` object that contains the data in the specified range. + * Returns a new file that contains the data in the specified range. * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) */ - slice(start = 0, end = Infinity, contentType = ""): File { + slice(start = 0, end = Infinity, contentType = ""): LazyFile { let range = { start, end }; if (this.#range != null) { @@ -135,12 +135,12 @@ export class LazyFile extends File { if (this.#range != null) { let [start, end] = getIndexes(this.#range, this.#contentSize); return Array.isArray(this.#content) - ? streamContent(this.#content, start, end) + ? streamContentArray(this.#content, start, end) : this.#content.read(start, end); } return Array.isArray(this.#content) - ? streamContent(this.#content) + ? streamContentArray(this.#content) : this.#content.read(); } @@ -158,17 +158,11 @@ export class LazyFile extends File { } } -function streamContent( +function streamContentArray( content: (Blob | Uint8Array)[], start = 0, end = Infinity ): ReadableStream { - if (end < start) { - throw new RangeError( - "The end index must be greater than or equal to the start index" - ); - } - let index = 0; let bytesRead = 0; @@ -204,6 +198,12 @@ function streamContent( for await (let chunk of part.stream()) { pushChunk(chunk); + + if (bytesRead >= end) { + // We can stop reading now. + controller.close(); + break; + } } } else { pushChunk(part); From 5b401ece5411551170b58a191beea6063a667d29 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 22 Aug 2024 18:58:35 -0700 Subject: [PATCH 294/730] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 908fed3d060..87dc040db4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # lazy-file CHANGELOG +## HEAD + +- Small perf improvement when streaming content arrays with Blobs in them and ending early + ## v1.1.0 (Aug 22, 2024) - Add ability to initialize a LazyFile with `BlobPart[]`, just like a normal `File` From c05ed08a627cc9f4aa19a34a8461f5e5d2901a0c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 23 Aug 2024 08:45:03 -0700 Subject: [PATCH 295/730] Don't auto-propagate type, lastModified in slice --- CHANGELOG.md | 1 + src/lib/lazy-file.spec.ts | 15 ++++++--------- src/lib/lazy-file.ts | 14 +++++++------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87dc040db4d..5f62501152d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## HEAD +- BREAKING: Do not automatically propagate `name` and `lastModified` in `file.slice()`. This matches the behavior of `File` more closely - Small perf improvement when streaming content arrays with Blobs in them and ending early ## v1.1.0 (Aug 22, 2024) diff --git a/src/lib/lazy-file.spec.ts b/src/lib/lazy-file.spec.ts index e07d938734f..6c3086490f6 100644 --- a/src/lib/lazy-file.spec.ts +++ b/src/lib/lazy-file.spec.ts @@ -107,15 +107,12 @@ describe("LazyFile", () => { }); describe("slice()", () => { - it("returns a file with the same name, type, and lastModified timestamp when slicing a file", () => { - let file = new LazyFile(createLazyContent(), "hello.txt", { - type: "text/plain", - lastModified: Date.now() + it("returns a file with the same name", () => { + let file = new LazyFile("hello world", "hello.txt", { + type: "text/plain" }); - let slice = file.slice(0, 5, file.type); + let slice = file.slice(0, 5); assert.equal(slice.name, file.name); - assert.equal(slice.type, file.type); - assert.equal(slice.lastModified, file.lastModified); }); it("returns a file with the same size as the original when slicing from 0 to the end", () => { @@ -127,7 +124,7 @@ describe("LazyFile", () => { }); it('returns a file with size 0 when the "start" index is greater than the content length', () => { - let file = new LazyFile(createLazyContent("hello world"), "hello.txt", { + let file = new LazyFile("hello world", "hello.txt", { type: "text/plain" }); let slice = file.slice(100); @@ -135,7 +132,7 @@ describe("LazyFile", () => { }); it('returns a file with size 0 when the "start" index is greater than the "end" index', () => { - let file = new LazyFile(createLazyContent("hello world"), "hello.txt", { + let file = new LazyFile("hello world", "hello.txt", { type: "text/plain" }); let slice = file.slice(5, 0); diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts index c15663bdc75..d3798853dd5 100644 --- a/src/lib/lazy-file.ts +++ b/src/lib/lazy-file.ts @@ -19,7 +19,6 @@ export interface LazyFileContent { export class LazyFile extends File { readonly #content: (Blob | Uint8Array)[] | LazyFileContent; readonly #contentSize: number; - readonly #props?: FilePropertyBag; readonly #range?: ByteRange; constructor( @@ -64,7 +63,6 @@ export class LazyFile extends File { this.#contentSize = content.byteLength; } - this.#props = props; this.#range = range; } @@ -111,19 +109,18 @@ export class LazyFile extends File { * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) */ slice(start = 0, end = Infinity, contentType = ""): LazyFile { - let range = { start, end }; - + let range: ByteRange; if (this.#range != null) { // file.slice().slice() is additive range = { start: this.#range.start + start, end: this.#range.end === Infinity ? end : this.#range.end + end }; + } else { + range = { start, end }; } - let props = { ...this.#props, type: contentType }; - - return new LazyFile(this.#content, this.name, props, range); + return new LazyFile(this.#content, this.name, { type: contentType }, range); } /** @@ -153,6 +150,9 @@ export class LazyFile extends File { return new TextDecoder("utf-8").decode(await this.bytes()); } + /** + * Iterates over the file's contents as a stream of byte arrays. + */ [Symbol.asyncIterator](): AsyncIterableIterator { return this.stream()[Symbol.asyncIterator](); } From bd631fd36acae3886bec908ab2e319bdc2bb6246 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 23 Aug 2024 10:02:13 -0700 Subject: [PATCH 296/730] More specs for byte range and a doc comment --- src/lib/byte-range.spec.ts | 34 ++++++++++++++++++++++++++-------- src/lib/lazy-file.ts | 5 +++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/lib/byte-range.spec.ts b/src/lib/byte-range.spec.ts index c313eb5eb29..ccdb66977d4 100644 --- a/src/lib/byte-range.spec.ts +++ b/src/lib/byte-range.spec.ts @@ -8,16 +8,25 @@ describe("getByteLength", () => { let size = 100; let range: ByteRange = { start: 10, end: 20 }; - assert.strictEqual(getByteLength(range, size), 10); + assert.equal(getByteLength(range, size), 10); range = { start: 10, end: -10 }; - assert.strictEqual(getByteLength(range, size), 80); + assert.equal(getByteLength(range, size), 80); range = { start: -10, end: -10 }; - assert.strictEqual(getByteLength(range, size), 0); + assert.equal(getByteLength(range, size), 0); range = { start: -10, end: 20 }; - assert.strictEqual(getByteLength(range, size), 0); + assert.equal(getByteLength(range, size), 0); + + range = { start: 0, end: Infinity }; + assert.equal(getByteLength(range, size), 100); + + range = { start: Infinity, end: 0 }; + assert.equal(getByteLength(range, size), 0); + + range = { start: Infinity, end: Infinity }; + assert.equal(getByteLength(range, size), 0); }); }); @@ -26,15 +35,24 @@ describe("getIndexes", () => { let size = 100; let range: ByteRange = { start: 10, end: 20 }; - assert.deepStrictEqual(getIndexes(range, size), [10, 20]); + assert.deepEqual(getIndexes(range, size), [10, 20]); range = { start: 10, end: -10 }; - assert.deepStrictEqual(getIndexes(range, size), [10, 90]); + assert.deepEqual(getIndexes(range, size), [10, 90]); range = { start: -10, end: -10 }; - assert.deepStrictEqual(getIndexes(range, size), [90, 90]); + assert.deepEqual(getIndexes(range, size), [90, 90]); range = { start: -10, end: 20 }; - assert.deepStrictEqual(getIndexes(range, size), [90, 90]); + assert.deepEqual(getIndexes(range, size), [90, 90]); + + range = { start: 0, end: Infinity }; + assert.deepEqual(getIndexes(range, size), [0, 100]); + + range = { start: Infinity, end: 0 }; + assert.deepEqual(getIndexes(range, size), [100, 100]); + + range = { start: Infinity, end: Infinity }; + assert.deepEqual(getIndexes(range, size), [100, 100]); }); }); diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts index d3798853dd5..04de7db3ad8 100644 --- a/src/lib/lazy-file.ts +++ b/src/lib/lazy-file.ts @@ -106,6 +106,11 @@ export class LazyFile extends File { /** * Returns a new file that contains the data in the specified range. * + * Note: The built-in Blob API does not handle streaming content or provide a way to store and + * retrieve the content range, so this method differs slightly from the native Blob.slice(). + * Instead of returning a name-less Blob, this method returns a new LazyFile (which is a Blob) + * with the same name and the range applied. + * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) */ slice(start = 0, end = Infinity, contentType = ""): LazyFile { From 4535ed02add969a6b8c0ad3d97c44bc92e52cd5f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 23 Aug 2024 11:15:36 -0700 Subject: [PATCH 297/730] Make file.slice(, end) default to file.size --- CHANGELOG.md | 1 + src/lib/lazy-file.ts | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f62501152d..686c38c99b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## HEAD - BREAKING: Do not automatically propagate `name` and `lastModified` in `file.slice()`. This matches the behavior of `File` more closely +- In `slice(start, end)` make `end` default to `size` instead of `Infinity`. This more closely matches the `File` spec - Small perf improvement when streaming content arrays with Blobs in them and ending early ## v1.1.0 (Aug 22, 2024) diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts index 04de7db3ad8..b6b8621b4f6 100644 --- a/src/lib/lazy-file.ts +++ b/src/lib/lazy-file.ts @@ -1,5 +1,8 @@ import { ByteRange, getByteLength, getIndexes } from "./byte-range.js"; +/** + * A streaming interface for file content. + */ export interface LazyFileContent { /** * The total length of the content. @@ -13,8 +16,15 @@ export interface LazyFileContent { } /** - * A `File` that is backed by a stream of data. This is useful for working with large files that + * A `File` that may be backed by a stream of data. This is useful for working with large files that * would be impractical to load into memory all at once. + * + * This class is an extension of JavaScript's built-in `File` class with the following additions: + * + * - The constructor may accept a regular string or a `LazyFileContent` object + * - The constructor may accept a `ByteRange` object to represent a subset of the file's content + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/File) */ export class LazyFile extends File { readonly #content: (Blob | Uint8Array)[] | LazyFileContent; @@ -113,16 +123,16 @@ export class LazyFile extends File { * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) */ - slice(start = 0, end = Infinity, contentType = ""): LazyFile { - let range: ByteRange; + slice(start = 0, end?: number, contentType = ""): LazyFile { + let range: ByteRange | undefined; if (this.#range != null) { // file.slice().slice() is additive range = { start: this.#range.start + start, - end: this.#range.end === Infinity ? end : this.#range.end + end + end: this.#range.end + (end ?? 0) }; } else { - range = { start, end }; + range = { start, end: end ?? this.size }; } return new LazyFile(this.#content, this.name, { type: contentType }, range); From d63c4a3450f38e4bca0d6ee92cd7415699f4abe4 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 23 Aug 2024 11:19:34 -0700 Subject: [PATCH 298/730] Update doc comment --- src/lib/lazy-file.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts index b6b8621b4f6..8397a20d31c 100644 --- a/src/lib/lazy-file.ts +++ b/src/lib/lazy-file.ts @@ -22,7 +22,7 @@ export interface LazyFileContent { * This class is an extension of JavaScript's built-in `File` class with the following additions: * * - The constructor may accept a regular string or a `LazyFileContent` object - * - The constructor may accept a `ByteRange` object to represent a subset of the file's content + * - The constructor may accept a `ByteRange` to represent a subset of the file's content * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/File) */ @@ -116,10 +116,10 @@ export class LazyFile extends File { /** * Returns a new file that contains the data in the specified range. * - * Note: The built-in Blob API does not handle streaming content or provide a way to store and - * retrieve the content range, so this method differs slightly from the native Blob.slice(). - * Instead of returning a name-less Blob, this method returns a new LazyFile (which is a Blob) - * with the same name and the range applied. + * Note: The built-in Blob constructor does not support streaming content or provide a way to + * store and retrieve the content range, so this method differs slightly from the native + * `Blob.slice()`. Instead of returning a name-less `Blob`, this method returns a new `LazyFile` + * (which is a `Blob`) of the same name with the range applied. * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) */ From f55a7e592024cc06766af28553b326a71f359727 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 23 Aug 2024 11:35:11 -0700 Subject: [PATCH 299/730] Remove LazyFile[Symbol.asyncIterator] method --- CHANGELOG.md | 1 + src/lib/lazy-file.spec.ts | 15 --------------- src/lib/lazy-file.ts | 7 ------- 3 files changed, 1 insertion(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 686c38c99b6..e5511d73650 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## HEAD - BREAKING: Do not automatically propagate `name` and `lastModified` in `file.slice()`. This matches the behavior of `File` more closely +- BREAKING: Remove `LazyFile[Symbol.asyncIterator]` to match the behavior of `File` more closely - In `slice(start, end)` make `end` default to `size` instead of `Infinity`. This more closely matches the `File` spec - Small perf improvement when streaming content arrays with Blobs in them and ending early diff --git a/src/lib/lazy-file.spec.ts b/src/lib/lazy-file.spec.ts index 6c3086490f6..123716da22f 100644 --- a/src/lib/lazy-file.spec.ts +++ b/src/lib/lazy-file.spec.ts @@ -91,21 +91,6 @@ describe("LazyFile", () => { assert.equal(await file.text(), "hello world"); }); - it("can be read using for await...of", async () => { - let file = new LazyFile(createLazyContent("hello world"), "hello.txt", { - type: "text/plain" - }); - - let decoder = new TextDecoder(); - let result = ""; - for await (let chunk of file) { - result += decoder.decode(chunk, { stream: true }); - } - result += decoder.decode(); - - assert.equal(result, "hello world"); - }); - describe("slice()", () => { it("returns a file with the same name", () => { let file = new LazyFile("hello world", "hello.txt", { diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts index 8397a20d31c..31e55e14aa5 100644 --- a/src/lib/lazy-file.ts +++ b/src/lib/lazy-file.ts @@ -164,13 +164,6 @@ export class LazyFile extends File { async text(): Promise { return new TextDecoder("utf-8").decode(await this.bytes()); } - - /** - * Iterates over the file's contents as a stream of byte arrays. - */ - [Symbol.asyncIterator](): AsyncIterableIterator { - return this.stream()[Symbol.asyncIterator](); - } } function streamContentArray( From 6d919d4f1a7af03feaa6da4047e9c059f3f29efc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 23 Aug 2024 11:35:38 -0700 Subject: [PATCH 300/730] Update doc comment --- src/lib/lazy-file.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts index 31e55e14aa5..58d3e3a7fec 100644 --- a/src/lib/lazy-file.ts +++ b/src/lib/lazy-file.ts @@ -24,6 +24,9 @@ export interface LazyFileContent { * - The constructor may accept a regular string or a `LazyFileContent` object * - The constructor may accept a `ByteRange` to represent a subset of the file's content * + * In normal usage you shouldn't have to manage the `ByteRange` yourself. The `slice()` method takes + * care of creating new `LazyFile` instances with the correct range. + * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/File) */ export class LazyFile extends File { From f523f2d74cb83b1d20500167a6aeaae1c3fa5a28 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 23 Aug 2024 11:36:35 -0700 Subject: [PATCH 301/730] Update README --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 82637e0d5e4..c40d947601a 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,13 @@ `lazy-file` is a lazy, streaming `File` implementation for JavaScript. It allows you to easily [create `File` objects](https://developer.mozilla.org/en-US/docs/Web/API/File) that defer reading their contents until needed, which is ideal for situations where a file's contents do not fit in memory all at once. +## Features + +- Subclasses `File` so `lazyFile instanceof File` works +- Accepts all the same content types as [`the File() constructor`](https://developer.mozilla.org/en-US/docs/Web/API/File/File) +- Supports [`Blob.slice(start, end)`](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice), even on streaming content +- Memory efficient! + ## The Problem JavaScript's [`File` API](https://developer.mozilla.org/en-US/docs/Web/API/File) is useful, but it's not a great fit for streaming server environments where you don't want to buffer file contents. In particular, [the `File` constructor](https://developer.mozilla.org/en-US/docs/Web/API/File/File) requires the contents of a file to be supplied up front when the object is first created, like this: @@ -10,7 +17,7 @@ JavaScript's [`File` API](https://developer.mozilla.org/en-US/docs/Web/API/File) let file = new File(["hello world"], "hello.txt", { type: "text/plain" }); ``` -A `LazyFile` improves this model by accepting an additional content type in its constructor: `LazyFileContent`. All other `File` functionality works exactly as you'd expect, including `instanceof File`. +A `LazyFile` improves this model by accepting an additional content type in its constructor: `LazyFileContent`. All other `File` functionality works as you'd expect. ## Installation From 796e94371b3ba04e318b898886532197961fcb45 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 23 Aug 2024 11:40:37 -0700 Subject: [PATCH 302/730] Version 2.0.0 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5511d73650..e23da4e22af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # lazy-file CHANGELOG -## HEAD +## v2.0.0 (Aug 23, 2024) - BREAKING: Do not automatically propagate `name` and `lastModified` in `file.slice()`. This matches the behavior of `File` more closely - BREAKING: Remove `LazyFile[Symbol.asyncIterator]` to match the behavior of `File` more closely diff --git a/package.json b/package.json index 553f5a97915..8889ba42443 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/lazy-file", - "version": "1.1.0", + "version": "2.0.0", "description": "Lazy, streaming files for JavaScript", "author": "Michael Jackson ", "repository": { From 033ea2c58fe1bd7e50119e56ce00898641b5a348 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 23 Aug 2024 15:50:55 -0700 Subject: [PATCH 303/730] Remove LazyFile and make it a dep --- package.json | 5 +- pnpm-lock.yaml | 9 +++ src/file-storage.ts | 2 - src/lib/byte-range.spec.ts | 40 ---------- src/lib/byte-range.ts | 36 --------- src/lib/lazy-file.spec.ts | 141 ---------------------------------- src/lib/lazy-file.ts | 116 ---------------------------- src/lib/local-file-storage.ts | 19 ++--- 8 files changed, 23 insertions(+), 345 deletions(-) delete mode 100644 src/lib/byte-range.spec.ts delete mode 100644 src/lib/byte-range.ts delete mode 100644 src/lib/lazy-file.spec.ts delete mode 100644 src/lib/lazy-file.ts diff --git a/package.json b/package.json index 7079d52d1ce..cae28280aa5 100644 --- a/package.json +++ b/package.json @@ -37,5 +37,8 @@ "storage", "stream", "fs" - ] + ], + "dependencies": { + "@mjackson/lazy-file": "^1.1.0" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5cacec13ea8..6eb32846260 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,10 @@ settings: importers: .: + dependencies: + '@mjackson/lazy-file': + specifier: ^1.1.0 + version: 1.1.0 devDependencies: '@types/node': specifier: ^20.14.10 @@ -33,6 +37,9 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@mjackson/lazy-file@1.1.0': + resolution: {integrity: sha512-QBbeLhBc14V+MIG6qNiX0iKNB6Cbfogmr3Kc4uhEkOnzxeyr5ImfzMulM4Od+IG7OYtHKGpoFJiaA59kmGErJQ==} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -223,6 +230,8 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@mjackson/lazy-file@1.1.0': {} + '@pkgjs/parseargs@0.11.0': optional: true diff --git a/src/file-storage.ts b/src/file-storage.ts index 9194215cf33..7cb07072c63 100644 --- a/src/file-storage.ts +++ b/src/file-storage.ts @@ -1,5 +1,3 @@ -export { type ByteRange, getByteLength, getIndexes } from "./lib/byte-range.js"; export { type FileStorage } from "./lib/file-storage.js"; -export { LazyFile } from "./lib/lazy-file.js"; export { LocalFileStorage } from "./lib/local-file-storage.js"; export { MemoryFileStorage } from "./lib/memory-file-storage.js"; diff --git a/src/lib/byte-range.spec.ts b/src/lib/byte-range.spec.ts deleted file mode 100644 index c313eb5eb29..00000000000 --- a/src/lib/byte-range.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -import * as assert from "node:assert/strict"; -import { describe, it } from "node:test"; - -import { ByteRange, getByteLength, getIndexes } from "./byte-range.js"; - -describe("getByteLength", () => { - it("returns the correct length", () => { - let size = 100; - - let range: ByteRange = { start: 10, end: 20 }; - assert.strictEqual(getByteLength(range, size), 10); - - range = { start: 10, end: -10 }; - assert.strictEqual(getByteLength(range, size), 80); - - range = { start: -10, end: -10 }; - assert.strictEqual(getByteLength(range, size), 0); - - range = { start: -10, end: 20 }; - assert.strictEqual(getByteLength(range, size), 0); - }); -}); - -describe("getIndexes", () => { - it("returns the correct indexes", () => { - let size = 100; - - let range: ByteRange = { start: 10, end: 20 }; - assert.deepStrictEqual(getIndexes(range, size), [10, 20]); - - range = { start: 10, end: -10 }; - assert.deepStrictEqual(getIndexes(range, size), [10, 90]); - - range = { start: -10, end: -10 }; - assert.deepStrictEqual(getIndexes(range, size), [90, 90]); - - range = { start: -10, end: 20 }; - assert.deepStrictEqual(getIndexes(range, size), [90, 90]); - }); -}); diff --git a/src/lib/byte-range.ts b/src/lib/byte-range.ts deleted file mode 100644 index af36fa06c3d..00000000000 --- a/src/lib/byte-range.ts +++ /dev/null @@ -1,36 +0,0 @@ -export interface ByteRange { - /** - * The start index of the range (inclusive). If this number is negative, it represents an offset - * from the end of the buffer. - */ - start: number; - /** - * The end index of the range (exclusive). If this number is negative, it represents an offset - * from the end of the buffer. `Infinity` represents the end of the buffer. - */ - end: number; -} - -/** - * Returns the length of the byte range in a buffer of the given `size`. - */ -export function getByteLength(range: ByteRange, size: number): number { - let [start, end] = getIndexes(range, size); - return end - start; -} - -/** - * Resolves a byte range to absolute indexes in a buffer of the given `size`. - */ -export function getIndexes(range: ByteRange, size: number): [number, number] { - let start = Math.min( - Math.max(0, range.start < 0 ? size + range.start : range.start), - size - ); - let end = Math.min( - Math.max(start, range.end < 0 ? size + range.end : range.end), - size - ); - - return [start, end]; -} diff --git a/src/lib/lazy-file.spec.ts b/src/lib/lazy-file.spec.ts deleted file mode 100644 index 4543af0ebb1..00000000000 --- a/src/lib/lazy-file.spec.ts +++ /dev/null @@ -1,141 +0,0 @@ -import * as assert from "node:assert/strict"; -import { describe, it } from "node:test"; - -import { LazyFileContent, LazyFile } from "./lazy-file.js"; - -function createContent(value = ""): LazyFileContent { - let buffer = new TextEncoder().encode(value); - return { - byteLength: buffer.byteLength, - read() { - return new ReadableStream({ - start(controller) { - controller.enqueue(buffer); - controller.close(); - } - }); - } - }; -} - -describe("LazyFile", () => { - it("has the correct name, size, type, and lastModified timestamp", () => { - let now = Date.now(); - let file = new LazyFile(createContent("X".repeat(100)), "example.txt", { - type: "text/plain", - lastModified: now - }); - - assert.equal(file.name, "example.txt"); - assert.equal(file.size, 100); - assert.equal(file.type, "text/plain"); - assert.equal(file.lastModified, now); - }); - - it("returns the file's contents as a stream", async () => { - let content = createContent("hello world"); - let file = new LazyFile(content, "hello.txt", { - type: "text/plain" - }); - - let decoder = new TextDecoder(); - let result = ""; - for await (let chunk of file.stream()) { - result += decoder.decode(chunk, { stream: true }); - } - result += decoder.decode(); - - assert.equal(result, "hello world"); - }); - - it("returns the file's contents as a string", async () => { - let content = createContent("hello world"); - let file = new LazyFile(content, "hello.txt", { - type: "text/plain" - }); - - assert.equal(await file.text(), "hello world"); - }); - - describe("slice()", () => { - it("returns a file with the same name, type, and lastModified timestamp when slicing a file", () => { - let file = new LazyFile(createContent(), "hello.txt", { - type: "text/plain", - lastModified: Date.now() - }); - let slice = file.slice(0, 5, file.type); - assert.equal(slice.name, file.name); - assert.equal(slice.type, file.type); - assert.equal(slice.lastModified, file.lastModified); - }); - - it("returns a file with the same size as the original when slicing from 0 to the end", () => { - let file = new LazyFile(createContent("hello world"), "hello.txt", { - type: "text/plain" - }); - let slice = file.slice(0); - assert.equal(slice.size, file.size); - }); - - it('returns a file with size 0 when the "start" index is greater than the content length', () => { - let file = new LazyFile(createContent("hello world"), "hello.txt", { - type: "text/plain" - }); - let slice = file.slice(100); - assert.equal(slice.size, 0); - }); - - it('returns a file with size 0 when the "start" index is greater than the "end" index', () => { - let file = new LazyFile(createContent("hello world"), "hello.txt", { - type: "text/plain" - }); - let slice = file.slice(5, 0); - assert.equal(slice.size, 0); - }); - - it("calls content.read() with the correct range", t => { - let content = createContent("X".repeat(100)); - let read = t.mock.method(content, "read"); - let file = new LazyFile(content, "example.txt", { type: "text/plain" }); - file.slice(10, 20).stream(); - assert.equal(read.mock.calls.length, 1); - assert.deepEqual(read.mock.calls[0].arguments, [10, 20]); - }); - - it('calls content.read() with the correct range when slicing a file with a negative "start" index', t => { - let content = createContent("X".repeat(100)); - let read = t.mock.method(content, "read"); - let file = new LazyFile(content, "example.txt", { type: "text/plain" }); - file.slice(-10).stream(); - assert.equal(read.mock.calls.length, 1); - assert.deepEqual(read.mock.calls[0].arguments, [90, 100]); - }); - - it('calls content.read() with the correct range when slicing a file with a negative "end" index', t => { - let content = createContent("X".repeat(100)); - let read = t.mock.method(content, "read"); - let file = new LazyFile(content, "example.txt", { type: "text/plain" }); - file.slice(0, -10).stream(); - assert.equal(read.mock.calls.length, 1); - assert.deepEqual(read.mock.calls[0].arguments, [0, 90]); - }); - - it('calls content.read() with the correct range when slicing a file with negative "start" and "end" indexes', t => { - let content = createContent("X".repeat(100)); - let read = t.mock.method(content, "read"); - let file = new LazyFile(content, "example.txt", { type: "text/plain" }); - file.slice(-20, -10).stream(); - assert.equal(read.mock.calls.length, 1); - assert.deepEqual(read.mock.calls[0].arguments, [80, 90]); - }); - - it('calls content.read() with the correct range when slicing a file with a "start" index greater than the "end" index', t => { - let content = createContent("X".repeat(100)); - let read = t.mock.method(content, "read"); - let file = new LazyFile(content, "example.txt", { type: "text/plain" }); - file.slice(20, 10).stream(); - assert.equal(read.mock.calls.length, 1); - assert.deepEqual(read.mock.calls[0].arguments, [20, 20]); - }); - }); -}); diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts deleted file mode 100644 index af6af9b21b0..00000000000 --- a/src/lib/lazy-file.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { ByteRange, getByteLength, getIndexes } from "./byte-range.js"; - -export interface LazyFileContent { - /** - * The total length of the content. - */ - byteLength: number; - /** - * Returns a stream that can be used to read the content, optionally within a given `start` - * (inclusive) and `end` (exclusive) index. - */ - read(start?: number, end?: number): ReadableStream; -} - -/** - * A `File` that is backed by a stream of data. This is useful for working with large files that - * would be impractical to load into memory all at once. - */ -export class LazyFile extends File { - #content: LazyFileContent; - #props?: FilePropertyBag; - #range?: ByteRange; - - constructor( - content: LazyFileContent, - name: string, - props?: FilePropertyBag, - range?: ByteRange - ) { - super([], name, props); - this.#content = content; - this.#props = props; - this.#range = range; - } - - /** - * The size of the file in bytes. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/size) - */ - get size(): number { - return this.#range != null - ? getByteLength(this.#range, this.#content.byteLength) - : this.#content.byteLength; - } - - /** - * Returns the file's contents as an array buffer. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer) - */ - async arrayBuffer(): Promise { - return (await this.bytes()).buffer; - } - - /** - * Returns the file's contents as a byte array. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/bytes) - */ - async bytes(): Promise { - let result = new Uint8Array(this.size); - - let offset = 0; - for await (let chunk of this.stream()) { - result.set(chunk, offset); - offset += chunk.length; - } - - return result; - } - - /** - * Returns a new `File` object that contains the data in the specified range. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) - */ - slice(start = 0, end = Infinity, contentType = ""): File { - let range = { start, end }; - - if (this.#range != null) { - // file.slice().slice() is additive - range = { - start: this.#range.start + start, - end: this.#range.end === Infinity ? end : this.#range.end + end - }; - } - - let props = { ...this.#props, type: contentType }; - - return new LazyFile(this.#content, this.name, props, range); - } - - /** - * Returns a stream that can be used to read the file's contents. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/stream) - */ - stream(): ReadableStream { - if (this.#range != null) { - let [start, end] = getIndexes(this.#range, this.#content.byteLength); - return this.#content.read(start, end); - } - - return this.#content.read(); - } - - /** - * Returns the file's contents as a string. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/text) - */ - async text(): Promise { - return new TextDecoder("utf-8").decode(await this.bytes()); - } -} diff --git a/src/lib/local-file-storage.ts b/src/lib/local-file-storage.ts index 2cff5617775..e924b3ef3f6 100644 --- a/src/lib/local-file-storage.ts +++ b/src/lib/local-file-storage.ts @@ -1,9 +1,9 @@ import * as fs from "node:fs"; import * as fsp from "node:fs/promises"; import * as path from "node:path"; +import { LazyFileContent, LazyFile } from "@mjackson/lazy-file"; import { FileStorage } from "./file-storage.js"; -import { LazyFileContent, LazyFile } from "./lazy-file.js"; type FileWithoutSize = Omit; @@ -16,28 +16,29 @@ type FileWithoutSize = Omit; * same storage object. */ export class LocalFileStorage implements FileStorage { - #directory: string; + #dirname: string; #metadata: FileMetadataIndex; /** * @param directory The directory where files are stored */ constructor(directory: string) { + this.#dirname = path.resolve(directory); + try { - let stat = fs.statSync(directory); + let stat = fs.statSync(this.#dirname); if (!stat.isDirectory()) { - throw new Error(`Path "${directory}" is not a directory`); + throw new Error(`Path "${this.#dirname}" is not a directory`); } } catch (error) { if (!isNoEntityError(error)) { throw error; } - fs.mkdirSync(directory, { recursive: true }); + fs.mkdirSync(this.#dirname, { recursive: true }); } - this.#directory = directory; this.#metadata = new FileMetadataIndex( path.join(directory, ".metadata.json") ); @@ -48,7 +49,7 @@ export class LocalFileStorage implements FileStorage { } async set(key: string, file: FileWithoutSize): Promise { - let { name, size } = await createFile(this.#directory, file.stream()); + let { name, size } = await createFile(this.#dirname, file.stream()); await this.#metadata.set(key, { file: name, @@ -65,7 +66,7 @@ export class LocalFileStorage implements FileStorage { return null; } - let file = path.join(this.#directory, metadata.file); + let file = path.join(this.#dirname, metadata.file); let content: LazyFileContent = { byteLength: metadata.size, read(start, end) { @@ -83,7 +84,7 @@ export class LocalFileStorage implements FileStorage { return; } - let file = path.join(this.#directory, metadata.file); + let file = path.join(this.#dirname, metadata.file); try { await fsp.unlink(file); } catch (error) { From d43a2fcb6ba82d24adf80f561628a649136476cf Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 16:11:01 -0700 Subject: [PATCH 304/730] Add lazy-file/fs --- CHANGELOG.md | 4 ++++ README.md | 15 +++++++++++++++ package.json | 6 +++++- pnpm-lock.yaml | 10 ++++++++++ src/fs.ts | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 src/fs.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index e23da4e22af..9e917bf5e55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # lazy-file CHANGELOG +## HEAD + +- Added `getFile` helper to `lazy-file/fs` export for reading files from the local filesystem + ## v2.0.0 (Aug 23, 2024) - BREAKING: Do not automatically propagate `name` and `lastModified` in `file.slice()`. This matches the behavior of `File` more closely diff --git a/README.md b/README.md index c40d947601a..82943c5eab0 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,8 @@ npm install @mjackson/lazy-file ## Usage +The low-level API can be used to create a `File` that streams content from anywhere: + ```ts import { type LazyFileContent, LazyFile } from "@mjackson/lazy-file"; @@ -54,6 +56,19 @@ file.name; // "example.txt" file.type; // "text/plain" ``` +`lazy-file` also ships with a `lazy-file/fs` export that makes it easy to get a (lazy!) `File` object from the local filesystem. These objects are very lightweight and do not attempt to actually read any data from disk until needed. + +```ts +import { getFile } from "@mjackson/lazy-file/fs"; + +// No data is read at this point, it's just a reference to a file on the local filesystem. +let file = getFile("./path/to/file.json"); + +// Data is read when you call file.text() (or any of the other Blob methods, like file.bytes(), +// file.stream(), etc.) +let json = JSON.parse(await file.text()); +``` + ## License See [LICENSE](https://github.com/mjackson/lazy-file/blob/main/LICENSE) diff --git a/package.json b/package.json index 8889ba42443..d95029a3106 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "type": "module", "exports": { ".": "./dist/lazy-file.js", + "./fs": "./dist/fs.js", "./package.json": "./package.json" }, "devDependencies": { @@ -36,5 +37,8 @@ "file", "buffer", "blob" - ] + ], + "dependencies": { + "mrmime": "^2.0.0" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c0178d428b8..06db263ad07 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,10 @@ settings: importers: .: + dependencies: + mrmime: + specifier: ^2.0.0 + version: 2.0.0 devDependencies: '@types/node': specifier: ^22.5.0 @@ -116,6 +120,10 @@ packages: engines: {node: '>=10'} hasBin: true + mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + engines: {node: '>=10'} + package-json-from-dist@1.0.0: resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} @@ -298,6 +306,8 @@ snapshots: mkdirp@3.0.1: {} + mrmime@2.0.0: {} + package-json-from-dist@1.0.0: {} path-key@3.1.1: {} diff --git a/src/fs.ts b/src/fs.ts new file mode 100644 index 00000000000..2fb5fb6e28d --- /dev/null +++ b/src/fs.ts @@ -0,0 +1,50 @@ +import * as fs from "node:fs"; +import * as path from "node:path"; +import { lookup } from "mrmime"; + +import { LazyFileContent, LazyFile } from "./lib/lazy-file.js"; + +/** + * Returns a `File` from the local filesytem. + * + * [MDN `File` Reference](https://developer.mozilla.org/en-US/docs/Web/API/File) + */ +export function getFile( + filename: string, + { name = path.basename(filename), type = lookup(filename) } = {} +): File { + let stats = fs.statSync(filename); + + if (!stats.isFile()) { + throw new Error(`Path "${filename}" is not a file`); + } + + let content: LazyFileContent = { + byteLength: stats.size, + read(start, end) { + return readFile(filename, start, end); + } + }; + + return new LazyFile(content, name, { type, lastModified: stats.mtimeMs }); +} + +function readFile( + filename: string, + start = 0, + end = Infinity +): ReadableStream { + let read = fs.createReadStream(filename, { start, end: end - 1 }).iterator(); + + return new ReadableStream({ + async pull(controller) { + let { done, value } = await read.next(); + + if (done) { + controller.close(); + } else { + controller.enqueue(value); + } + } + }); +} From e706074424a4dfbb74107f0f5dd9cc991e779237 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 16:11:13 -0700 Subject: [PATCH 305/730] Version 2.1.0 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e917bf5e55..20db6fb73c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # lazy-file CHANGELOG -## HEAD +## v2.1.0 (Aug 24, 2024) - Added `getFile` helper to `lazy-file/fs` export for reading files from the local filesystem diff --git a/package.json b/package.json index d95029a3106..2cf37d0b898 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/lazy-file", - "version": "2.0.0", + "version": "2.1.0", "description": "Lazy, streaming files for JavaScript", "author": "Michael Jackson ", "repository": { From 79c238a85a894bcb3365072471b10d4ceb8a7edc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 16:32:36 -0700 Subject: [PATCH 306/730] Use getFile internally --- package.json | 2 +- pnpm-lock.yaml | 18 +++-- src/lib/local-file-storage.ts | 120 +++++++++++----------------------- 3 files changed, 51 insertions(+), 89 deletions(-) diff --git a/package.json b/package.json index cae28280aa5..f1278d43d77 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,6 @@ "fs" ], "dependencies": { - "@mjackson/lazy-file": "^1.1.0" + "@mjackson/lazy-file": "^2.1.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6eb32846260..520817980d2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@mjackson/lazy-file': - specifier: ^1.1.0 - version: 1.1.0 + specifier: ^2.1.0 + version: 2.1.0 devDependencies: '@types/node': specifier: ^20.14.10 @@ -37,8 +37,8 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} - '@mjackson/lazy-file@1.1.0': - resolution: {integrity: sha512-QBbeLhBc14V+MIG6qNiX0iKNB6Cbfogmr3Kc4uhEkOnzxeyr5ImfzMulM4Od+IG7OYtHKGpoFJiaA59kmGErJQ==} + '@mjackson/lazy-file@2.1.0': + resolution: {integrity: sha512-HpBZfJfxLP1m0ytaytKzSaURP9OH0YQ8t5kr3/qDdaRJbrXrLHK03xmWptMMrepCbpLiKNFApQd1wYKzid6ITw==} '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} @@ -123,6 +123,10 @@ packages: engines: {node: '>=10'} hasBin: true + mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + engines: {node: '>=10'} + package-json-from-dist@1.0.0: resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} @@ -230,7 +234,9 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - '@mjackson/lazy-file@1.1.0': {} + '@mjackson/lazy-file@2.1.0': + dependencies: + mrmime: 2.0.0 '@pkgjs/parseargs@0.11.0': optional: true @@ -307,6 +313,8 @@ snapshots: mkdirp@3.0.1: {} + mrmime@2.0.0: {} + package-json-from-dist@1.0.0: {} path-key@3.1.1: {} diff --git a/src/lib/local-file-storage.ts b/src/lib/local-file-storage.ts index e924b3ef3f6..f890d7b6b55 100644 --- a/src/lib/local-file-storage.ts +++ b/src/lib/local-file-storage.ts @@ -1,12 +1,10 @@ import * as fs from "node:fs"; import * as fsp from "node:fs/promises"; import * as path from "node:path"; -import { LazyFileContent, LazyFile } from "@mjackson/lazy-file"; +import { getFile } from "@mjackson/lazy-file/fs"; import { FileStorage } from "./file-storage.js"; -type FileWithoutSize = Omit; - /** * A `FileStorage` that is backed by the local filesystem. * @@ -48,45 +46,33 @@ export class LocalFileStorage implements FileStorage { return this.#metadata.has(key); } - async set(key: string, file: FileWithoutSize): Promise { - let { name, size } = await createFile(this.#dirname, file.stream()); + async set(key: string, file: File): Promise { + let localFile = await storeFile(this.#dirname, file); await this.#metadata.set(key, { - file: name, + file: localFile.name, name: file.name, - size: size, + size: localFile.size, type: file.type }); } async get(key: string): Promise { let metadata = await this.#metadata.get(key); + if (metadata == null) return null; - if (metadata == null) { - return null; - } - - let file = path.join(this.#dirname, metadata.file); - let content: LazyFileContent = { - byteLength: metadata.size, - read(start, end) { - return readFile(file, start, end); - } - }; - - return new LazyFile(content, metadata.name, { type: metadata.type }); + let filename = path.join(this.#dirname, metadata.file); + return getFile(filename, { name: metadata.name, type: metadata.type }); } async remove(key: string): Promise { let metadata = await this.#metadata.get(key); + if (metadata == null) return; - if (metadata == null) { - return; - } + let filename = path.join(this.#dirname, metadata.file); - let file = path.join(this.#dirname, metadata.file); try { - await fsp.unlink(file); + await fsp.unlink(filename); } catch (error) { if (!isNoEntityError(error)) { throw error; @@ -97,65 +83,34 @@ export class LocalFileStorage implements FileStorage { } } -function randomFilename(): string { - return `${new Date().getTime().toString(36)}.${Math.random().toString(36).slice(2, 6)}`; -} - -function createFile( - directory: string, - stream: ReadableStream -): Promise<{ name: string; size: number }> { - let filename = randomFilename(); - let file = path.join(directory, filename); - - return new Promise((resolve, reject) => { - fs.open(file, "w", async (error, fd) => { - if (error) { - if (error.code === "EEXIST") { - // Try again with a different filename - return resolve(createFile(directory, stream)); - } else { - return reject(error); - } - } - - let writeStream = fs.createWriteStream(file, { fd }); - let bytesWritten = 0; - - try { - for await (let chunk of stream) { - writeStream.write(chunk); - bytesWritten += chunk.length; - } +async function storeFile(dirname: string, file: File): Promise { + let filename = path.join(dirname, randomFilename()); + + let handle: fsp.FileHandle; + try { + handle = await fsp.open(filename, "w"); + } catch (error) { + if ((error as NodeJS.ErrnoException).code === "EEXIST") { + // Try again with a different filename + return storeFile(dirname, file); + } else { + throw error; + } + } - writeStream.end(); + try { + for await (let chunk of file.stream()) { + await handle.write(chunk); + } + } finally { + await handle.close(); + } - resolve({ name: filename, size: bytesWritten }); - } catch (error) { - reject(error); - } - }); - }); + return getFile(filename); } -function readFile( - filename: string, - start?: number, - end = Infinity -): ReadableStream { - let read = fs.createReadStream(filename, { start, end: end - 1 }).iterator(); - - return new ReadableStream({ - async pull(controller) { - let { done, value } = await read.next(); - - if (done) { - controller.close(); - } else { - controller.enqueue(value); - } - } - }); +function randomFilename(): string { + return `${new Date().getTime().toString(36)}.${Math.random().toString(36).slice(2, 6)}`; } interface FileMetadata { @@ -174,7 +129,7 @@ class FileMetadataIndex { async #getAll(): Promise> { try { - return JSON.parse(await fsp.readFile(this.#path, { encoding: "utf-8" })); + return JSON.parse(await getFile(this.#path).text()); } catch (error) { if (!isNoEntityError(error)) { throw error; @@ -213,8 +168,7 @@ function isNoEntityError( obj: unknown ): obj is NodeJS.ErrnoException & { code: "ENOENT" } { return ( - typeof obj === "object" && - obj !== null && + obj instanceof Error && "code" in obj && (obj as NodeJS.ErrnoException).code === "ENOENT" ); From f306afcb6fd24ad8b4730b4447b3659ff3632d0a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 16:35:40 -0700 Subject: [PATCH 307/730] Rename var --- src/lib/local-file-storage.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/local-file-storage.ts b/src/lib/local-file-storage.ts index f890d7b6b55..c6d415665c2 100644 --- a/src/lib/local-file-storage.ts +++ b/src/lib/local-file-storage.ts @@ -24,9 +24,9 @@ export class LocalFileStorage implements FileStorage { this.#dirname = path.resolve(directory); try { - let stat = fs.statSync(this.#dirname); + let stats = fs.statSync(this.#dirname); - if (!stat.isDirectory()) { + if (!stats.isDirectory()) { throw new Error(`Path "${this.#dirname}" is not a directory`); } } catch (error) { From fe9a2b6ad8a47041ffd32a7c32f5930f1ea51856 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 17:01:42 -0700 Subject: [PATCH 308/730] Small doc tweak --- src/lib/lazy-file.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts index 58d3e3a7fec..5aca7df2787 100644 --- a/src/lib/lazy-file.ts +++ b/src/lib/lazy-file.ts @@ -27,7 +27,7 @@ export interface LazyFileContent { * In normal usage you shouldn't have to manage the `ByteRange` yourself. The `slice()` method takes * care of creating new `LazyFile` instances with the correct range. * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/File) + * [MDN `File` Reference](https://developer.mozilla.org/en-US/docs/Web/API/File) */ export class LazyFile extends File { readonly #content: (Blob | Uint8Array)[] | LazyFileContent; From a7d525a1d63753785d57a542e484e5c499f8ca54 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 17:42:11 -0700 Subject: [PATCH 309/730] Add support for overriding file.lastModified --- CHANGELOG.md | 5 +++++ src/fs.ts | 22 ++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20db6fb73c8..ede2a473adc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # lazy-file CHANGELOG +## HEAD + +- Added support for `getFile(, { lastModified })` to override `file.lastModified` +- Export `GetFileOptions` interface from `lazy-file/fs` + ## v2.1.0 (Aug 24, 2024) - Added `getFile` helper to `lazy-file/fs` export for reading files from the local filesystem diff --git a/src/fs.ts b/src/fs.ts index 2fb5fb6e28d..69b550cdf20 100644 --- a/src/fs.ts +++ b/src/fs.ts @@ -4,6 +4,21 @@ import { lookup } from "mrmime"; import { LazyFileContent, LazyFile } from "./lib/lazy-file.js"; +export interface GetFileOptions { + /** + * Overrides the name of the file. Default is the name of the file on disk. + */ + name?: string; + /** + * Overrides the MIME type of the file. Default is determined by the file extension. + */ + type?: string; + /** + * Overrides the last modified timestamp of the file. Default is the file's last modified time. + */ + lastModified?: number; +} + /** * Returns a `File` from the local filesytem. * @@ -11,7 +26,7 @@ import { LazyFileContent, LazyFile } from "./lib/lazy-file.js"; */ export function getFile( filename: string, - { name = path.basename(filename), type = lookup(filename) } = {} + { name, type, lastModified }: GetFileOptions = {} ): File { let stats = fs.statSync(filename); @@ -26,7 +41,10 @@ export function getFile( } }; - return new LazyFile(content, name, { type, lastModified: stats.mtimeMs }); + return new LazyFile(content, name ?? path.basename(filename), { + type: type ?? lookup(filename), + lastModified: lastModified ?? stats.mtimeMs + }); } function readFile( From 235cec5b165e9bce9c6d052e03a46c5b13a7706a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 17:42:19 -0700 Subject: [PATCH 310/730] Version 2.2.0 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ede2a473adc..dcc53802968 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # lazy-file CHANGELOG -## HEAD +## v2.2.0 (Aug 24, 2024) - Added support for `getFile(, { lastModified })` to override `file.lastModified` - Export `GetFileOptions` interface from `lazy-file/fs` diff --git a/package.json b/package.json index 2cf37d0b898..3506b5e3f54 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/lazy-file", - "version": "2.1.0", + "version": "2.2.0", "description": "Lazy, streaming files for JavaScript", "author": "Michael Jackson ", "repository": { From 9c78e3dea97c36efc42236c9e356d640385c4770 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 17:46:04 -0700 Subject: [PATCH 311/730] Preserve file.lastModified in storage --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- src/lib/local-file-storage.ts | 9 ++++++++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index f1278d43d77..c8f22383d86 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,6 @@ "fs" ], "dependencies": { - "@mjackson/lazy-file": "^2.1.0" + "@mjackson/lazy-file": "^2.2.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 520817980d2..baa233b4c66 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@mjackson/lazy-file': - specifier: ^2.1.0 - version: 2.1.0 + specifier: ^2.2.0 + version: 2.2.0 devDependencies: '@types/node': specifier: ^20.14.10 @@ -37,8 +37,8 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} - '@mjackson/lazy-file@2.1.0': - resolution: {integrity: sha512-HpBZfJfxLP1m0ytaytKzSaURP9OH0YQ8t5kr3/qDdaRJbrXrLHK03xmWptMMrepCbpLiKNFApQd1wYKzid6ITw==} + '@mjackson/lazy-file@2.2.0': + resolution: {integrity: sha512-51M2TAL5eMZj5mh1e22/qBl4C5udViZqSBEqwiHSi1lTAixCp4YiAOV62VaTSqVp771OkmgNCPsh8/LpJ/A/Yw==} '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} @@ -234,7 +234,7 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - '@mjackson/lazy-file@2.1.0': + '@mjackson/lazy-file@2.2.0': dependencies: mrmime: 2.0.0 diff --git a/src/lib/local-file-storage.ts b/src/lib/local-file-storage.ts index c6d415665c2..61be93a5e85 100644 --- a/src/lib/local-file-storage.ts +++ b/src/lib/local-file-storage.ts @@ -52,6 +52,7 @@ export class LocalFileStorage implements FileStorage { await this.#metadata.set(key, { file: localFile.name, name: file.name, + mtime: file.lastModified, size: localFile.size, type: file.type }); @@ -62,7 +63,12 @@ export class LocalFileStorage implements FileStorage { if (metadata == null) return null; let filename = path.join(this.#dirname, metadata.file); - return getFile(filename, { name: metadata.name, type: metadata.type }); + + return getFile(filename, { + name: metadata.name, + type: metadata.type, + lastModified: metadata.mtime + }); } async remove(key: string): Promise { @@ -116,6 +122,7 @@ function randomFilename(): string { interface FileMetadata { file: string; name: string; + mtime: number; size: number; type: string; } From e32be0152ede67713760fbe61caebd3a4771b867 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 17:46:34 -0700 Subject: [PATCH 312/730] Add LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..717984c0442 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Michael Jackson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 6e029d951414184bfc0a1204e31fadc64c1acbd7 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 17:46:41 -0700 Subject: [PATCH 313/730] Add README.md --- README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000000..438cad5f308 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +# file-storage + +`file-storage` is a key/value interface for storing [`File` objects](https://developer.mozilla.org/en-US/docs/Web/API/File) in JavaScript. + +## Goals + +- Provide a `FileStorage` interface that works for various large object storage backends +- Simple, intuitive key/value API (like [Web Storage](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API), but for `File`s instead of strings) +- Support streaming file content to and from storage + +## Installation + +Install from [npm](https://www.npmjs.com/): + +```sh +npm install @mjackson/file-storage +``` + +## Usage + +```ts +import { LocalFileStorage } from "@mjackson/file-storage"; + +let storage = new LocalFileStorage("./user/files"); + +let file = new File(["hello world"], "hello.txt", { type: "text/plain" }); +let key = "hello-key"; + +// Put the file in storage. +await storage.set(key, file); + +// Then, sometime later... +let fileFromStorage = await storage.get(key); +// All of the original file's metadata is intact +fileFromStorage.name; // 'hello.txt' +fileFromStorage.type; // 'text/plain' + +// To remove from storage +await storage.remove(key); +``` + +## License + +See [LICENSE](https://github.com/mjackson/file-storage/blob/main/LICENSE) From ec14a7d7d6d71d3e796d1a84068eacc95a58e36d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 17:48:29 -0700 Subject: [PATCH 314/730] Add version script and CHANGELOG --- CHANGELOG.md | 5 +++++ scripts/version.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 CHANGELOG.md create mode 100644 scripts/version.js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000000..50f7e84b274 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# `file-storage` CHANGELOG + +## HEAD + +- Initial release diff --git a/scripts/version.js b/scripts/version.js new file mode 100644 index 00000000000..3c140ddd756 --- /dev/null +++ b/scripts/version.js @@ -0,0 +1,30 @@ +import * as cp from "node:child_process"; +import * as fs from "node:fs"; +import * as path from "node:path"; +import * as process from "node:process"; + +const __dirname = path.dirname(new URL(import.meta.url).pathname); +const packageVersion = process.env.npm_package_version; + +// Update CHANGELOG.md with the current version +let changelogPath = path.resolve(__dirname, "../CHANGELOG.md"); +let changelog = fs.readFileSync(changelogPath, "utf-8"); +let match = /^## HEAD\n/m.exec(changelog); +if (match) { + let today = new Date().toLocaleDateString("en-US", { + month: "short", + day: "numeric", + year: "numeric" + }); + + changelog = + changelog.slice(0, match.index) + + `## v${packageVersion} (${today})\n` + + changelog.slice(match.index + match[0].length); + + fs.writeFileSync(changelogPath, changelog); + cp.execSync("git add CHANGELOG.md"); +} else { + console.error('Could not find "## HEAD" in CHANGELOG.md'); + process.exit(1); +} From de2be284277f73d121d3479af7dc74b1bec83c89 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 17:48:55 -0700 Subject: [PATCH 315/730] Prep for release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c8f22383d86..017d4e9f2b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/file-storage", - "version": "0.1.0", + "version": "0.0.0", "description": "Key/value storage for JavaScript File objects", "author": "Michael Jackson ", "repository": { From 60aec412175315ddaa9ae71818bce59ad7a22955 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 17:53:54 -0700 Subject: [PATCH 316/730] Add publish script --- .github/workflows/publish.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000000..cbdc3b17796 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,32 @@ +name: Publish + +on: + push: + tags: + - v[0-9]* + +jobs: + build: + runs-on: ubuntu-latest + + permissions: + contents: write + id-token: write + + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '20.x' + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - run: pnpm install + + - name: Publish to npm + run: npm publish --provenance --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From e04eaa64fbc06e867d8e4f19ad4dd482773316ad Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 17:55:10 -0700 Subject: [PATCH 317/730] Version 0.1.0 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50f7e84b274..caa6aaae405 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # `file-storage` CHANGELOG -## HEAD +## v0.1.0 (Aug 24, 2024) - Initial release diff --git a/package.json b/package.json index 017d4e9f2b1..c8f22383d86 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/file-storage", - "version": "0.0.0", + "version": "0.1.0", "description": "Key/value storage for JavaScript File objects", "author": "Michael Jackson ", "repository": { From df57bdb0d351d8b7d263adf550581a5dc9de86c3 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 18:06:46 -0700 Subject: [PATCH 318/730] Move global types into src root --- src/{lib => }/global.d.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{lib => }/global.d.ts (100%) diff --git a/src/lib/global.d.ts b/src/global.d.ts similarity index 100% rename from src/lib/global.d.ts rename to src/global.d.ts From e8ea75a63d179f7db75d749a4835d68bc586d70b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 18:10:41 -0700 Subject: [PATCH 319/730] Update README --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 2fe1ab8cf99..00c07e00fe4 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,9 @@ ## Goals -The goals of this project are: - - Provide a JavaScript-y multipart parser that runs anywhere JavaScript runs - Support the entire spectrum of `multipart/*` message types -- Be fast enough to get the job done quickly while using as little memory as possible +- Stream everything and buffer as little as possible ## Installation From 5952aaafd59a593c383593b6ec1a3784f099f2ac Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 18:16:36 -0700 Subject: [PATCH 320/730] Update doc comments --- src/lib/form-data.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/form-data.ts b/src/lib/form-data.ts index 8956c891240..b457aa37d5d 100644 --- a/src/lib/form-data.ts +++ b/src/lib/form-data.ts @@ -1,7 +1,7 @@ import { isMultipartRequest, parseMultipartRequest, - type MultipartPart + MultipartPart } from "@mjackson/multipart-parser"; /** @@ -77,7 +77,7 @@ async function defaultFileUploadHandler(file: FileUpload): Promise { * * The major difference between this function and using the built-in `request.formData()` API is the * ability to customize the handling of file uploads. Instead of buffering the entire file in memory, - * the `handleFileUpload` function allows you to store the file on disk or in a cloud storage service. + * the `uploadHandler` allows you to store the file on disk or in a cloud storage service. */ export async function parseFormData( request: Request, From f8ea9c7327f39fe269f3ffff6f6d5f67a1f55054 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 18:16:54 -0700 Subject: [PATCH 321/730] Prep for release --- README.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 001392f708a..1d82c8c0dfe 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,13 @@ async function handleRequest(request: Request) { } ``` +## Related packages + +- [`multipart-parser`](https://github.com/mjackson/multipart-parser) - The parser used internally + for parsing `multipart/form-data` HTTP messages +- [`file-storage`](https://github.com/mjackson/file-storage) - A simple interface for storing + `FileUpload` objects you get from the parser + ## License See [LICENSE](https://github.com/mjackson/form-data-parser/blob/main/LICENSE) diff --git a/package.json b/package.json index 1dd1ea6d5c1..4ebce0a3dc4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/form-data-parser", - "version": "0.1.0", + "version": "0.0.0", "description": "A request.formData() wrapper with pluggable file upload handling", "author": "Michael Jackson ", "repository": { From 44d06ef329c4634f005a578cc9664b797b854a5c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 18:18:13 -0700 Subject: [PATCH 322/730] Version 0.1.0 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb132f2be2d..54806607959 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # form-data-parser CHANGELOG -## HEAD +## v0.1.0 (Aug 24, 2024) - Initial release diff --git a/package.json b/package.json index 4ebce0a3dc4..1dd1ea6d5c1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/form-data-parser", - "version": "0.0.0", + "version": "0.1.0", "description": "A request.formData() wrapper with pluggable file upload handling", "author": "Michael Jackson ", "repository": { From 5a1476b14f3ef36f5e0a3c4563be22386edaa5d7 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 18:25:57 -0700 Subject: [PATCH 323/730] Update README --- README.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/README.md b/README.md index 438cad5f308..0a09048001c 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,45 @@ fileFromStorage.type; // 'text/plain' await storage.remove(key); ``` +The `FileStorage` interface allows you to implement your own file storage for custom storage +backends: + +```ts +import { type FileStorage } from "@mjackson/file-storage"; + +class CustomFileStorage implements FileStorage { + /** + * Returns `true` if a file with the given key exists, `false` otherwise. + */ + has(key: string): boolean | Promise { + // ... + } + /** + * Puts a file in storage at the given key. + */ + set(key: string, file: File): void | Promise { + // ... + } + /** + * Returns the file with the given key, or `null` if no such key exists. + */ + get(key: string): File | null | Promise { + // ... + } + /** + * Removes the file with the given key from storage. + */ + remove(key: string): void | Promise { + // ... + } +} +``` + +## Related packages + +- [`lazy-file`](https://github.com/mjackson/lazy-file) - The streaming `File` implementation used + internally to stream files from storage + ## License See [LICENSE](https://github.com/mjackson/file-storage/blob/main/LICENSE) From 20fd5d364837b87c5aaab29fe7978f4769501d4a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 18:28:26 -0700 Subject: [PATCH 324/730] Update README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 82943c5eab0..2341b396b63 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,10 @@ let file = getFile("./path/to/file.json"); let json = JSON.parse(await file.text()); ``` +## Related Packages + +- [`file-storage`](https://github.com/mjackson/file-storage) - Uses `lazy-file/fs` internally to create streaming `File` objects from storage on disk + ## License See [LICENSE](https://github.com/mjackson/lazy-file/blob/main/LICENSE) From 712d9157014dfc35c1d1faebabc61ab5f0170345 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 18:29:43 -0700 Subject: [PATCH 325/730] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1d82c8c0dfe..0c890b58ec1 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ async function handleRequest(request: Request) { } ``` -## Related packages +## Related Packages - [`multipart-parser`](https://github.com/mjackson/multipart-parser) - The parser used internally for parsing `multipart/form-data` HTTP messages From bc3339c5877235aa8a69307bc8c35774dfe54b68 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 18:31:16 -0700 Subject: [PATCH 326/730] Update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0a09048001c..bb0e236f007 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,8 @@ class CustomFileStorage implements FileStorage { ## Related packages +- [`form-data-parser`](https://github.com/mjackson/form-data-parser) - Pairs well with this library + for storing `FileUpload` objects received in `multipart/form-data` requests - [`lazy-file`](https://github.com/mjackson/lazy-file) - The streaming `File` implementation used internally to stream files from storage From 3ed291df28a57e76b9d2e02bafd05d115e7b89ae Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 18:34:24 -0700 Subject: [PATCH 327/730] Update README --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 00c07e00fe4..7aff0dbc6dc 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,11 @@ I encourage you to run the benchmarks yourself. You'll probably get different re pnpm run bench ``` +## Related Packages + +- [`form-data-parser`](https://github.com/mjackson/form-data-parser) - Uses `multipart-parser` + internally to parse multipart requests and generate `FileUpload`s for storage + ## Credits Thanks to Jacob Ebey who gave me several code reviews on this project prior to publishing. From c4d1ed87e98b3457cf8f4b4f6e089cffa5d8d8f8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 18:35:50 -0700 Subject: [PATCH 328/730] Update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7aff0dbc6dc..eec486bd9f9 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,8 @@ pnpm run bench ## Related Packages +- [`headers`](https://github.com/mjackson/headers) - Used internally to parse HTTP headers and get + metadata (filename, content type) for each `MultipartPart` - [`form-data-parser`](https://github.com/mjackson/form-data-parser) - Uses `multipart-parser` internally to parse multipart requests and generate `FileUpload`s for storage From f7c65fd07d9c9c3a9c1e285e096af7b8f00f870e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 22:53:45 -0700 Subject: [PATCH 329/730] Update README --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2341b396b63..91f04c4b91d 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ ## Features -- Subclasses `File` so `lazyFile instanceof File` works +- Subclasses `File` so `LazyFile` instances can be used anywhere you'd normally expect a `File` - Accepts all the same content types as [`the File() constructor`](https://developer.mozilla.org/en-US/docs/Web/API/File/File) -- Supports [`Blob.slice(start, end)`](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice), even on streaming content +- Supports [`Blob.slice()`](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice), even on streaming content - Memory efficient! ## The Problem @@ -69,6 +69,8 @@ let file = getFile("./path/to/file.json"); let json = JSON.parse(await file.text()); ``` +`lazy-file/fs` also serves as a good reference implementation for how to use this library effectively. + ## Related Packages - [`file-storage`](https://github.com/mjackson/file-storage) - Uses `lazy-file/fs` internally to create streaming `File` objects from storage on disk From 0bbd0fc41ea0da942458d5bab62fd7a645053b33 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 22:54:15 -0700 Subject: [PATCH 330/730] Move controller.close() call Now the early controller.close() should work for buffers as well as blobs. --- src/lib/lazy-file.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts index 5aca7df2787..d8699a6767d 100644 --- a/src/lib/lazy-file.ts +++ b/src/lib/lazy-file.ts @@ -212,7 +212,6 @@ function streamContentArray( if (bytesRead >= end) { // We can stop reading now. - controller.close(); break; } } @@ -223,6 +222,11 @@ function streamContentArray( while (!hasPushed && index < content.length) { await pushPart(content[index++]); + + if (bytesRead >= end) { + controller.close(); + break; + } } } }); From cdf930c5bee3d1b6ec5f4f5c3136077fcad12f54 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 23:27:58 -0700 Subject: [PATCH 331/730] Update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 91f04c4b91d..397b7ce8a6f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # lazy-file -`lazy-file` is a lazy, streaming `File` implementation for JavaScript. It allows you to easily [create `File` objects](https://developer.mozilla.org/en-US/docs/Web/API/File) that defer reading their contents until needed, which is ideal for situations where a file's contents do not fit in memory all at once. +`lazy-file` is a lazy, streaming `File` implementation for JavaScript. It allows you to easily create [File objects](https://developer.mozilla.org/en-US/docs/Web/API/File) that defer reading their contents until needed, which is ideal for situations where a file's contents do not fit in memory all at once. ## Features @@ -11,7 +11,7 @@ ## The Problem -JavaScript's [`File` API](https://developer.mozilla.org/en-US/docs/Web/API/File) is useful, but it's not a great fit for streaming server environments where you don't want to buffer file contents. In particular, [the `File` constructor](https://developer.mozilla.org/en-US/docs/Web/API/File/File) requires the contents of a file to be supplied up front when the object is first created, like this: +JavaScript's [File API](https://developer.mozilla.org/en-US/docs/Web/API/File) is useful, but it's not a great fit for streaming server environments where you don't want to buffer file contents. In particular, [`the File() constructor`](https://developer.mozilla.org/en-US/docs/Web/API/File/File) requires the contents of a file to be supplied up front when the object is first created, like this: ```ts let file = new File(["hello world"], "hello.txt", { type: "text/plain" }); From 74f7381e4b626bac8e6f17821823e83933c19a1b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 23:36:51 -0700 Subject: [PATCH 332/730] Update README --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index eec486bd9f9..7ac38085c20 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,14 @@ - Parsing `multipart/mixed` messages (email attachments, API responses, etc.) - Parsing email messages with both plain text and HTML versions (`multipart/alternative`) -## Goals - -- Provide a JavaScript-y multipart parser that runs anywhere JavaScript runs -- Support the entire spectrum of `multipart/*` message types -- Stream everything and buffer as little as possible +## Features + +- Runs anywhere JavaScript runs (see [examples for Node.js, Bun, Deno, and Cloudflare + Workers](https://github.com/mjackson/multipart-parser/tree/main/examples)) +- Built on the standard [web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) +- Supports the entire spectrum of `multipart/*` message types +- Memory efficient and does not buffer anything in normal usage +- [As fast or faster than](https://github.com/mjackson/multipart-parser#benchmark) other multipart libraries ## Installation From cace2bc91b50567da3cd22d993ecd647db2164fa Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 23:40:49 -0700 Subject: [PATCH 333/730] Update README --- README.md | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 0c890b58ec1..d4b4f53b27c 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,13 @@ `form-data-parser` is a wrapper around `request.formData()` that provides pluggable support for file upload handling. This is useful in server contexts where large files should be streamed to disk or some cloud storage service like [AWS S3](https://aws.amazon.com/s3/) or [Cloudflare R2](https://www.cloudflare.com/developer-platform/r2/) instead of being buffered in memory. +## Features + +- Drop-in replacement for `request.formData()` with support for streaming file uploads +- Built on the standard [web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) and [File API](https://developer.mozilla.org/en-US/docs/Web/API/File) +- Does not buffer any content, minimal memory usage +- Automatically falls back to native `request.formData()` implementation for non-`multipart/form-data` requests + ## The Problem The web fetch API's built-in [`request.formData()` method](https://developer.mozilla.org/en-US/docs/Web/API/Request/formData) is not a great fit for server environments because it doesn't provide a way to stream file uploads. This means that when you call `request.formData()` in a server environment on a request that was submitted by a ``, any file uploads contained in the request are buffered in memory. For small files this may not be an issue, but it's a total non-starter for large files that exceed the server's memory capacity. @@ -20,29 +27,31 @@ npm install @mjackson/form-data-parser ```ts import { LocalFileStorage } from "@mjackson/file-storage"; -import { parseFormData } from "@mjackson/form-data-parser"; +import { type FileUpload, parseFormData } from "@mjackson/form-data-parser"; const fileStorage = new LocalFileStorage("/uploads/user-avatars"); -async function handleRequest(request: Request) { - let formData = await parseFormData(request, async fileUpload => { - // Is this file upload from the in our ? - if (fileUpload.fieldName === "user-avatar") { - let storageKey = `user-${user.id}-avatar`; - - // FileUpload objects are not meant to stick around for very long (they are - // streaming data from the request.body!) so we should store them as soon as - // possible. - await fileStorage.put(storageKey, fileUpload); - - // Return a File for the FormData object. This is a LazyFile that knows how - // to access the file's content if needed (using e.g. file.stream()) but - // waits until it is requested to actually read anything. - return fileStorage.get(storageKey); - } - - // Ignore any files we don't recognize the name of... - }); +async function uploadHandler(fileUpload: FileUpload) { + // Is this file upload from the field? + if (fileUpload.fieldName === "user-avatar") { + let storageKey = `user-${user.id}-avatar`; + + // FileUpload objects are not meant to stick around for very long (they are + // streaming data from the request.body!) so we should store them as soon as + // possible. + await fileStorage.put(storageKey, fileUpload); + + // Return a File for the FormData object. This is a LazyFile that knows how + // to access the file's content if needed (using e.g. file.stream()) but + // waits until it is requested to actually read anything. + return fileStorage.get(storageKey); + } + + // Ignore any files we don't recognize the name of... +} + +async function requestHandler(request: Request) { + let formData = await parseFormData(request, uploadHandler); let file = formData.get("user-avatar"); // File (LazyFile) file.name; // "my-avatar.jpg" (name of the file on the user's computer) From ab840e8328ff3cca2391da340018a44f0a3c9215 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 23:44:07 -0700 Subject: [PATCH 334/730] Update README --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bb0e236f007..aba1f241726 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ # file-storage -`file-storage` is a key/value interface for storing [`File` objects](https://developer.mozilla.org/en-US/docs/Web/API/File) in JavaScript. +`file-storage` is a key/value interface for storing [`File` objects](https://developer.mozilla.org/en-US/docs/Web/API/File) in JavaScript. Similar to how `localStorage` allows you to store key/value pairs of strings in the browser, `file-storage` allows you to store key/value pairs of files on the server. -## Goals +## Features -- Provide a `FileStorage` interface that works for various large object storage backends - Simple, intuitive key/value API (like [Web Storage](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API), but for `File`s instead of strings) +- A generic `FileStorage` interface that works for various large object storage backends (can be adapted to AWS S3, Cloudflare R2, etc.) - Support streaming file content to and from storage +- Preserves all `File` metadata including `file.name`, `file.type`, and `file.lastModified` ## Installation From 25d76193962440615417d03c7d6c66327ca3dca1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 24 Aug 2024 23:45:46 -0700 Subject: [PATCH 335/730] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ac38085c20..67a3172728a 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ - Built on the standard [web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) - Supports the entire spectrum of `multipart/*` message types - Memory efficient and does not buffer anything in normal usage -- [As fast or faster than](https://github.com/mjackson/multipart-parser#benchmark) other multipart libraries +- [As fast or faster than](https://github.com/mjackson/multipart-parser#benchmark) other popular multipart libraries ## Installation From 01d208779d3b9ee64cd863e8ca7e0bd0e88f18b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Xalambr=C3=AD?= Date: Thu, 22 Aug 2024 00:51:36 -0500 Subject: [PATCH 336/730] Move local and memory to separate exports --- package.json | 2 ++ src/file-storage.ts | 2 -- src/local.ts | 1 + src/memory.ts | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 src/local.ts create mode 100644 src/memory.ts diff --git a/package.json b/package.json index c8f22383d86..e29af077237 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,8 @@ "type": "module", "exports": { ".": "./dist/file-storage.js", + "./local": "./dist/local.js", + "./memory": "./dist/memory.js", "./package.json": "./package.json" }, "devDependencies": { diff --git a/src/file-storage.ts b/src/file-storage.ts index 7cb07072c63..d558de6cddc 100644 --- a/src/file-storage.ts +++ b/src/file-storage.ts @@ -1,3 +1 @@ export { type FileStorage } from "./lib/file-storage.js"; -export { LocalFileStorage } from "./lib/local-file-storage.js"; -export { MemoryFileStorage } from "./lib/memory-file-storage.js"; diff --git a/src/local.ts b/src/local.ts new file mode 100644 index 00000000000..6370d3aaa7e --- /dev/null +++ b/src/local.ts @@ -0,0 +1 @@ +export { LocalFileStorage } from "./lib/local-file-storage.js"; diff --git a/src/memory.ts b/src/memory.ts new file mode 100644 index 00000000000..c0724d15b45 --- /dev/null +++ b/src/memory.ts @@ -0,0 +1 @@ +export { MemoryFileStorage } from "./lib/memory-file-storage.js"; From 1159c7f5464fc0d4a0636b3912c48d5dd5cecacc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 25 Aug 2024 19:31:46 -0700 Subject: [PATCH 337/730] Add LazyBlob Also, some small breaking changes to LazyFile and improvements to bring it more in line with the spec. --- CHANGELOG.md | 9 ++ src/fs.ts | 25 ++-- src/lazy-file.ts | 8 +- src/lib/byte-range.ts | 4 +- src/lib/lazy-file.spec.ts | 56 +++---- src/lib/lazy-file.ts | 297 ++++++++++++++++++++++++++------------ 6 files changed, 258 insertions(+), 141 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcc53802968..e5de01e8d73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # lazy-file CHANGELOG +## HEAD + +- BREAKING: Do not accept regular string argument to `LazyFile`. This more closely matches `File` behavior +- BREAKING: Move 4th `LazyFile()` argument `range` into `options.range` +- BREAKING: Renamed `LazyFileContent` interface to `LazyContent` and `content.read()` => `content.stream()` +- Added `LazyBlob` (`Blob` subclass) as a complement to `LazyFile` +- Added `LazyBlobOptions` and `LazyFileOptions` interfaces (`endings` is not supported) +- Return a `name`-less `Blob` from `file.slice()` to more closely match native `File` behavior + ## v2.2.0 (Aug 24, 2024) - Added support for `getFile(, { lastModified })` to override `file.lastModified` diff --git a/src/fs.ts b/src/fs.ts index 69b550cdf20..75ce978fd14 100644 --- a/src/fs.ts +++ b/src/fs.ts @@ -2,7 +2,7 @@ import * as fs from "node:fs"; import * as path from "node:path"; import { lookup } from "mrmime"; -import { LazyFileContent, LazyFile } from "./lib/lazy-file.js"; +import { LazyContent, LazyFile } from "./lib/lazy-file.js"; export interface GetFileOptions { /** @@ -24,30 +24,27 @@ export interface GetFileOptions { * * [MDN `File` Reference](https://developer.mozilla.org/en-US/docs/Web/API/File) */ -export function getFile( - filename: string, - { name, type, lastModified }: GetFileOptions = {} -): File { +export function getFile(filename: string, options?: GetFileOptions): File { let stats = fs.statSync(filename); if (!stats.isFile()) { throw new Error(`Path "${filename}" is not a file`); } - let content: LazyFileContent = { + let content: LazyContent = { byteLength: stats.size, - read(start, end) { - return readFile(filename, start, end); + stream(start, end) { + return streamFile(filename, start, end); } }; - return new LazyFile(content, name ?? path.basename(filename), { - type: type ?? lookup(filename), - lastModified: lastModified ?? stats.mtimeMs + return new LazyFile(content, options?.name ?? path.basename(filename), { + type: options?.type ?? lookup(filename), + lastModified: options?.lastModified ?? stats.mtimeMs }); } -function readFile( +function streamFile( filename: string, start = 0, end = Infinity @@ -61,7 +58,9 @@ function readFile( if (done) { controller.close(); } else { - controller.enqueue(value); + controller.enqueue( + new Uint8Array(value.buffer, value.byteOffset, value.byteLength) + ); } } }); diff --git a/src/lazy-file.ts b/src/lazy-file.ts index 549c25cde07..458db31e53a 100644 --- a/src/lazy-file.ts +++ b/src/lazy-file.ts @@ -1,2 +1,8 @@ export { type ByteRange, getByteLength, getIndexes } from "./lib/byte-range.js"; -export { type LazyFileContent, LazyFile } from "./lib/lazy-file.js"; +export { + type LazyContent, + type LazyBlobOptions, + LazyBlob, + type LazyFileOptions, + LazyFile +} from "./lib/lazy-file.js"; diff --git a/src/lib/byte-range.ts b/src/lib/byte-range.ts index af36fa06c3d..741e2afed1b 100644 --- a/src/lib/byte-range.ts +++ b/src/lib/byte-range.ts @@ -1,12 +1,12 @@ export interface ByteRange { /** * The start index of the range (inclusive). If this number is negative, it represents an offset - * from the end of the buffer. + * from the end of the content. */ start: number; /** * The end index of the range (exclusive). If this number is negative, it represents an offset - * from the end of the buffer. `Infinity` represents the end of the buffer. + * from the end of the content. `Infinity` represents the end of the content. */ end: number; } diff --git a/src/lib/lazy-file.spec.ts b/src/lib/lazy-file.spec.ts index 123716da22f..8228e9328f5 100644 --- a/src/lib/lazy-file.spec.ts +++ b/src/lib/lazy-file.spec.ts @@ -1,13 +1,13 @@ import * as assert from "node:assert/strict"; import { describe, it } from "node:test"; -import { LazyFileContent, LazyFile } from "./lazy-file.js"; +import { LazyContent, LazyFile } from "./lazy-file.js"; -function createLazyContent(value = ""): LazyFileContent { +function createLazyContent(value = ""): LazyContent { let buffer = new TextEncoder().encode(value); return { byteLength: buffer.byteLength, - read() { + stream() { return new ReadableStream({ start(controller) { controller.enqueue(buffer); @@ -32,12 +32,6 @@ describe("LazyFile", () => { assert.equal(file.lastModified, now); }); - it("can be initialized with a string as the content", async () => { - let file = new LazyFile("hello world", "hello.txt", { type: "text/plain" }); - assert.equal(file.size, 11); - assert.equal("hello world", await file.text()); - }); - it("can be initialized with a [Blob] as the content", async () => { let content = [new Blob(["hello world"], { type: "text/plain" })]; let file = new LazyFile(content, "hello.txt", { type: "text/plain" }); @@ -47,7 +41,7 @@ describe("LazyFile", () => { it("can be initialized with another LazyFile as the content", async () => { let content = [ - new LazyFile("hello world", "hello.txt", { type: "text/plain" }) + new LazyFile(["hello world"], "hello.txt", { type: "text/plain" }) ]; let file = new LazyFile(content, "hello.txt", { type: "text/plain" }); assert.equal(file.size, 11); @@ -55,22 +49,20 @@ describe("LazyFile", () => { }); it("can be initialized with multiple Blobs and strings as the content and can slice them correctly", async () => { - let content = [ + let parts = [ new Blob([" hello "], { type: "text/plain" }), "world", new Blob(["!", " "], { type: "text/plain" }), "extra stuff" ]; - let file = new LazyFile(content, "hello.txt", { type: "text/plain" }); + let file = new LazyFile(parts, "hello.txt", { type: "text/plain" }); assert.equal(file.size, 27); - assert.equal("hello world!", await file.slice(2, -13, "text/plain").text()); + assert.equal(await file.slice(2, -13).text(), "hello world!"); }); it("returns the file's contents as a stream", async () => { let content = createLazyContent("hello world"); - let file = new LazyFile(content, "hello.txt", { - type: "text/plain" - }); + let file = new LazyFile(content, "hello.txt", { type: "text/plain" }); let decoder = new TextDecoder(); let result = ""; @@ -92,14 +84,6 @@ describe("LazyFile", () => { }); describe("slice()", () => { - it("returns a file with the same name", () => { - let file = new LazyFile("hello world", "hello.txt", { - type: "text/plain" - }); - let slice = file.slice(0, 5); - assert.equal(slice.name, file.name); - }); - it("returns a file with the same size as the original when slicing from 0 to the end", () => { let file = new LazyFile(createLazyContent("hello world"), "hello.txt", { type: "text/plain" @@ -109,7 +93,7 @@ describe("LazyFile", () => { }); it('returns a file with size 0 when the "start" index is greater than the content length', () => { - let file = new LazyFile("hello world", "hello.txt", { + let file = new LazyFile(["hello world"], "hello.txt", { type: "text/plain" }); let slice = file.slice(100); @@ -117,52 +101,52 @@ describe("LazyFile", () => { }); it('returns a file with size 0 when the "start" index is greater than the "end" index', () => { - let file = new LazyFile("hello world", "hello.txt", { + let file = new LazyFile(["hello world"], "hello.txt", { type: "text/plain" }); let slice = file.slice(5, 0); assert.equal(slice.size, 0); }); - it("calls content.read() with the correct range", t => { + it("calls content.stream() with the correct range", t => { let content = createLazyContent("X".repeat(100)); - let read = t.mock.method(content, "read"); + let read = t.mock.method(content, "stream"); let file = new LazyFile(content, "example.txt", { type: "text/plain" }); file.slice(10, 20).stream(); assert.equal(read.mock.calls.length, 1); assert.deepEqual(read.mock.calls[0].arguments, [10, 20]); }); - it('calls content.read() with the correct range when slicing a file with a negative "start" index', t => { + it('calls content.stream() with the correct range when slicing a file with a negative "start" index', t => { let content = createLazyContent("X".repeat(100)); - let read = t.mock.method(content, "read"); + let read = t.mock.method(content, "stream"); let file = new LazyFile(content, "example.txt", { type: "text/plain" }); file.slice(-10).stream(); assert.equal(read.mock.calls.length, 1); assert.deepEqual(read.mock.calls[0].arguments, [90, 100]); }); - it('calls content.read() with the correct range when slicing a file with a negative "end" index', t => { + it('calls content.stream() with the correct range when slicing a file with a negative "end" index', t => { let content = createLazyContent("X".repeat(100)); - let read = t.mock.method(content, "read"); + let read = t.mock.method(content, "stream"); let file = new LazyFile(content, "example.txt", { type: "text/plain" }); file.slice(0, -10).stream(); assert.equal(read.mock.calls.length, 1); assert.deepEqual(read.mock.calls[0].arguments, [0, 90]); }); - it('calls content.read() with the correct range when slicing a file with negative "start" and "end" indexes', t => { + it('calls content.stream() with the correct range when slicing a file with negative "start" and "end" indexes', t => { let content = createLazyContent("X".repeat(100)); - let read = t.mock.method(content, "read"); + let read = t.mock.method(content, "stream"); let file = new LazyFile(content, "example.txt", { type: "text/plain" }); file.slice(-20, -10).stream(); assert.equal(read.mock.calls.length, 1); assert.deepEqual(read.mock.calls[0].arguments, [80, 90]); }); - it('calls content.read() with the correct range when slicing a file with a "start" index greater than the "end" index', t => { + it('calls content.stream() with the correct range when slicing a file with a "start" index greater than the "end" index', t => { let content = createLazyContent("X".repeat(100)); - let read = t.mock.method(content, "read"); + let read = t.mock.method(content, "stream"); let file = new LazyFile(content, "example.txt", { type: "text/plain" }); file.slice(20, 10).stream(); assert.equal(read.mock.calls.length, 1); diff --git a/src/lib/lazy-file.ts b/src/lib/lazy-file.ts index d8699a6767d..3664dda0306 100644 --- a/src/lib/lazy-file.ts +++ b/src/lib/lazy-file.ts @@ -1,18 +1,118 @@ import { ByteRange, getByteLength, getIndexes } from "./byte-range.js"; /** - * A streaming interface for file content. + * A streaming interface for blob/file content. */ -export interface LazyFileContent { +export interface LazyContent { /** * The total length of the content. */ byteLength: number; /** - * Returns a stream that can be used to read the content, optionally within a given `start` - * (inclusive) and `end` (exclusive) index. + * Returns a stream that can be used to read the content. When given, the `start` index is + * inclusive indicating the index of the first byte to read. The `end` index is exclusive + * indicating the index of the first byte not to read. */ - read(start?: number, end?: number): ReadableStream; + stream(start?: number, end?: number): ReadableStream; +} + +export interface LazyBlobOptions { + /** + * The range of bytes to include from the content. If not specified, all content is included. + */ + range?: ByteRange; + /** + * The MIME type of the content. The default is an empty string. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob#type) + */ + type?: string; +} + +/** + * A `Blob` that may be backed by a stream of data. This is useful for working with large blobs that + * would be impractical to load into memory all at once. + * + * This class is an extension of JavaScript's built-in `Blob` class with the following additions: + * + * - The constructor may accept a `LazyContent` object instead of a `BlobPart[]` array + * - The constructor may accept a `range` in the options to specify a subset of the content + * + * In normal usage you shouldn't have to specify the `range` yourself. The `slice()` method + * automatically takes care of creating new `LazyBlob` instances with the correct range. + * + * [MDN `Blob` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob) + */ +export class LazyBlob extends Blob { + readonly #content: BlobContent; + + constructor(parts: BlobPart[] | LazyContent, options?: LazyBlobOptions) { + super([], options); + this.#content = new BlobContent(parts, options); + } + + /** + * Returns the blob's contents as an `ArrayBuffer`. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer) + */ + async arrayBuffer(): Promise { + return this.#content.arrayBuffer(); + } + + /** + * Returns the blob's contents as a byte array. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/bytes) + */ + async bytes(): Promise { + return this.#content.bytes(); + } + + /** + * The size of the blob in bytes. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/size) + */ + get size(): number { + return this.#content.size; + } + + /** + * Returns a new `Blob` that contains the data in the specified range. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) + */ + slice(start?: number, end?: number, contentType?: string): Blob { + return this.#content.slice(start, end, contentType); + } + + /** + * Returns a stream that can be used to read the blob's contents. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/stream) + */ + stream(): ReadableStream { + return this.#content.stream(); + } + + /** + * Returns the blob's contents as a string. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/text) + */ + async text(): Promise { + return this.#content.text(); + } +} + +export interface LazyFileOptions extends LazyBlobOptions { + /** + * The last modified timestamp of the file in milliseconds. Defaults to `Date.now()`. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/File/File#lastmodified) + */ + lastModified?: number; } /** @@ -21,35 +121,96 @@ export interface LazyFileContent { * * This class is an extension of JavaScript's built-in `File` class with the following additions: * - * - The constructor may accept a regular string or a `LazyFileContent` object - * - The constructor may accept a `ByteRange` to represent a subset of the file's content + * - The constructor may accept a `LazyContent` object instead of a `BlobPart[]` array + * - The constructor may accept a `range` in the options to specify a subset of the content * - * In normal usage you shouldn't have to manage the `ByteRange` yourself. The `slice()` method takes - * care of creating new `LazyFile` instances with the correct range. + * In normal usage you shouldn't have to specify the `range` yourself. The `slice()` method + * automatically takes care of creating new `LazyBlob` instances with the correct range. * * [MDN `File` Reference](https://developer.mozilla.org/en-US/docs/Web/API/File) */ export class LazyFile extends File { - readonly #content: (Blob | Uint8Array)[] | LazyFileContent; - readonly #contentSize: number; - readonly #range?: ByteRange; + readonly #content: BlobContent; constructor( - content: BlobPart[] | string | LazyFileContent, + parts: BlobPart[] | LazyContent, name: string, - props?: FilePropertyBag, - range?: ByteRange + options?: LazyFileOptions ) { - super([], name, props); + super([], name, options); + this.#content = new BlobContent(parts, options); + } + + /** + * Returns the file's content as an `ArrayBuffer`. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer) + */ + async arrayBuffer(): Promise { + return this.#content.arrayBuffer(); + } - if (Array.isArray(content)) { - this.#content = []; - this.#contentSize = 0; + /** + * Returns the file's contents as a byte array. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/bytes) + */ + async bytes(): Promise { + return this.#content.bytes(); + } + + /** + * The size of the file in bytes. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/size) + */ + get size(): number { + return this.#content.size; + } + + /** + * Returns a new `Blob` that contains the data in the specified range. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) + */ + slice(start?: number, end?: number, contentType?: string): Blob { + return this.#content.slice(start, end, contentType); + } + + /** + * Returns a stream that can be used to read the file's contents. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/stream) + */ + stream(): ReadableStream { + return this.#content.stream(); + } + + /** + * Returns the file's contents as a string. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/text) + */ + async text(): Promise { + return this.#content.text(); + } +} + +class BlobContent { + readonly source: (Blob | Uint8Array)[] | LazyContent; + readonly totalSize: number; + readonly range?: ByteRange; + readonly type: string; - for (let part of content) { + constructor(parts: BlobPart[] | LazyContent, options?: LazyBlobOptions) { + if (Array.isArray(parts)) { + this.source = []; + this.totalSize = 0; + + for (let part of parts) { if (part instanceof Blob) { - this.#content.push(part); - this.#contentSize += part.size; + this.source.push(part); + this.totalSize += part.size; } else { let array: Uint8Array; if (typeof part === "string") { @@ -63,36 +224,24 @@ export class LazyFile extends File { } else { array = new Uint8Array(part); } - this.#content.push(array); - this.#contentSize += array.byteLength; + + this.source.push(array); + this.totalSize += array.byteLength; } } - } else if (typeof content === "string") { - let array = new TextEncoder().encode(content); - this.#content = [array]; - this.#contentSize = array.byteLength; } else { - this.#content = content; - this.#contentSize = content.byteLength; + this.source = parts; + this.totalSize = parts.byteLength; } - this.#range = range; + this.range = options?.range; + this.type = options?.type ?? ""; } - /** - * Returns the file's contents as an array buffer. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer) - */ async arrayBuffer(): Promise { return (await this.bytes()).buffer; } - /** - * Returns the file's contents as a byte array. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/bytes) - */ async bytes(): Promise { let result = new Uint8Array(this.size); @@ -105,65 +254,35 @@ export class LazyFile extends File { return result; } - /** - * The size of the file in bytes. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/size) - */ get size(): number { - return this.#range != null - ? getByteLength(this.#range, this.#contentSize) - : this.#contentSize; + return this.range != null + ? getByteLength(this.range, this.totalSize) + : this.totalSize; } - /** - * Returns a new file that contains the data in the specified range. - * - * Note: The built-in Blob constructor does not support streaming content or provide a way to - * store and retrieve the content range, so this method differs slightly from the native - * `Blob.slice()`. Instead of returning a name-less `Blob`, this method returns a new `LazyFile` - * (which is a `Blob`) of the same name with the range applied. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) - */ - slice(start = 0, end?: number, contentType = ""): LazyFile { - let range: ByteRange | undefined; - if (this.#range != null) { - // file.slice().slice() is additive - range = { - start: this.#range.start + start, - end: this.#range.end + (end ?? 0) - }; - } else { - range = { start, end: end ?? this.size }; - } + slice(start = 0, end?: number, contentType = ""): LazyBlob { + let range: ByteRange = + this.range != null + ? // file.slice().slice() is additive + { start: this.range.start + start, end: this.range.end + (end ?? 0) } + : { start, end: end ?? this.size }; - return new LazyFile(this.#content, this.name, { type: contentType }, range); + return new LazyBlob(this.source, { range, type: contentType }); } - /** - * Returns a stream that can be used to read the file's contents. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/stream) - */ stream(): ReadableStream { - if (this.#range != null) { - let [start, end] = getIndexes(this.#range, this.#contentSize); - return Array.isArray(this.#content) - ? streamContentArray(this.#content, start, end) - : this.#content.read(start, end); + if (this.range != null) { + let [start, end] = getIndexes(this.range, this.totalSize); + return Array.isArray(this.source) + ? streamContentArray(this.source, start, end) + : this.source.stream(start, end); } - return Array.isArray(this.#content) - ? streamContentArray(this.#content) - : this.#content.read(); + return Array.isArray(this.source) + ? streamContentArray(this.source) + : this.source.stream(); } - /** - * Returns the file's contents as a string. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/text) - */ async text(): Promise { return new TextDecoder("utf-8").decode(await this.bytes()); } From 14c1a7287b6f2ed40654a6a8826289770f11854d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 25 Aug 2024 23:38:56 -0700 Subject: [PATCH 338/730] Update README --- README.md | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 397b7ce8a6f..5ef27f2b62b 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ # lazy-file -`lazy-file` is a lazy, streaming `File` implementation for JavaScript. It allows you to easily create [File objects](https://developer.mozilla.org/en-US/docs/Web/API/File) that defer reading their contents until needed, which is ideal for situations where a file's contents do not fit in memory all at once. +`lazy-file` is a lazy, streaming `Blob`/`File` implementation for JavaScript. + +It allows you to easily create [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) and [File](https://developer.mozilla.org/en-US/docs/Web/API/File) objects that defer reading their contents until needed, which is ideal for situations where a file's contents do not fit in memory all at once. When file contents are read, they are streamed to avoid buffering. ## Features -- Subclasses `File` so `LazyFile` instances can be used anywhere you'd normally expect a `File` -- Accepts all the same content types as [`the File() constructor`](https://developer.mozilla.org/en-US/docs/Web/API/File/File) +- `LazyBlob extends Blob` and `LazyFile extends File` so instances can be used anywhere you'd normally expect a regular `Blob`/`File` +- Accepts all the same content types as the original [`Blob()`](https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob) and [`File()`](https://developer.mozilla.org/en-US/docs/Web/API/File/File) constructors - Supports [`Blob.slice()`](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice), even on streaming content - Memory efficient! @@ -17,7 +19,7 @@ JavaScript's [File API](https://developer.mozilla.org/en-US/docs/Web/API/File) i let file = new File(["hello world"], "hello.txt", { type: "text/plain" }); ``` -A `LazyFile` improves this model by accepting an additional content type in its constructor: `LazyFileContent`. All other `File` functionality works as you'd expect. +A `LazyFile` improves this model by accepting an additional content type in its constructor: `LazyContent`. All other `File` functionality works as you'd expect. ## Installation @@ -32,14 +34,14 @@ npm install @mjackson/lazy-file The low-level API can be used to create a `File` that streams content from anywhere: ```ts -import { type LazyFileContent, LazyFile } from "@mjackson/lazy-file"; +import { type LazyContent, LazyFile } from "@mjackson/lazy-file"; -let content: LazyFileContent = { +let content: LazyContent = { // The total length of this file in bytes. byteLength: 100000, - // A "reader" function that provides a stream of data for the file contents, + // A function that provides a stream of data for the file contents, // beginning at the `start` index and ending at `end`. - read(start, end) { + stream(start, end) { // ... read the file contents from somewhere and return a ReadableStream return new ReadableStream({ start(controller) { @@ -56,7 +58,7 @@ file.name; // "example.txt" file.type; // "text/plain" ``` -`lazy-file` also ships with a `lazy-file/fs` export that makes it easy to get a (lazy!) `File` object from the local filesystem. These objects are very lightweight and do not attempt to actually read any data from disk until needed. +The `lazy-file/fs` export provides a `getFile(filename)` function that allows you to create `File` objects from files on the local filesystem. These objects are lightweight and do not attempt to actually read from the file on disk until contents are requested. ```ts import { getFile } from "@mjackson/lazy-file/fs"; @@ -67,6 +69,12 @@ let file = getFile("./path/to/file.json"); // Data is read when you call file.text() (or any of the other Blob methods, like file.bytes(), // file.stream(), etc.) let json = JSON.parse(await file.text()); + +let imageFile = getFile("./path/to/image.jpg"); + +// Get a LazyBlob that omits the first 100 bytes of the file. This could be useful for serving +// HTTP Range requests. +let blob = imageFile.slice(100); ``` `lazy-file/fs` also serves as a good reference implementation for how to use this library effectively. From 25ac6727570102f00a26137d89fc6230d1c06d82 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 25 Aug 2024 23:39:02 -0700 Subject: [PATCH 339/730] Version 3.0.0 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5de01e8d73..bc862ae7709 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # lazy-file CHANGELOG -## HEAD +## v3.0.0 (Aug 25, 2024) - BREAKING: Do not accept regular string argument to `LazyFile`. This more closely matches `File` behavior - BREAKING: Move 4th `LazyFile()` argument `range` into `options.range` diff --git a/package.json b/package.json index 3506b5e3f54..e55109904f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/lazy-file", - "version": "2.2.0", + "version": "3.0.0", "description": "Lazy, streaming files for JavaScript", "author": "Michael Jackson ", "repository": { From 15347a04eb89dad3dc791e58e875404e0c02b147 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 26 Aug 2024 00:03:47 -0700 Subject: [PATCH 340/730] No need to store size in metadata --- src/lib/local-file-storage.spec.ts | 7 ++++++- src/lib/local-file-storage.ts | 20 +++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/lib/local-file-storage.spec.ts b/src/lib/local-file-storage.spec.ts index af1a3b9a3eb..7543cba07ac 100644 --- a/src/lib/local-file-storage.spec.ts +++ b/src/lib/local-file-storage.spec.ts @@ -16,7 +16,11 @@ describe("LocalFileStorage", () => { it("stores and retrieves files", async () => { let storage = new LocalFileStorage(directory); - let file = new File(["Hello, world!"], "hello.txt", { type: "text/plain" }); + let lastModified = Date.now(); + let file = new File(["Hello, world!"], "hello.txt", { + type: "text/plain", + lastModified + }); await storage.set("hello", file); @@ -27,6 +31,7 @@ describe("LocalFileStorage", () => { assert.ok(retrieved); assert.equal(retrieved.name, "hello.txt"); assert.equal(retrieved.type, "text/plain"); + assert.equal(retrieved.lastModified, lastModified); assert.equal(retrieved.size, 13); let text = await retrieved.text(); diff --git a/src/lib/local-file-storage.ts b/src/lib/local-file-storage.ts index 61be93a5e85..9b480acf362 100644 --- a/src/lib/local-file-storage.ts +++ b/src/lib/local-file-storage.ts @@ -47,14 +47,13 @@ export class LocalFileStorage implements FileStorage { } async set(key: string, file: File): Promise { - let localFile = await storeFile(this.#dirname, file); + let storedFile = await storeFile(this.#dirname, file); await this.#metadata.set(key, { - file: localFile.name, + file: storedFile, name: file.name, - mtime: file.lastModified, - size: localFile.size, - type: file.type + type: file.type, + mtime: file.lastModified }); } @@ -89,12 +88,12 @@ export class LocalFileStorage implements FileStorage { } } -async function storeFile(dirname: string, file: File): Promise { - let filename = path.join(dirname, randomFilename()); +async function storeFile(dirname: string, file: File): Promise { + let filename = randomFilename(); let handle: fsp.FileHandle; try { - handle = await fsp.open(filename, "w"); + handle = await fsp.open(path.join(dirname, filename), "w"); } catch (error) { if ((error as NodeJS.ErrnoException).code === "EEXIST") { // Try again with a different filename @@ -112,7 +111,7 @@ async function storeFile(dirname: string, file: File): Promise { await handle.close(); } - return getFile(filename); + return filename; } function randomFilename(): string { @@ -122,9 +121,8 @@ function randomFilename(): string { interface FileMetadata { file: string; name: string; - mtime: number; - size: number; type: string; + mtime: number; } class FileMetadataIndex { From 5e210ec37012f2c323a94048cb53b817640aef07 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 26 Aug 2024 00:08:37 -0700 Subject: [PATCH 341/730] Update CHANGELOG --- CHANGELOG.md | 5 +++++ README.md | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index caa6aaae405..c2ff54318b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # `file-storage` CHANGELOG +## HEAD + +- Moved `LocalFileStorage` to `file-storage/local` export +- Moved `MemoryFileStorage` to `file-storage/memory` export + ## v0.1.0 (Aug 24, 2024) - Initial release diff --git a/README.md b/README.md index aba1f241726..cd06007ed36 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ npm install @mjackson/file-storage ## Usage ```ts -import { LocalFileStorage } from "@mjackson/file-storage"; +import { LocalFileStorage } from "@mjackson/file-storage/local"; let storage = new LocalFileStorage("./user/files"); @@ -40,8 +40,7 @@ fileFromStorage.type; // 'text/plain' await storage.remove(key); ``` -The `FileStorage` interface allows you to implement your own file storage for custom storage -backends: +The `FileStorage` interface allows you to implement your own file storage for custom storage backends: ```ts import { type FileStorage } from "@mjackson/file-storage"; From e00b7e1b99a5295e40825f215f91ede961e53ae2 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 26 Aug 2024 00:08:43 -0700 Subject: [PATCH 342/730] Version 0.2.0 --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2ff54318b5..318cb897c33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # `file-storage` CHANGELOG -## HEAD +## v0.2.0 (Aug 26, 2024) - Moved `LocalFileStorage` to `file-storage/local` export - Moved `MemoryFileStorage` to `file-storage/memory` export diff --git a/package.json b/package.json index e29af077237..da3a6e057cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/file-storage", - "version": "0.1.0", + "version": "0.2.0", "description": "Key/value storage for JavaScript File objects", "author": "Michael Jackson ", "repository": { From 59982a332c4cb10e0711e614f540d3a4bcfb556f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 26 Aug 2024 00:10:17 -0700 Subject: [PATCH 343/730] Update README --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d4b4f53b27c..49ac4730a2e 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ npm install @mjackson/form-data-parser ## Usage ```ts -import { LocalFileStorage } from "@mjackson/file-storage"; +import { LocalFileStorage } from "@mjackson/file-storage/local"; import { type FileUpload, parseFormData } from "@mjackson/form-data-parser"; const fileStorage = new LocalFileStorage("/uploads/user-avatars"); @@ -62,10 +62,8 @@ async function requestHandler(request: Request) { ## Related Packages -- [`multipart-parser`](https://github.com/mjackson/multipart-parser) - The parser used internally - for parsing `multipart/form-data` HTTP messages -- [`file-storage`](https://github.com/mjackson/file-storage) - A simple interface for storing - `FileUpload` objects you get from the parser +- [`multipart-parser`](https://github.com/mjackson/multipart-parser) - The parser used internally for parsing `multipart/form-data` HTTP messages +- [`file-storage`](https://github.com/mjackson/file-storage) - A simple interface for storing `FileUpload` objects you get from the parser ## License From 8f059a02ce958dc842fa32057e28bc45bf6cb4f8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 26 Aug 2024 00:46:23 -0700 Subject: [PATCH 344/730] Update README --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5ef27f2b62b..6b1c49fee0d 100644 --- a/README.md +++ b/README.md @@ -63,17 +63,18 @@ The `lazy-file/fs` export provides a `getFile(filename)` function that allows yo ```ts import { getFile } from "@mjackson/lazy-file/fs"; -// No data is read at this point, it's just a reference to a file on the local filesystem. +// No data is read at this point, it's just a reference to a +// file on the local filesystem. let file = getFile("./path/to/file.json"); -// Data is read when you call file.text() (or any of the other Blob methods, like file.bytes(), -// file.stream(), etc.) +// Data is read when you call file.text() (or any of the +// other Blob methods, like file.bytes(), file.stream(), etc.) let json = JSON.parse(await file.text()); let imageFile = getFile("./path/to/image.jpg"); -// Get a LazyBlob that omits the first 100 bytes of the file. This could be useful for serving -// HTTP Range requests. +// Get a LazyBlob that omits the first 100 bytes of the file. +// This could be useful for serving HTTP Range requests. let blob = imageFile.slice(100); ``` From df75f59507fa0e6e47add8a95f0c9a2f33f7527c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 26 Aug 2024 09:20:19 -0700 Subject: [PATCH 345/730] Update README --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6b1c49fee0d..19e05766d9a 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,10 @@ It allows you to easily create [Blob](https://developer.mozilla.org/en-US/docs/W ## Features +- Deferred loading of blob/file contents to minimize memory usage - `LazyBlob extends Blob` and `LazyFile extends File` so instances can be used anywhere you'd normally expect a regular `Blob`/`File` - Accepts all the same content types as the original [`Blob()`](https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob) and [`File()`](https://developer.mozilla.org/en-US/docs/Web/API/File/File) constructors - Supports [`Blob.slice()`](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice), even on streaming content -- Memory efficient! ## The Problem @@ -19,7 +19,16 @@ JavaScript's [File API](https://developer.mozilla.org/en-US/docs/Web/API/File) i let file = new File(["hello world"], "hello.txt", { type: "text/plain" }); ``` -A `LazyFile` improves this model by accepting an additional content type in its constructor: `LazyContent`. All other `File` functionality works as you'd expect. +A `LazyFile` improves this model by accepting an additional content type in its constructor: `LazyContent`. + +```ts +let lazyContent: LazyContent = { + /* See below for usage */ +}; +let file = new File(lazyContent, "hello.txt", { type: "text/plain" }); +``` + +All other `File` functionality works as you'd expect. ## Installation From 2f6085b13557fd628596adf576ae9b90520ab509 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 26 Aug 2024 13:11:30 -0700 Subject: [PATCH 346/730] Update README --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cd06007ed36..75663f3b40e 100644 --- a/README.md +++ b/README.md @@ -73,12 +73,10 @@ class CustomFileStorage implements FileStorage { } ``` -## Related packages +## Related Packages -- [`form-data-parser`](https://github.com/mjackson/form-data-parser) - Pairs well with this library - for storing `FileUpload` objects received in `multipart/form-data` requests -- [`lazy-file`](https://github.com/mjackson/lazy-file) - The streaming `File` implementation used - internally to stream files from storage +- [`form-data-parser`](https://github.com/mjackson/form-data-parser) - Pairs well with this library for storing `FileUpload` objects received in `multipart/form-data` requests +- [`lazy-file`](https://github.com/mjackson/lazy-file) - The streaming `File` implementation used internally to stream files from storage ## License From 757805fe576b0389543a7d70617317dbacea073f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 26 Aug 2024 17:24:26 -0700 Subject: [PATCH 347/730] Initial commit, monorepo baby --- .gitignore | 5 +++++ package.json | 8 ++++++++ pnpm-lock.yaml | 9 +++++++++ pnpm-workspace.yaml | 2 ++ 4 files changed, 24 insertions(+) create mode 100644 .gitignore create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..c40c95a61dd --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +**/.tsimp/ +**/dist/ +**/node_modules/ + +**/*.tsbuildinfo diff --git a/package.json b/package.json new file mode 100644 index 00000000000..2ed19846431 --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "name": "remix-the-web", + "private": true, + "scripts": { + "clean": "git clean -fdX ." + }, + "packageManager": "pnpm@9.9.0" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000000..9b60ae1782d --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,9 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 00000000000..924b55f42e9 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - packages/* From 51a4f62dac85b7f766cc49a39f6b151c87343a19 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 16:24:22 -0700 Subject: [PATCH 348/730] Move lazy-file into packages dir --- .github/workflows/publish.yml | 32 -- .gitignore | 5 - .../lazy-file/CHANGELOG.md | 0 LICENSE => packages/lazy-file/LICENSE | 0 README.md => packages/lazy-file/README.md | 0 .../lazy-file/package.json | 13 +- {src => packages/lazy-file/src}/fs.ts | 0 {src => packages/lazy-file/src}/global.d.ts | 0 {src => packages/lazy-file/src}/lazy-file.ts | 0 .../lazy-file/src}/lib/byte-range.spec.ts | 0 .../lazy-file/src}/lib/byte-range.ts | 0 .../lazy-file/src}/lib/lazy-file.spec.ts | 0 .../lazy-file/src}/lib/lazy-file.ts | 0 .../lazy-file/tsconfig.json | 0 .../lazy-file/tsconfig.lib.json | 0 .../lazy-file/tsconfig.spec.json | 0 pnpm-lock.yaml | 397 ------------------ scripts/version.js | 30 -- 18 files changed, 5 insertions(+), 472 deletions(-) delete mode 100644 .github/workflows/publish.yml delete mode 100644 .gitignore rename CHANGELOG.md => packages/lazy-file/CHANGELOG.md (100%) rename LICENSE => packages/lazy-file/LICENSE (100%) rename README.md => packages/lazy-file/README.md (100%) rename package.json => packages/lazy-file/package.json (85%) rename {src => packages/lazy-file/src}/fs.ts (100%) rename {src => packages/lazy-file/src}/global.d.ts (100%) rename {src => packages/lazy-file/src}/lazy-file.ts (100%) rename {src => packages/lazy-file/src}/lib/byte-range.spec.ts (100%) rename {src => packages/lazy-file/src}/lib/byte-range.ts (100%) rename {src => packages/lazy-file/src}/lib/lazy-file.spec.ts (100%) rename {src => packages/lazy-file/src}/lib/lazy-file.ts (100%) rename tsconfig.json => packages/lazy-file/tsconfig.json (100%) rename tsconfig.lib.json => packages/lazy-file/tsconfig.lib.json (100%) rename tsconfig.spec.json => packages/lazy-file/tsconfig.spec.json (100%) delete mode 100644 pnpm-lock.yaml delete mode 100644 scripts/version.js diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index cbdc3b17796..00000000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Publish - -on: - push: - tags: - - v[0-9]* - -jobs: - build: - runs-on: ubuntu-latest - - permissions: - contents: write - id-token: write - - steps: - - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - - - uses: actions/setup-node@v4 - with: - node-version: '20.x' - registry-url: 'https://registry.npmjs.org' - cache: 'pnpm' - - - run: pnpm install - - - name: Publish to npm - run: npm publish --provenance --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore deleted file mode 100644 index c9282d7e5e3..00000000000 --- a/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.tsimp -dist -node_modules - -*.tsbuildinfo \ No newline at end of file diff --git a/CHANGELOG.md b/packages/lazy-file/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to packages/lazy-file/CHANGELOG.md diff --git a/LICENSE b/packages/lazy-file/LICENSE similarity index 100% rename from LICENSE rename to packages/lazy-file/LICENSE diff --git a/README.md b/packages/lazy-file/README.md similarity index 100% rename from README.md rename to packages/lazy-file/README.md diff --git a/package.json b/packages/lazy-file/package.json similarity index 85% rename from package.json rename to packages/lazy-file/package.json index e55109904f9..54f1eb34280 100644 --- a/package.json +++ b/packages/lazy-file/package.json @@ -19,6 +19,9 @@ "./fs": "./dist/fs.js", "./package.json": "./package.json" }, + "dependencies": { + "mrmime": "^2.0.0" + }, "devDependencies": { "@types/node": "^22.5.0", "prettier": "^3.3.3", @@ -26,19 +29,13 @@ "typescript": "^5.5.4" }, "scripts": { - "clean": "git clean -fdX .", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "version": "node scripts/version.js" + "prepare": "pnpm run build" }, - "packageManager": "pnpm@9.7.1", "keywords": [ "file", "buffer", "blob" - ], - "dependencies": { - "mrmime": "^2.0.0" - } + ] } diff --git a/src/fs.ts b/packages/lazy-file/src/fs.ts similarity index 100% rename from src/fs.ts rename to packages/lazy-file/src/fs.ts diff --git a/src/global.d.ts b/packages/lazy-file/src/global.d.ts similarity index 100% rename from src/global.d.ts rename to packages/lazy-file/src/global.d.ts diff --git a/src/lazy-file.ts b/packages/lazy-file/src/lazy-file.ts similarity index 100% rename from src/lazy-file.ts rename to packages/lazy-file/src/lazy-file.ts diff --git a/src/lib/byte-range.spec.ts b/packages/lazy-file/src/lib/byte-range.spec.ts similarity index 100% rename from src/lib/byte-range.spec.ts rename to packages/lazy-file/src/lib/byte-range.spec.ts diff --git a/src/lib/byte-range.ts b/packages/lazy-file/src/lib/byte-range.ts similarity index 100% rename from src/lib/byte-range.ts rename to packages/lazy-file/src/lib/byte-range.ts diff --git a/src/lib/lazy-file.spec.ts b/packages/lazy-file/src/lib/lazy-file.spec.ts similarity index 100% rename from src/lib/lazy-file.spec.ts rename to packages/lazy-file/src/lib/lazy-file.spec.ts diff --git a/src/lib/lazy-file.ts b/packages/lazy-file/src/lib/lazy-file.ts similarity index 100% rename from src/lib/lazy-file.ts rename to packages/lazy-file/src/lib/lazy-file.ts diff --git a/tsconfig.json b/packages/lazy-file/tsconfig.json similarity index 100% rename from tsconfig.json rename to packages/lazy-file/tsconfig.json diff --git a/tsconfig.lib.json b/packages/lazy-file/tsconfig.lib.json similarity index 100% rename from tsconfig.lib.json rename to packages/lazy-file/tsconfig.lib.json diff --git a/tsconfig.spec.json b/packages/lazy-file/tsconfig.spec.json similarity index 100% rename from tsconfig.spec.json rename to packages/lazy-file/tsconfig.spec.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index 06db263ad07..00000000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,397 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - mrmime: - specifier: ^2.0.0 - version: 2.0.0 - devDependencies: - '@types/node': - specifier: ^22.5.0 - version: 22.5.0 - prettier: - specifier: ^3.3.3 - version: 3.3.3 - tsimp: - specifier: ^2.0.11 - version: 2.0.11(typescript@5.5.4) - typescript: - specifier: ^5.5.4 - version: 5.5.4 - -packages: - - '@isaacs/cached@1.0.1': - resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} - - '@isaacs/catcher@1.0.4': - resolution: {integrity: sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA==} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@types/node@22.5.0': - resolution: {integrity: sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - foreground-child@3.3.0: - resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} - engines: {node: '>=14'} - - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - mkdirp@3.0.1: - resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} - engines: {node: '>=10'} - hasBin: true - - mrmime@2.0.0: - resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} - engines: {node: '>=10'} - - package-json-from-dist@1.0.0: - resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} - engines: {node: '>= 6'} - - prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} - engines: {node: '>=14'} - hasBin: true - - rimraf@5.0.10: - resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - sock-daemon@1.4.2: - resolution: {integrity: sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg==} - engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} - - socket-post-message@1.0.3: - resolution: {integrity: sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - tsimp@2.0.11: - resolution: {integrity: sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==} - engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} - hasBin: true - peerDependencies: - typescript: ^5.1.0 - - typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} - engines: {node: '>=14.17'} - hasBin: true - - undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - - walk-up-path@3.0.1: - resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - -snapshots: - - '@isaacs/cached@1.0.1': - dependencies: - '@isaacs/catcher': 1.0.4 - - '@isaacs/catcher@1.0.4': {} - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@types/node@22.5.0': - dependencies: - undici-types: 6.19.8 - - ansi-regex@5.0.1: {} - - ansi-regex@6.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.1: {} - - balanced-match@1.0.2: {} - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - eastasianwidth@0.2.0: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - foreground-child@3.3.0: - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - - glob@10.4.5: - dependencies: - foreground-child: 3.3.0 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.0 - path-scurry: 1.11.1 - - is-fullwidth-code-point@3.0.0: {} - - isexe@2.0.0: {} - - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - lru-cache@10.4.3: {} - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.1 - - minipass@7.1.2: {} - - mkdirp@3.0.1: {} - - mrmime@2.0.0: {} - - package-json-from-dist@1.0.0: {} - - path-key@3.1.1: {} - - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 - - pirates@4.0.6: {} - - prettier@3.3.3: {} - - rimraf@5.0.10: - dependencies: - glob: 10.4.5 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - signal-exit@4.1.0: {} - - sock-daemon@1.4.2: - dependencies: - rimraf: 5.0.10 - signal-exit: 4.1.0 - socket-post-message: 1.0.3 - - socket-post-message@1.0.3: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.0.1 - - tsimp@2.0.11(typescript@5.5.4): - dependencies: - '@isaacs/cached': 1.0.1 - '@isaacs/catcher': 1.0.4 - foreground-child: 3.3.0 - mkdirp: 3.0.1 - pirates: 4.0.6 - rimraf: 5.0.10 - signal-exit: 4.1.0 - sock-daemon: 1.4.2 - typescript: 5.5.4 - walk-up-path: 3.0.1 - - typescript@5.5.4: {} - - undici-types@6.19.8: {} - - walk-up-path@3.0.1: {} - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 diff --git a/scripts/version.js b/scripts/version.js deleted file mode 100644 index 3c140ddd756..00000000000 --- a/scripts/version.js +++ /dev/null @@ -1,30 +0,0 @@ -import * as cp from "node:child_process"; -import * as fs from "node:fs"; -import * as path from "node:path"; -import * as process from "node:process"; - -const __dirname = path.dirname(new URL(import.meta.url).pathname); -const packageVersion = process.env.npm_package_version; - -// Update CHANGELOG.md with the current version -let changelogPath = path.resolve(__dirname, "../CHANGELOG.md"); -let changelog = fs.readFileSync(changelogPath, "utf-8"); -let match = /^## HEAD\n/m.exec(changelog); -if (match) { - let today = new Date().toLocaleDateString("en-US", { - month: "short", - day: "numeric", - year: "numeric" - }); - - changelog = - changelog.slice(0, match.index) + - `## v${packageVersion} (${today})\n` + - changelog.slice(match.index + match[0].length); - - fs.writeFileSync(changelogPath, changelog); - cp.execSync("git add CHANGELOG.md"); -} else { - console.error('Could not find "## HEAD" in CHANGELOG.md'); - process.exit(1); -} From a7450812e2cb083f26aef2d78832b473eec75601 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 16:25:33 -0700 Subject: [PATCH 349/730] Add Nx --- .gitignore | 3 + nx.json | 4 + package.json | 7 +- pnpm-lock.yaml | 971 ++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 982 insertions(+), 3 deletions(-) create mode 100644 nx.json diff --git a/.gitignore b/.gitignore index c40c95a61dd..2400b8e91e7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ **/node_modules/ **/*.tsbuildinfo + +.nx/cache +.nx/workspace-data \ No newline at end of file diff --git a/nx.json b/nx.json new file mode 100644 index 00000000000..f8e2b253a36 --- /dev/null +++ b/nx.json @@ -0,0 +1,4 @@ +{ + "$schema": "./node_modules/nx/schemas/nx-schema.json", + "defaultBase": "main" +} \ No newline at end of file diff --git a/package.json b/package.json index 2ed19846431..651a7cbb305 100644 --- a/package.json +++ b/package.json @@ -4,5 +4,8 @@ "scripts": { "clean": "git clean -fdX ." }, - "packageManager": "pnpm@9.9.0" -} + "packageManager": "pnpm@9.9.0", + "devDependencies": { + "nx": "19.6.3" + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9b60ae1782d..c2578c2f94a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,4 +6,973 @@ settings: importers: - .: {} + .: + devDependencies: + nx: + specifier: 19.6.3 + version: 19.6.3 + +packages: + + '@emnapi/core@1.2.0': + resolution: {integrity: sha512-E7Vgw78I93we4ZWdYCb4DGAwRROGkMIXk7/y87UmANR+J6qsWusmC3gLt0H+O0KOt5e6O38U8oJamgbudrES/w==} + + '@emnapi/runtime@1.2.0': + resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==} + + '@emnapi/wasi-threads@1.0.1': + resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@napi-rs/wasm-runtime@0.2.4': + resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} + + '@nrwl/tao@19.6.3': + resolution: {integrity: sha512-j4vPU87yBhTrdyPFSNhlUkN29w4BQ+M14khT8PFGe+Y26gHMxNRNXNFUCwtVARYAc6IwxS8Uvlwy7AwXG2ETPA==} + hasBin: true + + '@nx/nx-darwin-arm64@19.6.3': + resolution: {integrity: sha512-P7WlX5YDZOABAlyfpR6eObigQTNuUuy3iJVUuGwp1Nuo3VPMPkpK1GMWKWLwOR9+2jGnF5MzuqWHk7CdF33uqQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@nx/nx-darwin-x64@19.6.3': + resolution: {integrity: sha512-HF28dPc7h0EmEGYJWJUPA3cBvjXyHbSbGQP5oP885gos9zcyVBjQ2kdJEUZDNMHB9KlZraeXbmV1umFkikjn6A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@nx/nx-freebsd-x64@19.6.3': + resolution: {integrity: sha512-y52dWxQ/x2ccyPqA4Vou4CnTqZX4gr/wV9myJX56G1CyEpWasmcqmPFeOKQd6dj7llGM/KJ/4Gz29RYxcWffcA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@nx/nx-linux-arm-gnueabihf@19.6.3': + resolution: {integrity: sha512-RneCg1tglLbP4cmGnGUs4FgZVT0aOA9wA53tO4IbyxLnlRXNY9OE452YLgqv3H7sLtNjsey2Lkq1seBHtr3p/Q==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@nx/nx-linux-arm64-gnu@19.6.3': + resolution: {integrity: sha512-Y+vgqaxrPQUEtCzxK25QY4ahO90l0eWgVrvCALexGmq0lW41JrVpfTTsbH/BAPLsx+u8A/GPAQAgrmg7d5lSxw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@nx/nx-linux-arm64-musl@19.6.3': + resolution: {integrity: sha512-o/99DBgafbjiJ4e9KFxaldvtlZta/FdzEiQQW+SQQ0JGSYlLCZZ8tIT6t3edV7cmG+gQLNMwolJzgpY53O9wjA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@nx/nx-linux-x64-gnu@19.6.3': + resolution: {integrity: sha512-ppp0NBOhwJ39U1vR7h8jhFSfiur6CZPSUYjXsV44BlaNGc1wHZ+7FDXhzOTokgTNWHavYgYOJuVan5LtTLKJkA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@nx/nx-linux-x64-musl@19.6.3': + resolution: {integrity: sha512-H7xgsT5OTtVYCXjXBLZu28v+rIInhbUggrgVJ2iQJFGBT2A2qmvGmDJdcDz8+K90ku1f4VuWmm8i+TEyDEcBuQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@nx/nx-win32-arm64-msvc@19.6.3': + resolution: {integrity: sha512-o9O6lSmx67zUnqOtlDC4YpC++fiUkixgIsQEG8J/2jdNgAATqOtERcqCNra/uke/Q94Vht2tVXjXF3uj92APhw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@nx/nx-win32-x64-msvc@19.6.3': + resolution: {integrity: sha512-6NQhc7jYQ/sqPt5fDy8C+br73kTd5jhb8ZkPtEy2Amr1aA1K9SAxZAYfyvxLHS2z1nBEelNFgXe6HBmDX92FkA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@tybys/wasm-util@0.9.0': + resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + + '@yarnpkg/lockfile@1.1.0': + resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} + + '@yarnpkg/parsers@3.0.0-rc.46': + resolution: {integrity: sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==} + engines: {node: '>=14.15.0'} + + '@zkochan/js-yaml@0.0.7': + resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} + hasBin: true + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.7.5: + resolution: {integrity: sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + + cli-spinners@2.6.1: + resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} + engines: {node: '>=6'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + dotenv-expand@11.0.6: + resolution: {integrity: sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==} + engines: {node: '>=12'} + + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + enquirer@2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + front-matter@4.0.2: + resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + lines-and-columns@2.0.4: + resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + node-machine-id@1.1.12: + resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + nx@19.6.3: + resolution: {integrity: sha512-JbgrEKaIBvTfhw3mG3GeyyzJHBAMfuQkMNrxxIto1fn94gxdjXdMfqUnAzrW6xRAt5OEEU+rf7v2OA3vEXYc3A==} + hasBin: true + peerDependencies: + '@swc-node/register': ^1.8.0 + '@swc/core': ^1.3.85 + peerDependenciesMeta: + '@swc-node/register': + optional: true + '@swc/core': + optional: true + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + ora@5.3.0: + resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} + engines: {node: '>=10'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + 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'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strong-log-transformer@2.1.0: + resolution: {integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==} + engines: {node: '>=4'} + hasBin: true + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + tmp@0.2.3: + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + engines: {node: '>=14.14'} + + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + +snapshots: + + '@emnapi/core@1.2.0': + dependencies: + '@emnapi/wasi-threads': 1.0.1 + tslib: 2.7.0 + + '@emnapi/runtime@1.2.0': + dependencies: + tslib: 2.7.0 + + '@emnapi/wasi-threads@1.0.1': + dependencies: + tslib: 2.7.0 + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@napi-rs/wasm-runtime@0.2.4': + dependencies: + '@emnapi/core': 1.2.0 + '@emnapi/runtime': 1.2.0 + '@tybys/wasm-util': 0.9.0 + + '@nrwl/tao@19.6.3': + dependencies: + nx: 19.6.3 + tslib: 2.7.0 + transitivePeerDependencies: + - '@swc-node/register' + - '@swc/core' + - debug + + '@nx/nx-darwin-arm64@19.6.3': + optional: true + + '@nx/nx-darwin-x64@19.6.3': + optional: true + + '@nx/nx-freebsd-x64@19.6.3': + optional: true + + '@nx/nx-linux-arm-gnueabihf@19.6.3': + optional: true + + '@nx/nx-linux-arm64-gnu@19.6.3': + optional: true + + '@nx/nx-linux-arm64-musl@19.6.3': + optional: true + + '@nx/nx-linux-x64-gnu@19.6.3': + optional: true + + '@nx/nx-linux-x64-musl@19.6.3': + optional: true + + '@nx/nx-win32-arm64-msvc@19.6.3': + optional: true + + '@nx/nx-win32-x64-msvc@19.6.3': + optional: true + + '@sinclair/typebox@0.27.8': {} + + '@tybys/wasm-util@0.9.0': + dependencies: + tslib: 2.7.0 + + '@yarnpkg/lockfile@1.1.0': {} + + '@yarnpkg/parsers@3.0.0-rc.46': + dependencies: + js-yaml: 3.14.1 + tslib: 2.7.0 + + '@zkochan/js-yaml@0.0.7': + dependencies: + argparse: 2.0.1 + + ansi-colors@4.1.3: {} + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + asynckit@0.4.0: {} + + axios@1.7.5: + dependencies: + follow-redirects: 1.15.6 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + base64-js@1.5.1: {} + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + cli-spinners@2.6.1: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@1.0.4: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + define-lazy-prop@2.0.0: {} + + delayed-stream@1.0.0: {} + + diff-sequences@29.6.3: {} + + dotenv-expand@11.0.6: + dependencies: + dotenv: 16.4.5 + + dotenv@16.4.5: {} + + duplexer@0.1.2: {} + + emoji-regex@8.0.0: {} + + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + enquirer@2.3.6: + dependencies: + ansi-colors: 4.1.3 + + escalade@3.1.2: {} + + escape-string-regexp@1.0.5: {} + + esprima@4.0.1: {} + + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + + flat@5.0.2: {} + + follow-redirects@1.15.6: {} + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + front-matter@4.0.2: + dependencies: + js-yaml: 3.14.1 + + fs-constants@1.0.0: {} + + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + get-caller-file@2.0.5: {} + + graceful-fs@4.2.11: {} + + has-flag@4.0.0: {} + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + inherits@2.0.4: {} + + is-docker@2.2.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-interactive@1.0.0: {} + + is-unicode-supported@0.1.0: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-get-type@29.6.3: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + json5@2.2.3: {} + + jsonc-parser@3.2.0: {} + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + lines-and-columns@2.0.4: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mimic-fn@2.1.0: {} + + minimatch@9.0.3: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + node-machine-id@1.1.12: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + nx@19.6.3: + dependencies: + '@napi-rs/wasm-runtime': 0.2.4 + '@nrwl/tao': 19.6.3 + '@yarnpkg/lockfile': 1.1.0 + '@yarnpkg/parsers': 3.0.0-rc.46 + '@zkochan/js-yaml': 0.0.7 + axios: 1.7.5 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.6.1 + cliui: 8.0.1 + dotenv: 16.4.5 + dotenv-expand: 11.0.6 + enquirer: 2.3.6 + figures: 3.2.0 + flat: 5.0.2 + front-matter: 4.0.2 + fs-extra: 11.2.0 + ignore: 5.3.2 + jest-diff: 29.7.0 + jsonc-parser: 3.2.0 + lines-and-columns: 2.0.4 + minimatch: 9.0.3 + node-machine-id: 1.1.12 + npm-run-path: 4.0.1 + open: 8.4.2 + ora: 5.3.0 + semver: 7.6.3 + string-width: 4.2.3 + strong-log-transformer: 2.1.0 + tar-stream: 2.2.0 + tmp: 0.2.3 + tsconfig-paths: 4.2.0 + tslib: 2.7.0 + yargs: 17.7.2 + yargs-parser: 21.1.1 + optionalDependencies: + '@nx/nx-darwin-arm64': 19.6.3 + '@nx/nx-darwin-x64': 19.6.3 + '@nx/nx-freebsd-x64': 19.6.3 + '@nx/nx-linux-arm-gnueabihf': 19.6.3 + '@nx/nx-linux-arm64-gnu': 19.6.3 + '@nx/nx-linux-arm64-musl': 19.6.3 + '@nx/nx-linux-x64-gnu': 19.6.3 + '@nx/nx-linux-x64-musl': 19.6.3 + '@nx/nx-win32-arm64-msvc': 19.6.3 + '@nx/nx-win32-x64-msvc': 19.6.3 + transitivePeerDependencies: + - debug + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + ora@5.3.0: + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.6.1 + is-interactive: 1.0.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + + path-key@3.1.1: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + proxy-from-env@1.1.0: {} + + react-is@18.3.1: {} + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + require-directory@2.1.1: {} + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + safe-buffer@5.2.1: {} + + semver@7.6.3: {} + + signal-exit@3.0.7: {} + + sprintf-js@1.0.3: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@3.0.0: {} + + strong-log-transformer@2.1.0: + dependencies: + duplexer: 0.1.2 + minimist: 1.2.8 + through: 2.3.8 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + through@2.3.8: {} + + tmp@0.2.3: {} + + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.7.0: {} + + universalify@2.0.1: {} + + util-deprecate@1.0.2: {} + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + y18n@5.0.8: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 From 84a4a093bd3f0c0b835b2e8c7e62fb274b0fd605 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 16:54:48 -0700 Subject: [PATCH 350/730] Prep for monorepo migration --- .github/workflows/publish.yml | 32 -- .gitignore | 7 - .../file-storage/CHANGELOG.md | 0 LICENSE => packages/file-storage/LICENSE | 0 README.md => packages/file-storage/README.md | 0 .../file-storage/package.json | 12 +- .../file-storage/src}/file-storage.ts | 0 .../file-storage/src}/global.d.ts | 0 .../file-storage/src}/lib/file-storage.ts | 0 .../src}/lib/local-file-storage.spec.ts | 0 .../src}/lib/local-file-storage.ts | 0 .../src}/lib/memory-file-storage.spec.ts | 0 .../src}/lib/memory-file-storage.ts | 0 {src => packages/file-storage/src}/local.ts | 0 {src => packages/file-storage/src}/memory.ts | 0 .../file-storage/tsconfig.json | 0 .../file-storage/tsconfig.lib.json | 0 .../file-storage/tsconfig.spec.json | 0 pnpm-lock.yaml | 404 ------------------ scripts/version.js | 30 -- 20 files changed, 5 insertions(+), 480 deletions(-) delete mode 100644 .github/workflows/publish.yml delete mode 100644 .gitignore rename CHANGELOG.md => packages/file-storage/CHANGELOG.md (100%) rename LICENSE => packages/file-storage/LICENSE (100%) rename README.md => packages/file-storage/README.md (100%) rename package.json => packages/file-storage/package.json (89%) rename {src => packages/file-storage/src}/file-storage.ts (100%) rename {src => packages/file-storage/src}/global.d.ts (100%) rename {src => packages/file-storage/src}/lib/file-storage.ts (100%) rename {src => packages/file-storage/src}/lib/local-file-storage.spec.ts (100%) rename {src => packages/file-storage/src}/lib/local-file-storage.ts (100%) rename {src => packages/file-storage/src}/lib/memory-file-storage.spec.ts (100%) rename {src => packages/file-storage/src}/lib/memory-file-storage.ts (100%) rename {src => packages/file-storage/src}/local.ts (100%) rename {src => packages/file-storage/src}/memory.ts (100%) rename tsconfig.json => packages/file-storage/tsconfig.json (100%) rename tsconfig.lib.json => packages/file-storage/tsconfig.lib.json (100%) rename tsconfig.spec.json => packages/file-storage/tsconfig.spec.json (100%) delete mode 100644 pnpm-lock.yaml delete mode 100644 scripts/version.js diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index cbdc3b17796..00000000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Publish - -on: - push: - tags: - - v[0-9]* - -jobs: - build: - runs-on: ubuntu-latest - - permissions: - contents: write - id-token: write - - steps: - - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - - - uses: actions/setup-node@v4 - with: - node-version: '20.x' - registry-url: 'https://registry.npmjs.org' - cache: 'pnpm' - - - run: pnpm install - - - name: Publish to npm - run: npm publish --provenance --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore deleted file mode 100644 index d8b18099d6f..00000000000 --- a/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -.tsimp -.wrangler -dist -node_modules -test-local-file-storage - -*.tsbuildinfo \ No newline at end of file diff --git a/CHANGELOG.md b/packages/file-storage/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to packages/file-storage/CHANGELOG.md diff --git a/LICENSE b/packages/file-storage/LICENSE similarity index 100% rename from LICENSE rename to packages/file-storage/LICENSE diff --git a/README.md b/packages/file-storage/README.md similarity index 100% rename from README.md rename to packages/file-storage/README.md diff --git a/package.json b/packages/file-storage/package.json similarity index 89% rename from package.json rename to packages/file-storage/package.json index da3a6e057cd..ae926d6d48b 100644 --- a/package.json +++ b/packages/file-storage/package.json @@ -20,6 +20,9 @@ "./memory": "./dist/memory.js", "./package.json": "./package.json" }, + "dependencies": { + "@mjackson/lazy-file": "^2.2.0" + }, "devDependencies": { "@types/node": "^20.14.10", "prettier": "^3.3.3", @@ -30,17 +33,12 @@ "clean": "git clean -fdX .", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", - "prepare": "npm run build", - "version": "node scripts/version.js" + "prepare": "npm run build" }, - "packageManager": "pnpm@9.7.1", "keywords": [ "file", "storage", "stream", "fs" - ], - "dependencies": { - "@mjackson/lazy-file": "^2.2.0" - } + ] } diff --git a/src/file-storage.ts b/packages/file-storage/src/file-storage.ts similarity index 100% rename from src/file-storage.ts rename to packages/file-storage/src/file-storage.ts diff --git a/src/global.d.ts b/packages/file-storage/src/global.d.ts similarity index 100% rename from src/global.d.ts rename to packages/file-storage/src/global.d.ts diff --git a/src/lib/file-storage.ts b/packages/file-storage/src/lib/file-storage.ts similarity index 100% rename from src/lib/file-storage.ts rename to packages/file-storage/src/lib/file-storage.ts diff --git a/src/lib/local-file-storage.spec.ts b/packages/file-storage/src/lib/local-file-storage.spec.ts similarity index 100% rename from src/lib/local-file-storage.spec.ts rename to packages/file-storage/src/lib/local-file-storage.spec.ts diff --git a/src/lib/local-file-storage.ts b/packages/file-storage/src/lib/local-file-storage.ts similarity index 100% rename from src/lib/local-file-storage.ts rename to packages/file-storage/src/lib/local-file-storage.ts diff --git a/src/lib/memory-file-storage.spec.ts b/packages/file-storage/src/lib/memory-file-storage.spec.ts similarity index 100% rename from src/lib/memory-file-storage.spec.ts rename to packages/file-storage/src/lib/memory-file-storage.spec.ts diff --git a/src/lib/memory-file-storage.ts b/packages/file-storage/src/lib/memory-file-storage.ts similarity index 100% rename from src/lib/memory-file-storage.ts rename to packages/file-storage/src/lib/memory-file-storage.ts diff --git a/src/local.ts b/packages/file-storage/src/local.ts similarity index 100% rename from src/local.ts rename to packages/file-storage/src/local.ts diff --git a/src/memory.ts b/packages/file-storage/src/memory.ts similarity index 100% rename from src/memory.ts rename to packages/file-storage/src/memory.ts diff --git a/tsconfig.json b/packages/file-storage/tsconfig.json similarity index 100% rename from tsconfig.json rename to packages/file-storage/tsconfig.json diff --git a/tsconfig.lib.json b/packages/file-storage/tsconfig.lib.json similarity index 100% rename from tsconfig.lib.json rename to packages/file-storage/tsconfig.lib.json diff --git a/tsconfig.spec.json b/packages/file-storage/tsconfig.spec.json similarity index 100% rename from tsconfig.spec.json rename to packages/file-storage/tsconfig.spec.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index baa233b4c66..00000000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,404 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@mjackson/lazy-file': - specifier: ^2.2.0 - version: 2.2.0 - devDependencies: - '@types/node': - specifier: ^20.14.10 - version: 20.16.1 - prettier: - specifier: ^3.3.3 - version: 3.3.3 - tsimp: - specifier: ^2.0.11 - version: 2.0.11(typescript@5.5.4) - typescript: - specifier: ^5.5.3 - version: 5.5.4 - -packages: - - '@isaacs/cached@1.0.1': - resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} - - '@isaacs/catcher@1.0.4': - resolution: {integrity: sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA==} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@mjackson/lazy-file@2.2.0': - resolution: {integrity: sha512-51M2TAL5eMZj5mh1e22/qBl4C5udViZqSBEqwiHSi1lTAixCp4YiAOV62VaTSqVp771OkmgNCPsh8/LpJ/A/Yw==} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@types/node@20.16.1': - resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - foreground-child@3.3.0: - resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} - engines: {node: '>=14'} - - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - mkdirp@3.0.1: - resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} - engines: {node: '>=10'} - hasBin: true - - mrmime@2.0.0: - resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} - engines: {node: '>=10'} - - package-json-from-dist@1.0.0: - resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} - engines: {node: '>= 6'} - - prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} - engines: {node: '>=14'} - hasBin: true - - rimraf@5.0.10: - resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - sock-daemon@1.4.2: - resolution: {integrity: sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg==} - engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} - - socket-post-message@1.0.3: - resolution: {integrity: sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - tsimp@2.0.11: - resolution: {integrity: sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==} - engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} - hasBin: true - peerDependencies: - typescript: ^5.1.0 - - typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} - engines: {node: '>=14.17'} - hasBin: true - - undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - - walk-up-path@3.0.1: - resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - -snapshots: - - '@isaacs/cached@1.0.1': - dependencies: - '@isaacs/catcher': 1.0.4 - - '@isaacs/catcher@1.0.4': {} - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@mjackson/lazy-file@2.2.0': - dependencies: - mrmime: 2.0.0 - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@types/node@20.16.1': - dependencies: - undici-types: 6.19.8 - - ansi-regex@5.0.1: {} - - ansi-regex@6.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.1: {} - - balanced-match@1.0.2: {} - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - eastasianwidth@0.2.0: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - foreground-child@3.3.0: - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - - glob@10.4.5: - dependencies: - foreground-child: 3.3.0 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.0 - path-scurry: 1.11.1 - - is-fullwidth-code-point@3.0.0: {} - - isexe@2.0.0: {} - - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - lru-cache@10.4.3: {} - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.1 - - minipass@7.1.2: {} - - mkdirp@3.0.1: {} - - mrmime@2.0.0: {} - - package-json-from-dist@1.0.0: {} - - path-key@3.1.1: {} - - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 - - pirates@4.0.6: {} - - prettier@3.3.3: {} - - rimraf@5.0.10: - dependencies: - glob: 10.4.5 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - signal-exit@4.1.0: {} - - sock-daemon@1.4.2: - dependencies: - rimraf: 5.0.10 - signal-exit: 4.1.0 - socket-post-message: 1.0.3 - - socket-post-message@1.0.3: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.0.1 - - tsimp@2.0.11(typescript@5.5.4): - dependencies: - '@isaacs/cached': 1.0.1 - '@isaacs/catcher': 1.0.4 - foreground-child: 3.3.0 - mkdirp: 3.0.1 - pirates: 4.0.6 - rimraf: 5.0.10 - signal-exit: 4.1.0 - sock-daemon: 1.4.2 - typescript: 5.5.4 - walk-up-path: 3.0.1 - - typescript@5.5.4: {} - - undici-types@6.19.8: {} - - walk-up-path@3.0.1: {} - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 diff --git a/scripts/version.js b/scripts/version.js deleted file mode 100644 index 3c140ddd756..00000000000 --- a/scripts/version.js +++ /dev/null @@ -1,30 +0,0 @@ -import * as cp from "node:child_process"; -import * as fs from "node:fs"; -import * as path from "node:path"; -import * as process from "node:process"; - -const __dirname = path.dirname(new URL(import.meta.url).pathname); -const packageVersion = process.env.npm_package_version; - -// Update CHANGELOG.md with the current version -let changelogPath = path.resolve(__dirname, "../CHANGELOG.md"); -let changelog = fs.readFileSync(changelogPath, "utf-8"); -let match = /^## HEAD\n/m.exec(changelog); -if (match) { - let today = new Date().toLocaleDateString("en-US", { - month: "short", - day: "numeric", - year: "numeric" - }); - - changelog = - changelog.slice(0, match.index) + - `## v${packageVersion} (${today})\n` + - changelog.slice(match.index + match[0].length); - - fs.writeFileSync(changelogPath, changelog); - cp.execSync("git add CHANGELOG.md"); -} else { - console.error('Could not find "## HEAD" in CHANGELOG.md'); - process.exit(1); -} From e247c15eda3a5537a3192b57bdd0d4bbfaabd977 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 17:00:03 -0700 Subject: [PATCH 351/730] Prep for monorepo migration --- .github/workflows/publish.yml | 32 -- .gitignore | 5 - .../form-data-parser/CHANGELOG.md | 0 LICENSE => packages/form-data-parser/LICENSE | 0 .../form-data-parser/README.md | 0 .../form-data-parser/package.json | 4 +- .../form-data-parser/src}/form-data-parser.ts | 0 .../src}/lib/form-data.spec.ts | 0 .../form-data-parser/src}/lib/form-data.ts | 0 .../form-data-parser/tsconfig.json | 0 .../form-data-parser/tsconfig.lib.json | 0 .../form-data-parser/tsconfig.spec.json | 0 pnpm-lock.yaml | 403 ------------------ scripts/version.js | 30 -- 14 files changed, 1 insertion(+), 473 deletions(-) delete mode 100644 .github/workflows/publish.yml delete mode 100644 .gitignore rename CHANGELOG.md => packages/form-data-parser/CHANGELOG.md (100%) rename LICENSE => packages/form-data-parser/LICENSE (100%) rename README.md => packages/form-data-parser/README.md (100%) rename package.json => packages/form-data-parser/package.json (90%) rename {src => packages/form-data-parser/src}/form-data-parser.ts (100%) rename {src => packages/form-data-parser/src}/lib/form-data.spec.ts (100%) rename {src => packages/form-data-parser/src}/lib/form-data.ts (100%) rename tsconfig.json => packages/form-data-parser/tsconfig.json (100%) rename tsconfig.lib.json => packages/form-data-parser/tsconfig.lib.json (100%) rename tsconfig.spec.json => packages/form-data-parser/tsconfig.spec.json (100%) delete mode 100644 pnpm-lock.yaml delete mode 100644 scripts/version.js diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index cbdc3b17796..00000000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Publish - -on: - push: - tags: - - v[0-9]* - -jobs: - build: - runs-on: ubuntu-latest - - permissions: - contents: write - id-token: write - - steps: - - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - - - uses: actions/setup-node@v4 - with: - node-version: '20.x' - registry-url: 'https://registry.npmjs.org' - cache: 'pnpm' - - - run: pnpm install - - - name: Publish to npm - run: npm publish --provenance --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore deleted file mode 100644 index c9282d7e5e3..00000000000 --- a/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.tsimp -dist -node_modules - -*.tsbuildinfo \ No newline at end of file diff --git a/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to packages/form-data-parser/CHANGELOG.md diff --git a/LICENSE b/packages/form-data-parser/LICENSE similarity index 100% rename from LICENSE rename to packages/form-data-parser/LICENSE diff --git a/README.md b/packages/form-data-parser/README.md similarity index 100% rename from README.md rename to packages/form-data-parser/README.md diff --git a/package.json b/packages/form-data-parser/package.json similarity index 90% rename from package.json rename to packages/form-data-parser/package.json index 1dd1ea6d5c1..3a528990868 100644 --- a/package.json +++ b/packages/form-data-parser/package.json @@ -31,10 +31,8 @@ "clean": "git clean -fdX .", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "version": "node scripts/version.js" + "prepare": "pnpm run build" }, - "packageManager": "pnpm@9.7.1", "keywords": [ "form-data", "FormData", diff --git a/src/form-data-parser.ts b/packages/form-data-parser/src/form-data-parser.ts similarity index 100% rename from src/form-data-parser.ts rename to packages/form-data-parser/src/form-data-parser.ts diff --git a/src/lib/form-data.spec.ts b/packages/form-data-parser/src/lib/form-data.spec.ts similarity index 100% rename from src/lib/form-data.spec.ts rename to packages/form-data-parser/src/lib/form-data.spec.ts diff --git a/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts similarity index 100% rename from src/lib/form-data.ts rename to packages/form-data-parser/src/lib/form-data.ts diff --git a/tsconfig.json b/packages/form-data-parser/tsconfig.json similarity index 100% rename from tsconfig.json rename to packages/form-data-parser/tsconfig.json diff --git a/tsconfig.lib.json b/packages/form-data-parser/tsconfig.lib.json similarity index 100% rename from tsconfig.lib.json rename to packages/form-data-parser/tsconfig.lib.json diff --git a/tsconfig.spec.json b/packages/form-data-parser/tsconfig.spec.json similarity index 100% rename from tsconfig.spec.json rename to packages/form-data-parser/tsconfig.spec.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index d937e438594..00000000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,403 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@mjackson/multipart-parser': - specifier: ^0.6.1 - version: 0.6.1 - devDependencies: - '@types/node': - specifier: ^22.4.1 - version: 22.4.1 - prettier: - specifier: ^3.3.3 - version: 3.3.3 - tsimp: - specifier: ^2.0.11 - version: 2.0.11(typescript@5.5.4) - typescript: - specifier: ^5.5.4 - version: 5.5.4 - -packages: - - '@isaacs/cached@1.0.1': - resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} - - '@isaacs/catcher@1.0.4': - resolution: {integrity: sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA==} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@mjackson/headers@0.5.1': - resolution: {integrity: sha512-sJpFgecPT/zJvwk3GRNVWNs8EkwaJoUNU2D0VMlp+gDJs6cuSTm1q/aCZi3ZtuV6CgDEQ4l2ZjUG3A9JrQlbNA==} - - '@mjackson/multipart-parser@0.6.1': - resolution: {integrity: sha512-blI4HObze3ge1VQnSZSmhWv9tCm06Y23vVNBTffndhhmkdUpRsoIkw/3GXjcJXEOiciR3MjeTkBskJz6DMgspg==} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@types/node@22.4.1': - resolution: {integrity: sha512-1tbpb9325+gPnKK0dMm+/LMriX0vKxf6RnB0SZUqfyVkQ4fMgUSySqhxE/y8Jvs4NyF1yHzTfG9KlnkIODxPKg==} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - foreground-child@3.3.0: - resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} - engines: {node: '>=14'} - - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - mkdirp@3.0.1: - resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} - engines: {node: '>=10'} - hasBin: true - - package-json-from-dist@1.0.0: - resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} - engines: {node: '>= 6'} - - prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} - engines: {node: '>=14'} - hasBin: true - - rimraf@5.0.10: - resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - sock-daemon@1.4.2: - resolution: {integrity: sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg==} - engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} - - socket-post-message@1.0.3: - resolution: {integrity: sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - tsimp@2.0.11: - resolution: {integrity: sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==} - engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} - hasBin: true - peerDependencies: - typescript: ^5.1.0 - - typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} - engines: {node: '>=14.17'} - hasBin: true - - undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - - walk-up-path@3.0.1: - resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - -snapshots: - - '@isaacs/cached@1.0.1': - dependencies: - '@isaacs/catcher': 1.0.4 - - '@isaacs/catcher@1.0.4': {} - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@mjackson/headers@0.5.1': {} - - '@mjackson/multipart-parser@0.6.1': - dependencies: - '@mjackson/headers': 0.5.1 - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@types/node@22.4.1': - dependencies: - undici-types: 6.19.8 - - ansi-regex@5.0.1: {} - - ansi-regex@6.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.1: {} - - balanced-match@1.0.2: {} - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - eastasianwidth@0.2.0: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - foreground-child@3.3.0: - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - - glob@10.4.5: - dependencies: - foreground-child: 3.3.0 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.0 - path-scurry: 1.11.1 - - is-fullwidth-code-point@3.0.0: {} - - isexe@2.0.0: {} - - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - lru-cache@10.4.3: {} - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.1 - - minipass@7.1.2: {} - - mkdirp@3.0.1: {} - - package-json-from-dist@1.0.0: {} - - path-key@3.1.1: {} - - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 - - pirates@4.0.6: {} - - prettier@3.3.3: {} - - rimraf@5.0.10: - dependencies: - glob: 10.4.5 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - signal-exit@4.1.0: {} - - sock-daemon@1.4.2: - dependencies: - rimraf: 5.0.10 - signal-exit: 4.1.0 - socket-post-message: 1.0.3 - - socket-post-message@1.0.3: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.0.1 - - tsimp@2.0.11(typescript@5.5.4): - dependencies: - '@isaacs/cached': 1.0.1 - '@isaacs/catcher': 1.0.4 - foreground-child: 3.3.0 - mkdirp: 3.0.1 - pirates: 4.0.6 - rimraf: 5.0.10 - signal-exit: 4.1.0 - sock-daemon: 1.4.2 - typescript: 5.5.4 - walk-up-path: 3.0.1 - - typescript@5.5.4: {} - - undici-types@6.19.8: {} - - walk-up-path@3.0.1: {} - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 diff --git a/scripts/version.js b/scripts/version.js deleted file mode 100644 index 3c140ddd756..00000000000 --- a/scripts/version.js +++ /dev/null @@ -1,30 +0,0 @@ -import * as cp from "node:child_process"; -import * as fs from "node:fs"; -import * as path from "node:path"; -import * as process from "node:process"; - -const __dirname = path.dirname(new URL(import.meta.url).pathname); -const packageVersion = process.env.npm_package_version; - -// Update CHANGELOG.md with the current version -let changelogPath = path.resolve(__dirname, "../CHANGELOG.md"); -let changelog = fs.readFileSync(changelogPath, "utf-8"); -let match = /^## HEAD\n/m.exec(changelog); -if (match) { - let today = new Date().toLocaleDateString("en-US", { - month: "short", - day: "numeric", - year: "numeric" - }); - - changelog = - changelog.slice(0, match.index) + - `## v${packageVersion} (${today})\n` + - changelog.slice(match.index + match[0].length); - - fs.writeFileSync(changelogPath, changelog); - cp.execSync("git add CHANGELOG.md"); -} else { - console.error('Could not find "## HEAD" in CHANGELOG.md'); - process.exit(1); -} From a1bb25f3592fb44b7abe57fa2bb7c385d3c82083 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 17:09:14 -0700 Subject: [PATCH 352/730] Prep for monorepo migration --- .github/workflows/publish.yml | 35 - .gitignore | 6 - .prettierrc | 4 - .vscode/settings.json | 2 +- .../multipart-parser/CHANGELOG.md | 0 LICENSE => packages/multipart-parser/LICENSE | 0 .../multipart-parser/README.md | 0 .../multipart-parser/bench}/global.d.ts | 0 .../multipart-parser/bench}/messages.ts | 0 .../multipart-parser/bench}/package.json | 0 .../multipart-parser/bench}/parsers/busboy.ts | 0 .../bench}/parsers/fastify-busboy.ts | 0 .../bench}/parsers/multipart-parser.ts | 0 .../bench}/parsers/multipasta.ts | 0 .../multipart-parser/bench}/runner.ts | 0 .../multipart-parser/bench}/tsconfig.json | 0 .../multipart-parser/bench}/utils.ts | 0 .../multipart-parser/examples}/bun/.gitignore | 0 .../multipart-parser/examples}/bun/README.md | 0 .../examples}/bun/global.d.ts | 0 .../examples}/bun/package.json | 0 .../multipart-parser/examples}/bun/server.ts | 0 .../examples}/bun/tsconfig.json | 0 .../examples}/cf-workers/README.md | 0 .../examples}/cf-workers/package.json | 0 .../examples}/cf-workers/src/index.ts | 0 .../examples}/cf-workers/tsconfig.json | 0 .../cf-workers/worker-configuration.d.ts | 0 .../examples}/cf-workers/wrangler.toml | 0 .../multipart-parser/examples}/deno/README.md | 0 .../multipart-parser/examples}/deno/main.ts | 0 .../examples}/deno/package.json | 0 .../multipart-parser/examples}/node/README.md | 0 .../examples}/node/package.json | 0 .../multipart-parser/examples}/node/server.js | 0 .../examples}/node/tsconfig.json | 0 .../multipart-parser/jsr.json | 0 .../multipart-parser/package.json | 0 .../multipart-parser/src}/global.d.ts | 0 .../src}/lib/multipart.node.spec.ts | 0 .../src}/lib/multipart.node.ts | 0 .../src}/lib/multipart.spec.ts | 0 .../multipart-parser/src}/lib/multipart.ts | 0 .../multipart-parser/src}/lib/search.spec.ts | 0 .../multipart-parser/src}/lib/search.ts | 0 .../src}/multipart-parser.node.ts | 0 .../multipart-parser/src}/multipart-parser.ts | 0 .../multipart-parser/src}/test/utils.node.ts | 0 .../multipart-parser/src}/test/utils.ts | 0 .../multipart-parser/tsconfig.json | 0 .../multipart-parser/tsconfig.lib.json | 0 .../multipart-parser/tsconfig.spec.json | 0 pnpm-lock.yaml | 1424 ----------------- pnpm-workspace.yaml | 4 +- scripts/version.js | 37 - 55 files changed, 3 insertions(+), 1509 deletions(-) delete mode 100644 .github/workflows/publish.yml delete mode 100644 .gitignore delete mode 100644 .prettierrc rename CHANGELOG.md => packages/multipart-parser/CHANGELOG.md (100%) rename LICENSE => packages/multipart-parser/LICENSE (100%) rename README.md => packages/multipart-parser/README.md (100%) rename {bench => packages/multipart-parser/bench}/global.d.ts (100%) rename {bench => packages/multipart-parser/bench}/messages.ts (100%) rename {bench => packages/multipart-parser/bench}/package.json (100%) rename {bench => packages/multipart-parser/bench}/parsers/busboy.ts (100%) rename {bench => packages/multipart-parser/bench}/parsers/fastify-busboy.ts (100%) rename {bench => packages/multipart-parser/bench}/parsers/multipart-parser.ts (100%) rename {bench => packages/multipart-parser/bench}/parsers/multipasta.ts (100%) rename {bench => packages/multipart-parser/bench}/runner.ts (100%) rename {bench => packages/multipart-parser/bench}/tsconfig.json (100%) rename {bench => packages/multipart-parser/bench}/utils.ts (100%) rename {examples => packages/multipart-parser/examples}/bun/.gitignore (100%) rename {examples => packages/multipart-parser/examples}/bun/README.md (100%) rename {examples => packages/multipart-parser/examples}/bun/global.d.ts (100%) rename {examples => packages/multipart-parser/examples}/bun/package.json (100%) rename {examples => packages/multipart-parser/examples}/bun/server.ts (100%) rename {examples => packages/multipart-parser/examples}/bun/tsconfig.json (100%) rename {examples => packages/multipart-parser/examples}/cf-workers/README.md (100%) rename {examples => packages/multipart-parser/examples}/cf-workers/package.json (100%) rename {examples => packages/multipart-parser/examples}/cf-workers/src/index.ts (100%) rename {examples => packages/multipart-parser/examples}/cf-workers/tsconfig.json (100%) rename {examples => packages/multipart-parser/examples}/cf-workers/worker-configuration.d.ts (100%) rename {examples => packages/multipart-parser/examples}/cf-workers/wrangler.toml (100%) rename {examples => packages/multipart-parser/examples}/deno/README.md (100%) rename {examples => packages/multipart-parser/examples}/deno/main.ts (100%) rename {examples => packages/multipart-parser/examples}/deno/package.json (100%) rename {examples => packages/multipart-parser/examples}/node/README.md (100%) rename {examples => packages/multipart-parser/examples}/node/package.json (100%) rename {examples => packages/multipart-parser/examples}/node/server.js (100%) rename {examples => packages/multipart-parser/examples}/node/tsconfig.json (100%) rename jsr.json => packages/multipart-parser/jsr.json (100%) rename package.json => packages/multipart-parser/package.json (100%) rename {src => packages/multipart-parser/src}/global.d.ts (100%) rename {src => packages/multipart-parser/src}/lib/multipart.node.spec.ts (100%) rename {src => packages/multipart-parser/src}/lib/multipart.node.ts (100%) rename {src => packages/multipart-parser/src}/lib/multipart.spec.ts (100%) rename {src => packages/multipart-parser/src}/lib/multipart.ts (100%) rename {src => packages/multipart-parser/src}/lib/search.spec.ts (100%) rename {src => packages/multipart-parser/src}/lib/search.ts (100%) rename {src => packages/multipart-parser/src}/multipart-parser.node.ts (100%) rename {src => packages/multipart-parser/src}/multipart-parser.ts (100%) rename {src => packages/multipart-parser/src}/test/utils.node.ts (100%) rename {src => packages/multipart-parser/src}/test/utils.ts (100%) rename tsconfig.json => packages/multipart-parser/tsconfig.json (100%) rename tsconfig.lib.json => packages/multipart-parser/tsconfig.lib.json (100%) rename tsconfig.spec.json => packages/multipart-parser/tsconfig.spec.json (100%) delete mode 100644 pnpm-lock.yaml delete mode 100644 scripts/version.js diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index b80f53a3ce9..00000000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Publish - -on: - push: - tags: - - v[0-9]* - -jobs: - build: - runs-on: ubuntu-latest - - permissions: - contents: write - id-token: write - - steps: - - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - - - uses: actions/setup-node@v4 - with: - node-version: '20.x' - registry-url: 'https://registry.npmjs.org' - cache: 'pnpm' - - - run: pnpm install - - - name: Publish to npm - run: npm publish --provenance --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - - name: Publish to JSR - run: npx jsr publish diff --git a/.gitignore b/.gitignore deleted file mode 100644 index f45b2eb5ca9..00000000000 --- a/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.tsimp -.wrangler -dist -node_modules - -*.tsbuildinfo \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index f018274ffc2..00000000000 --- a/.prettierrc +++ /dev/null @@ -1,4 +0,0 @@ -printWidth: 100 -semi: true -singleQuote: true -useTabs: false diff --git a/.vscode/settings.json b/.vscode/settings.json index f4ab7915a02..dbc6d7ee2df 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "deno.enablePaths": ["./examples/deno"] + "deno.enablePaths": ["./packages/multipart-parser/examples/deno"] } diff --git a/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to packages/multipart-parser/CHANGELOG.md diff --git a/LICENSE b/packages/multipart-parser/LICENSE similarity index 100% rename from LICENSE rename to packages/multipart-parser/LICENSE diff --git a/README.md b/packages/multipart-parser/README.md similarity index 100% rename from README.md rename to packages/multipart-parser/README.md diff --git a/bench/global.d.ts b/packages/multipart-parser/bench/global.d.ts similarity index 100% rename from bench/global.d.ts rename to packages/multipart-parser/bench/global.d.ts diff --git a/bench/messages.ts b/packages/multipart-parser/bench/messages.ts similarity index 100% rename from bench/messages.ts rename to packages/multipart-parser/bench/messages.ts diff --git a/bench/package.json b/packages/multipart-parser/bench/package.json similarity index 100% rename from bench/package.json rename to packages/multipart-parser/bench/package.json diff --git a/bench/parsers/busboy.ts b/packages/multipart-parser/bench/parsers/busboy.ts similarity index 100% rename from bench/parsers/busboy.ts rename to packages/multipart-parser/bench/parsers/busboy.ts diff --git a/bench/parsers/fastify-busboy.ts b/packages/multipart-parser/bench/parsers/fastify-busboy.ts similarity index 100% rename from bench/parsers/fastify-busboy.ts rename to packages/multipart-parser/bench/parsers/fastify-busboy.ts diff --git a/bench/parsers/multipart-parser.ts b/packages/multipart-parser/bench/parsers/multipart-parser.ts similarity index 100% rename from bench/parsers/multipart-parser.ts rename to packages/multipart-parser/bench/parsers/multipart-parser.ts diff --git a/bench/parsers/multipasta.ts b/packages/multipart-parser/bench/parsers/multipasta.ts similarity index 100% rename from bench/parsers/multipasta.ts rename to packages/multipart-parser/bench/parsers/multipasta.ts diff --git a/bench/runner.ts b/packages/multipart-parser/bench/runner.ts similarity index 100% rename from bench/runner.ts rename to packages/multipart-parser/bench/runner.ts diff --git a/bench/tsconfig.json b/packages/multipart-parser/bench/tsconfig.json similarity index 100% rename from bench/tsconfig.json rename to packages/multipart-parser/bench/tsconfig.json diff --git a/bench/utils.ts b/packages/multipart-parser/bench/utils.ts similarity index 100% rename from bench/utils.ts rename to packages/multipart-parser/bench/utils.ts diff --git a/examples/bun/.gitignore b/packages/multipart-parser/examples/bun/.gitignore similarity index 100% rename from examples/bun/.gitignore rename to packages/multipart-parser/examples/bun/.gitignore diff --git a/examples/bun/README.md b/packages/multipart-parser/examples/bun/README.md similarity index 100% rename from examples/bun/README.md rename to packages/multipart-parser/examples/bun/README.md diff --git a/examples/bun/global.d.ts b/packages/multipart-parser/examples/bun/global.d.ts similarity index 100% rename from examples/bun/global.d.ts rename to packages/multipart-parser/examples/bun/global.d.ts diff --git a/examples/bun/package.json b/packages/multipart-parser/examples/bun/package.json similarity index 100% rename from examples/bun/package.json rename to packages/multipart-parser/examples/bun/package.json diff --git a/examples/bun/server.ts b/packages/multipart-parser/examples/bun/server.ts similarity index 100% rename from examples/bun/server.ts rename to packages/multipart-parser/examples/bun/server.ts diff --git a/examples/bun/tsconfig.json b/packages/multipart-parser/examples/bun/tsconfig.json similarity index 100% rename from examples/bun/tsconfig.json rename to packages/multipart-parser/examples/bun/tsconfig.json diff --git a/examples/cf-workers/README.md b/packages/multipart-parser/examples/cf-workers/README.md similarity index 100% rename from examples/cf-workers/README.md rename to packages/multipart-parser/examples/cf-workers/README.md diff --git a/examples/cf-workers/package.json b/packages/multipart-parser/examples/cf-workers/package.json similarity index 100% rename from examples/cf-workers/package.json rename to packages/multipart-parser/examples/cf-workers/package.json diff --git a/examples/cf-workers/src/index.ts b/packages/multipart-parser/examples/cf-workers/src/index.ts similarity index 100% rename from examples/cf-workers/src/index.ts rename to packages/multipart-parser/examples/cf-workers/src/index.ts diff --git a/examples/cf-workers/tsconfig.json b/packages/multipart-parser/examples/cf-workers/tsconfig.json similarity index 100% rename from examples/cf-workers/tsconfig.json rename to packages/multipart-parser/examples/cf-workers/tsconfig.json diff --git a/examples/cf-workers/worker-configuration.d.ts b/packages/multipart-parser/examples/cf-workers/worker-configuration.d.ts similarity index 100% rename from examples/cf-workers/worker-configuration.d.ts rename to packages/multipart-parser/examples/cf-workers/worker-configuration.d.ts diff --git a/examples/cf-workers/wrangler.toml b/packages/multipart-parser/examples/cf-workers/wrangler.toml similarity index 100% rename from examples/cf-workers/wrangler.toml rename to packages/multipart-parser/examples/cf-workers/wrangler.toml diff --git a/examples/deno/README.md b/packages/multipart-parser/examples/deno/README.md similarity index 100% rename from examples/deno/README.md rename to packages/multipart-parser/examples/deno/README.md diff --git a/examples/deno/main.ts b/packages/multipart-parser/examples/deno/main.ts similarity index 100% rename from examples/deno/main.ts rename to packages/multipart-parser/examples/deno/main.ts diff --git a/examples/deno/package.json b/packages/multipart-parser/examples/deno/package.json similarity index 100% rename from examples/deno/package.json rename to packages/multipart-parser/examples/deno/package.json diff --git a/examples/node/README.md b/packages/multipart-parser/examples/node/README.md similarity index 100% rename from examples/node/README.md rename to packages/multipart-parser/examples/node/README.md diff --git a/examples/node/package.json b/packages/multipart-parser/examples/node/package.json similarity index 100% rename from examples/node/package.json rename to packages/multipart-parser/examples/node/package.json diff --git a/examples/node/server.js b/packages/multipart-parser/examples/node/server.js similarity index 100% rename from examples/node/server.js rename to packages/multipart-parser/examples/node/server.js diff --git a/examples/node/tsconfig.json b/packages/multipart-parser/examples/node/tsconfig.json similarity index 100% rename from examples/node/tsconfig.json rename to packages/multipart-parser/examples/node/tsconfig.json diff --git a/jsr.json b/packages/multipart-parser/jsr.json similarity index 100% rename from jsr.json rename to packages/multipart-parser/jsr.json diff --git a/package.json b/packages/multipart-parser/package.json similarity index 100% rename from package.json rename to packages/multipart-parser/package.json diff --git a/src/global.d.ts b/packages/multipart-parser/src/global.d.ts similarity index 100% rename from src/global.d.ts rename to packages/multipart-parser/src/global.d.ts diff --git a/src/lib/multipart.node.spec.ts b/packages/multipart-parser/src/lib/multipart.node.spec.ts similarity index 100% rename from src/lib/multipart.node.spec.ts rename to packages/multipart-parser/src/lib/multipart.node.spec.ts diff --git a/src/lib/multipart.node.ts b/packages/multipart-parser/src/lib/multipart.node.ts similarity index 100% rename from src/lib/multipart.node.ts rename to packages/multipart-parser/src/lib/multipart.node.ts diff --git a/src/lib/multipart.spec.ts b/packages/multipart-parser/src/lib/multipart.spec.ts similarity index 100% rename from src/lib/multipart.spec.ts rename to packages/multipart-parser/src/lib/multipart.spec.ts diff --git a/src/lib/multipart.ts b/packages/multipart-parser/src/lib/multipart.ts similarity index 100% rename from src/lib/multipart.ts rename to packages/multipart-parser/src/lib/multipart.ts diff --git a/src/lib/search.spec.ts b/packages/multipart-parser/src/lib/search.spec.ts similarity index 100% rename from src/lib/search.spec.ts rename to packages/multipart-parser/src/lib/search.spec.ts diff --git a/src/lib/search.ts b/packages/multipart-parser/src/lib/search.ts similarity index 100% rename from src/lib/search.ts rename to packages/multipart-parser/src/lib/search.ts diff --git a/src/multipart-parser.node.ts b/packages/multipart-parser/src/multipart-parser.node.ts similarity index 100% rename from src/multipart-parser.node.ts rename to packages/multipart-parser/src/multipart-parser.node.ts diff --git a/src/multipart-parser.ts b/packages/multipart-parser/src/multipart-parser.ts similarity index 100% rename from src/multipart-parser.ts rename to packages/multipart-parser/src/multipart-parser.ts diff --git a/src/test/utils.node.ts b/packages/multipart-parser/src/test/utils.node.ts similarity index 100% rename from src/test/utils.node.ts rename to packages/multipart-parser/src/test/utils.node.ts diff --git a/src/test/utils.ts b/packages/multipart-parser/src/test/utils.ts similarity index 100% rename from src/test/utils.ts rename to packages/multipart-parser/src/test/utils.ts diff --git a/tsconfig.json b/packages/multipart-parser/tsconfig.json similarity index 100% rename from tsconfig.json rename to packages/multipart-parser/tsconfig.json diff --git a/tsconfig.lib.json b/packages/multipart-parser/tsconfig.lib.json similarity index 100% rename from tsconfig.lib.json rename to packages/multipart-parser/tsconfig.lib.json diff --git a/tsconfig.spec.json b/packages/multipart-parser/tsconfig.spec.json similarity index 100% rename from tsconfig.spec.json rename to packages/multipart-parser/tsconfig.spec.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index 03bdc2ef3ec..00000000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,1424 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@mjackson/headers': - specifier: ^0.5.0 - version: 0.5.0 - devDependencies: - '@types/node': - specifier: ^20.14.10 - version: 20.14.13 - prettier: - specifier: ^3.3.3 - version: 3.3.3 - tsimp: - specifier: ^2.0.11 - version: 2.0.11(typescript@5.5.4) - typescript: - specifier: ^5.5.3 - version: 5.5.4 - - bench: - dependencies: - '@fastify/busboy': - specifier: ^3.0.0 - version: 3.0.0 - '@mjackson/multipart-parser': - specifier: workspace:* - version: link:.. - busboy: - specifier: ^1.6.0 - version: 1.6.0 - multipasta: - specifier: ^0.2.4 - version: 0.2.4 - devDependencies: - '@types/bun': - specifier: ^1.1.6 - version: 1.1.6 - '@types/busboy': - specifier: ^1.5.4 - version: 1.5.4 - - examples/bun: - dependencies: - '@mjackson/multipart-parser': - specifier: workspace:* - version: link:../.. - tmp: - specifier: ^0.2.3 - version: 0.2.3 - devDependencies: - '@types/bun': - specifier: ^1.1.6 - version: 1.1.6 - '@types/tmp': - specifier: ^0.2.6 - version: 0.2.6 - - examples/cf-workers: - dependencies: - '@mjackson/multipart-parser': - specifier: workspace:* - version: link:../.. - devDependencies: - '@cloudflare/workers-types': - specifier: ^4.20240725.0 - version: 4.20240725.0 - typescript: - specifier: ^5.5.2 - version: 5.5.4 - wrangler: - specifier: ^3.60.3 - version: 3.67.1(@cloudflare/workers-types@4.20240725.0) - - examples/deno: - dependencies: - '@mjackson/multipart-parser': - specifier: workspace:* - version: link:../.. - tmp: - specifier: ^0.2.3 - version: 0.2.3 - devDependencies: - '@types/tmp': - specifier: ^0.2.6 - version: 0.2.6 - - examples/node: - dependencies: - '@mjackson/multipart-parser': - specifier: workspace:* - version: link:../.. - tmp: - specifier: ^0.2.3 - version: 0.2.3 - devDependencies: - '@types/node': - specifier: ^20.14.10 - version: 20.14.13 - '@types/tmp': - specifier: ^0.2.6 - version: 0.2.6 - -packages: - - '@cloudflare/kv-asset-handler@0.3.4': - resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} - engines: {node: '>=16.13'} - - '@cloudflare/workerd-darwin-64@1.20240718.0': - resolution: {integrity: sha512-BsPZcSCgoGnufog2GIgdPuiKicYTNyO/Dp++HbpLRH+yQdX3x4aWx83M+a0suTl1xv76dO4g9aw7SIB6OSgIyQ==} - engines: {node: '>=16'} - cpu: [x64] - os: [darwin] - - '@cloudflare/workerd-darwin-arm64@1.20240718.0': - resolution: {integrity: sha512-nlr4gaOO5gcJerILJQph3+2rnas/nx/lYsuaot1ntHu4LAPBoQo1q/Pucj2cSIav4UiMzTbDmoDwPlls4Kteog==} - engines: {node: '>=16'} - cpu: [arm64] - os: [darwin] - - '@cloudflare/workerd-linux-64@1.20240718.0': - resolution: {integrity: sha512-LJ/k3y47pBcjax0ee4K+6ZRrSsqWlfU4lbU8Dn6u5tSC9yzwI4YFNXDrKWInB0vd7RT3w4Yqq1S6ZEbfRrqVUg==} - engines: {node: '>=16'} - cpu: [x64] - os: [linux] - - '@cloudflare/workerd-linux-arm64@1.20240718.0': - resolution: {integrity: sha512-zBEZvy88EcAMGRGfuVtS00Yl7lJdUM9sH7i651OoL+q0Plv9kphlCC0REQPwzxrEYT1qibSYtWcD9IxQGgx2/g==} - engines: {node: '>=16'} - cpu: [arm64] - os: [linux] - - '@cloudflare/workerd-windows-64@1.20240718.0': - resolution: {integrity: sha512-YpCRvvT47XanFum7C3SedOZKK6BfVhqmwdAAVAQFyc4gsCdegZo0JkUkdloC/jwuWlbCACOG2HTADHOqyeolzQ==} - engines: {node: '>=16'} - cpu: [x64] - os: [win32] - - '@cloudflare/workers-types@4.20240725.0': - resolution: {integrity: sha512-L6T/Bg50zm9IIACQVQ0CdVcQL+2nLkRXdPz6BsXF3SlzgjyWR5ndVctAbfr/HLV7aKYxWnnEZsIORsTWb+FssA==} - - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - - '@esbuild-plugins/node-globals-polyfill@0.2.3': - resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} - peerDependencies: - esbuild: '*' - - '@esbuild-plugins/node-modules-polyfill@0.2.2': - resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} - peerDependencies: - esbuild: '*' - - '@esbuild/android-arm64@0.17.19': - resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.17.19': - resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.17.19': - resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.17.19': - resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.17.19': - resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.17.19': - resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.17.19': - resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.17.19': - resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.17.19': - resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.17.19': - resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.17.19': - resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.17.19': - resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.17.19': - resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.17.19': - resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.17.19': - resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.17.19': - resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-x64@0.17.19': - resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-x64@0.17.19': - resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/sunos-x64@0.17.19': - resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.17.19': - resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.17.19': - resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.17.19': - resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@fastify/busboy@2.1.1': - resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} - engines: {node: '>=14'} - - '@fastify/busboy@3.0.0': - resolution: {integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==} - - '@isaacs/cached@1.0.1': - resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} - - '@isaacs/catcher@1.0.4': - resolution: {integrity: sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA==} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - - '@mjackson/headers@0.5.0': - resolution: {integrity: sha512-aRlcySUJXTm2krQbXMXhOOPdCWN0dtIL4Y0M1veLqp0ObjslNSJ2ttKN2W0+9gE01MUo5UgtwSXq8UMhMifytQ==} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@types/bun@1.1.6': - resolution: {integrity: sha512-uJgKjTdX0GkWEHZzQzFsJkWp5+43ZS7HC8sZPFnOwnSo1AsNl2q9o2bFeS23disNDqbggEgyFkKCHl/w8iZsMA==} - - '@types/busboy@1.5.4': - resolution: {integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==} - - '@types/node-forge@1.3.11': - resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} - - '@types/node@20.12.14': - resolution: {integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==} - - '@types/node@20.14.13': - resolution: {integrity: sha512-+bHoGiZb8UiQ0+WEtmph2IWQCjIqg8MDZMAV+ppRRhUZnquF5mQkP/9vpSwJClEiSM/C7fZZExPzfU0vJTyp8w==} - - '@types/tmp@0.2.6': - resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} - - '@types/ws@8.5.12': - resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} - - acorn-walk@8.3.3: - resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} - engines: {node: '>=0.4.0'} - - acorn@8.12.1: - resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} - engines: {node: '>=0.4.0'} - hasBin: true - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - as-table@1.0.55: - resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - - blake3-wasm@2.1.5: - resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - bun-types@1.1.17: - resolution: {integrity: sha512-Z4+OplcSd/YZq7ZsrfD00DKJeCwuNY96a1IDJyR73+cTBaFIS7SC6LhpY/W3AMEXO9iYq5NJ58WAwnwL1p5vKg==} - - busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} - - capnp-ts@0.7.0: - resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} - - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - consola@3.2.3: - resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} - engines: {node: ^14.18.0 || >=16.10.0} - - cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} - - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - - data-uri-to-buffer@2.0.2: - resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} - - date-fns@3.6.0: - resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} - - debug@4.3.6: - resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - esbuild@0.17.19: - resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} - engines: {node: '>=12'} - hasBin: true - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - estree-walker@0.6.1: - resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} - - exit-hook@2.2.1: - resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} - engines: {node: '>=6'} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - foreground-child@3.2.1: - resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} - engines: {node: '>=14'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - get-source@2.0.12: - resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-core-module@2.15.0: - resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==} - engines: {node: '>= 0.4'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - magic-string@0.25.9: - resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - - mime@3.0.0: - resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} - engines: {node: '>=10.0.0'} - hasBin: true - - miniflare@3.20240718.1: - resolution: {integrity: sha512-mn3MjGnpgYvarCRTfz4TQyVyY8yW0zz7f8LOAPVai78IGC/lcVcyskZcuIr7Zovb2i+IERmmsJAiEPeZHIIKbA==} - engines: {node: '>=16.13'} - hasBin: true - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - mkdirp@3.0.1: - resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} - engines: {node: '>=10'} - hasBin: true - - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - - multipasta@0.2.4: - resolution: {integrity: sha512-uS6VKZou4iDU4evtrNKGvRqgqkFtPdjG/ql9XDICfnzKEedgf0OZ+oEhM0ps0FL5IVFhkIzOBgLV/KpEEJMthw==} - - mustache@4.2.0: - resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} - hasBin: true - - nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - node-fetch-native@1.6.4: - resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} - - node-forge@1.3.1: - resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} - engines: {node: '>= 6.13.0'} - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - package-json-from-dist@1.0.0: - resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - - path-to-regexp@6.2.2: - resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} - - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} - engines: {node: '>= 6'} - - prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} - engines: {node: '>=14'} - hasBin: true - - printable-characters@1.0.42: - resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} - - resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true - - rimraf@5.0.10: - resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} - hasBin: true - - rollup-plugin-inject@3.0.2: - resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} - deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. - - rollup-plugin-node-polyfills@0.2.1: - resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} - - rollup-pluginutils@2.8.2: - resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} - - selfsigned@2.4.1: - resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} - engines: {node: '>=10'} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - sock-daemon@1.4.2: - resolution: {integrity: sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg==} - engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} - - socket-post-message@1.0.3: - resolution: {integrity: sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - - stacktracey@2.1.8: - resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} - - stoppable@1.1.0: - resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} - engines: {node: '>=4', npm: '>=6'} - - streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - tmp@0.2.3: - resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} - engines: {node: '>=14.14'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - tsimp@2.0.11: - resolution: {integrity: sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==} - engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} - hasBin: true - peerDependencies: - typescript: ^5.1.0 - - tslib@2.6.3: - resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} - - typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} - engines: {node: '>=14.17'} - hasBin: true - - ufo@1.5.4: - resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} - - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - undici@5.28.4: - resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} - engines: {node: '>=14.0'} - - unenv-nightly@1.10.0-1717606461.a117952: - resolution: {integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==} - - walk-up-path@3.0.1: - resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - workerd@1.20240718.0: - resolution: {integrity: sha512-w7lOLRy0XecQTg/ujTLWBiJJuoQvzB3CdQ6/8Wgex3QxFhV9Pbnh3UbwIuUfMw3OCCPQc4o7y+1P+mISAgp6yg==} - engines: {node: '>=16'} - hasBin: true - - wrangler@3.67.1: - resolution: {integrity: sha512-lLVJxq/OZMfntvZ79WQJNC1OKfxOCs6PLfogqDBuPFEQ3L/Mwqvd9IZ0bB8ahrwUN/K3lSdDPXynk9HfcGZxVw==} - engines: {node: '>=16.17.0'} - hasBin: true - peerDependencies: - '@cloudflare/workers-types': ^4.20240718.0 - peerDependenciesMeta: - '@cloudflare/workers-types': - optional: true - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - ws@8.18.0: - resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - xxhash-wasm@1.0.2: - resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} - - youch@3.3.3: - resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} - - zod@3.23.8: - resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} - -snapshots: - - '@cloudflare/kv-asset-handler@0.3.4': - dependencies: - mime: 3.0.0 - - '@cloudflare/workerd-darwin-64@1.20240718.0': - optional: true - - '@cloudflare/workerd-darwin-arm64@1.20240718.0': - optional: true - - '@cloudflare/workerd-linux-64@1.20240718.0': - optional: true - - '@cloudflare/workerd-linux-arm64@1.20240718.0': - optional: true - - '@cloudflare/workerd-windows-64@1.20240718.0': - optional: true - - '@cloudflare/workers-types@4.20240725.0': {} - - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - - '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': - dependencies: - esbuild: 0.17.19 - - '@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19)': - dependencies: - esbuild: 0.17.19 - escape-string-regexp: 4.0.0 - rollup-plugin-node-polyfills: 0.2.1 - - '@esbuild/android-arm64@0.17.19': - optional: true - - '@esbuild/android-arm@0.17.19': - optional: true - - '@esbuild/android-x64@0.17.19': - optional: true - - '@esbuild/darwin-arm64@0.17.19': - optional: true - - '@esbuild/darwin-x64@0.17.19': - optional: true - - '@esbuild/freebsd-arm64@0.17.19': - optional: true - - '@esbuild/freebsd-x64@0.17.19': - optional: true - - '@esbuild/linux-arm64@0.17.19': - optional: true - - '@esbuild/linux-arm@0.17.19': - optional: true - - '@esbuild/linux-ia32@0.17.19': - optional: true - - '@esbuild/linux-loong64@0.17.19': - optional: true - - '@esbuild/linux-mips64el@0.17.19': - optional: true - - '@esbuild/linux-ppc64@0.17.19': - optional: true - - '@esbuild/linux-riscv64@0.17.19': - optional: true - - '@esbuild/linux-s390x@0.17.19': - optional: true - - '@esbuild/linux-x64@0.17.19': - optional: true - - '@esbuild/netbsd-x64@0.17.19': - optional: true - - '@esbuild/openbsd-x64@0.17.19': - optional: true - - '@esbuild/sunos-x64@0.17.19': - optional: true - - '@esbuild/win32-arm64@0.17.19': - optional: true - - '@esbuild/win32-ia32@0.17.19': - optional: true - - '@esbuild/win32-x64@0.17.19': - optional: true - - '@fastify/busboy@2.1.1': {} - - '@fastify/busboy@3.0.0': {} - - '@isaacs/cached@1.0.1': - dependencies: - '@isaacs/catcher': 1.0.4 - - '@isaacs/catcher@1.0.4': {} - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.0': {} - - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - - '@mjackson/headers@0.5.0': {} - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@types/bun@1.1.6': - dependencies: - bun-types: 1.1.17 - - '@types/busboy@1.5.4': - dependencies: - '@types/node': 20.14.13 - - '@types/node-forge@1.3.11': - dependencies: - '@types/node': 20.14.13 - - '@types/node@20.12.14': - dependencies: - undici-types: 5.26.5 - - '@types/node@20.14.13': - dependencies: - undici-types: 5.26.5 - - '@types/tmp@0.2.6': {} - - '@types/ws@8.5.12': - dependencies: - '@types/node': 20.14.13 - - acorn-walk@8.3.3: - dependencies: - acorn: 8.12.1 - - acorn@8.12.1: {} - - ansi-regex@5.0.1: {} - - ansi-regex@6.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.1: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - as-table@1.0.55: - dependencies: - printable-characters: 1.0.42 - - balanced-match@1.0.2: {} - - binary-extensions@2.3.0: {} - - blake3-wasm@2.1.5: {} - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - bun-types@1.1.17: - dependencies: - '@types/node': 20.12.14 - '@types/ws': 8.5.12 - - busboy@1.6.0: - dependencies: - streamsearch: 1.1.0 - - capnp-ts@0.7.0: - dependencies: - debug: 4.3.6 - tslib: 2.6.3 - transitivePeerDependencies: - - supports-color - - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - consola@3.2.3: {} - - cookie@0.5.0: {} - - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - data-uri-to-buffer@2.0.2: {} - - date-fns@3.6.0: {} - - debug@4.3.6: - dependencies: - ms: 2.1.2 - - defu@6.1.4: {} - - eastasianwidth@0.2.0: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - esbuild@0.17.19: - optionalDependencies: - '@esbuild/android-arm': 0.17.19 - '@esbuild/android-arm64': 0.17.19 - '@esbuild/android-x64': 0.17.19 - '@esbuild/darwin-arm64': 0.17.19 - '@esbuild/darwin-x64': 0.17.19 - '@esbuild/freebsd-arm64': 0.17.19 - '@esbuild/freebsd-x64': 0.17.19 - '@esbuild/linux-arm': 0.17.19 - '@esbuild/linux-arm64': 0.17.19 - '@esbuild/linux-ia32': 0.17.19 - '@esbuild/linux-loong64': 0.17.19 - '@esbuild/linux-mips64el': 0.17.19 - '@esbuild/linux-ppc64': 0.17.19 - '@esbuild/linux-riscv64': 0.17.19 - '@esbuild/linux-s390x': 0.17.19 - '@esbuild/linux-x64': 0.17.19 - '@esbuild/netbsd-x64': 0.17.19 - '@esbuild/openbsd-x64': 0.17.19 - '@esbuild/sunos-x64': 0.17.19 - '@esbuild/win32-arm64': 0.17.19 - '@esbuild/win32-ia32': 0.17.19 - '@esbuild/win32-x64': 0.17.19 - - escape-string-regexp@4.0.0: {} - - estree-walker@0.6.1: {} - - exit-hook@2.2.1: {} - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - foreground-child@3.2.1: - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - get-source@2.0.12: - dependencies: - data-uri-to-buffer: 2.0.2 - source-map: 0.6.1 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-to-regexp@0.4.1: {} - - glob@10.4.5: - dependencies: - foreground-child: 3.2.1 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.0 - path-scurry: 1.11.1 - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-core-module@2.15.0: - dependencies: - hasown: 2.0.2 - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@3.0.0: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-number@7.0.0: {} - - isexe@2.0.0: {} - - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - lru-cache@10.4.3: {} - - magic-string@0.25.9: - dependencies: - sourcemap-codec: 1.4.8 - - mime@3.0.0: {} - - miniflare@3.20240718.1: - dependencies: - '@cspotcode/source-map-support': 0.8.1 - acorn: 8.12.1 - acorn-walk: 8.3.3 - capnp-ts: 0.7.0 - exit-hook: 2.2.1 - glob-to-regexp: 0.4.1 - stoppable: 1.1.0 - undici: 5.28.4 - workerd: 1.20240718.0 - ws: 8.18.0 - youch: 3.3.3 - zod: 3.23.8 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.1 - - minipass@7.1.2: {} - - mkdirp@3.0.1: {} - - ms@2.1.2: {} - - multipasta@0.2.4: {} - - mustache@4.2.0: {} - - nanoid@3.3.7: {} - - node-fetch-native@1.6.4: {} - - node-forge@1.3.1: {} - - normalize-path@3.0.0: {} - - package-json-from-dist@1.0.0: {} - - path-key@3.1.1: {} - - path-parse@1.0.7: {} - - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 - - path-to-regexp@6.2.2: {} - - pathe@1.1.2: {} - - picomatch@2.3.1: {} - - pirates@4.0.6: {} - - prettier@3.3.3: {} - - printable-characters@1.0.42: {} - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - resolve.exports@2.0.2: {} - - resolve@1.22.8: - dependencies: - is-core-module: 2.15.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - rimraf@5.0.10: - dependencies: - glob: 10.4.5 - - rollup-plugin-inject@3.0.2: - dependencies: - estree-walker: 0.6.1 - magic-string: 0.25.9 - rollup-pluginutils: 2.8.2 - - rollup-plugin-node-polyfills@0.2.1: - dependencies: - rollup-plugin-inject: 3.0.2 - - rollup-pluginutils@2.8.2: - dependencies: - estree-walker: 0.6.1 - - selfsigned@2.4.1: - dependencies: - '@types/node-forge': 1.3.11 - node-forge: 1.3.1 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - signal-exit@4.1.0: {} - - sock-daemon@1.4.2: - dependencies: - rimraf: 5.0.10 - signal-exit: 4.1.0 - socket-post-message: 1.0.3 - - socket-post-message@1.0.3: {} - - source-map@0.6.1: {} - - sourcemap-codec@1.4.8: {} - - stacktracey@2.1.8: - dependencies: - as-table: 1.0.55 - get-source: 2.0.12 - - stoppable@1.1.0: {} - - streamsearch@1.1.0: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.0.1 - - supports-preserve-symlinks-flag@1.0.0: {} - - tmp@0.2.3: {} - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - tsimp@2.0.11(typescript@5.5.4): - dependencies: - '@isaacs/cached': 1.0.1 - '@isaacs/catcher': 1.0.4 - foreground-child: 3.2.1 - mkdirp: 3.0.1 - pirates: 4.0.6 - rimraf: 5.0.10 - signal-exit: 4.1.0 - sock-daemon: 1.4.2 - typescript: 5.5.4 - walk-up-path: 3.0.1 - - tslib@2.6.3: {} - - typescript@5.5.4: {} - - ufo@1.5.4: {} - - undici-types@5.26.5: {} - - undici@5.28.4: - dependencies: - '@fastify/busboy': 2.1.1 - - unenv-nightly@1.10.0-1717606461.a117952: - dependencies: - consola: 3.2.3 - defu: 6.1.4 - mime: 3.0.0 - node-fetch-native: 1.6.4 - pathe: 1.1.2 - ufo: 1.5.4 - - walk-up-path@3.0.1: {} - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - workerd@1.20240718.0: - optionalDependencies: - '@cloudflare/workerd-darwin-64': 1.20240718.0 - '@cloudflare/workerd-darwin-arm64': 1.20240718.0 - '@cloudflare/workerd-linux-64': 1.20240718.0 - '@cloudflare/workerd-linux-arm64': 1.20240718.0 - '@cloudflare/workerd-windows-64': 1.20240718.0 - - wrangler@3.67.1(@cloudflare/workers-types@4.20240725.0): - dependencies: - '@cloudflare/kv-asset-handler': 0.3.4 - '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) - '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) - blake3-wasm: 2.1.5 - chokidar: 3.6.0 - date-fns: 3.6.0 - esbuild: 0.17.19 - miniflare: 3.20240718.1 - nanoid: 3.3.7 - path-to-regexp: 6.2.2 - resolve: 1.22.8 - resolve.exports: 2.0.2 - selfsigned: 2.4.1 - source-map: 0.6.1 - unenv: unenv-nightly@1.10.0-1717606461.a117952 - workerd: 1.20240718.0 - xxhash-wasm: 1.0.2 - optionalDependencies: - '@cloudflare/workers-types': 4.20240725.0 - fsevents: 2.3.3 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - ws@8.18.0: {} - - xxhash-wasm@1.0.2: {} - - youch@3.3.3: - dependencies: - cookie: 0.5.0 - mustache: 4.2.0 - stacktracey: 2.1.8 - - zod@3.23.8: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index cc1e5949236..5112167c0fc 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,3 @@ packages: - - 'bench' - - 'examples/*' \ No newline at end of file + - packages/multipart-parser/bench + - packages/multipart-parser/examples/* \ No newline at end of file diff --git a/scripts/version.js b/scripts/version.js deleted file mode 100644 index 08ef09d9768..00000000000 --- a/scripts/version.js +++ /dev/null @@ -1,37 +0,0 @@ -import * as cp from 'node:child_process'; -import * as fs from 'node:fs'; -import * as path from 'node:path'; -import * as process from 'node:process'; - -const __dirname = path.dirname(new URL(import.meta.url).pathname); -const packageVersion = process.env.npm_package_version; - -// Update CHANGELOG.md with the current version -let changelogPath = path.resolve(__dirname, '../CHANGELOG.md'); -let changelog = fs.readFileSync(changelogPath, 'utf-8'); -let match = /^## HEAD\n/m.exec(changelog); -if (match) { - let today = new Date().toLocaleDateString('en-US', { - month: 'short', - day: 'numeric', - year: 'numeric', - }); - - changelog = - changelog.slice(0, match.index) + - `## v${packageVersion} (${today})\n` + - changelog.slice(match.index + match[0].length); - - fs.writeFileSync(changelogPath, changelog); - cp.execSync('git add CHANGELOG.md'); -} else { - console.error('Could not find "## HEAD" in CHANGELOG.md'); - process.exit(1); -} - -// Update jsr.json with the current version -let jsrJsonPath = path.resolve(__dirname, '../jsr.json'); -let jsrJson = JSON.parse(fs.readFileSync(jsrJsonPath, 'utf-8')); -jsrJson.version = packageVersion; -fs.writeFileSync(jsrJsonPath, JSON.stringify(jsrJson, null, 2) + '\n'); -cp.execSync('git add jsr.json'); From 19619a10687e48b34cac0cbbbdc646b361d2edaf Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 17:37:40 -0700 Subject: [PATCH 353/730] Update some package metadata --- packages/file-storage/package.json | 6 +- packages/form-data-parser/package.json | 4 +- packages/lazy-file/package.json | 3 +- packages/multipart-parser/package.json | 8 +- pnpm-lock.yaml | 1520 +++++++++++++++++++++++- 5 files changed, 1477 insertions(+), 64 deletions(-) diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index ae926d6d48b..b4c8117ae14 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -5,7 +5,8 @@ "author": "Michael Jackson ", "repository": { "type": "git", - "url": "git+https://github.com/mjackson/file-storage.git" + "url": "git+https://github.com/mjackson/remix-the-web.git", + "directory": "packages/file-storage" }, "license": "MIT", "files": [ @@ -30,10 +31,9 @@ "typescript": "^5.5.3" }, "scripts": { - "clean": "git clean -fdX .", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", - "prepare": "npm run build" + "prepare": "pnpm run build" }, "keywords": [ "file", diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index 3a528990868..aa480dc49a9 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -5,7 +5,8 @@ "author": "Michael Jackson ", "repository": { "type": "git", - "url": "git+https://github.com/mjackson/form-data-parser.git" + "url": "git+https://github.com/mjackson/remix-the-web.git", + "directory": "packages/form-data-parser" }, "license": "MIT", "files": [ @@ -28,7 +29,6 @@ "typescript": "^5.5.4" }, "scripts": { - "clean": "git clean -fdX .", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", "prepare": "pnpm run build" diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index 54f1eb34280..7c70c4f6eda 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -5,7 +5,8 @@ "author": "Michael Jackson ", "repository": { "type": "git", - "url": "git+https://github.com/mjackson/lazy-file.git" + "url": "git+https://github.com/mjackson/remix-the-web.git", + "directory": "packages/lazy-file" }, "license": "MIT", "files": [ diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 061428895f9..aa4580bf099 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -5,7 +5,8 @@ "author": "Michael Jackson ", "repository": { "type": "git", - "url": "git+https://github.com/mjackson/multipart-parser.git" + "url": "git+https://github.com/mjackson/remix-the-web.git", + "directory": "packages/multipart-parser" }, "license": "MIT", "files": [ @@ -29,17 +30,14 @@ "typescript": "^5.5.3" }, "scripts": { - "clean": "git clean -fdX .", "bench": "pnpm run bench:node && pnpm run bench:bun && pnpm run bench:deno", "bench:bun": "bun run ./bench/runner.ts", "bench:deno": "deno --unstable-byonm --unstable-sloppy-imports run --allow-sys ./bench/runner.ts", "bench:node": "node --import tsimp/import ./bench/runner.ts", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", - "prepare": "npm run build", - "version": "node scripts/version.js" + "prepare": "pnpm run build" }, - "packageManager": "pnpm@9.4.0", "keywords": [ "multipart", "parser", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c2578c2f94a..89bd384a040 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,212 @@ importers: specifier: 19.6.3 version: 19.6.3 + packages/file-storage: + dependencies: + '@mjackson/lazy-file': + specifier: ^2.2.0 + version: 2.2.0 + devDependencies: + '@types/node': + specifier: ^20.14.10 + version: 20.16.1 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + tsimp: + specifier: ^2.0.11 + version: 2.0.11(typescript@5.5.4) + typescript: + specifier: ^5.5.3 + version: 5.5.4 + + packages/form-data-parser: + dependencies: + '@mjackson/multipart-parser': + specifier: ^0.6.1 + version: 0.6.2 + devDependencies: + '@types/node': + specifier: ^22.4.1 + version: 22.5.0 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + tsimp: + specifier: ^2.0.11 + version: 2.0.11(typescript@5.5.4) + typescript: + specifier: ^5.5.4 + version: 5.5.4 + + packages/lazy-file: + dependencies: + mrmime: + specifier: ^2.0.0 + version: 2.0.0 + devDependencies: + '@types/node': + specifier: ^22.5.0 + version: 22.5.0 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + tsimp: + specifier: ^2.0.11 + version: 2.0.11(typescript@5.5.4) + typescript: + specifier: ^5.5.4 + version: 5.5.4 + + packages/multipart-parser: + dependencies: + '@mjackson/headers': + specifier: ^0.5.0 + version: 0.5.1 + devDependencies: + '@types/node': + specifier: ^20.14.10 + version: 20.16.1 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + tsimp: + specifier: ^2.0.11 + version: 2.0.11(typescript@5.5.4) + typescript: + specifier: ^5.5.3 + version: 5.5.4 + + packages/multipart-parser/bench: + dependencies: + '@fastify/busboy': + specifier: ^3.0.0 + version: 3.0.0 + '@mjackson/multipart-parser': + specifier: workspace:* + version: link:.. + busboy: + specifier: ^1.6.0 + version: 1.6.0 + multipasta: + specifier: ^0.2.4 + version: 0.2.5 + devDependencies: + '@types/bun': + specifier: ^1.1.6 + version: 1.1.8 + '@types/busboy': + specifier: ^1.5.4 + version: 1.5.4 + + packages/multipart-parser/examples/bun: + dependencies: + '@mjackson/multipart-parser': + specifier: workspace:* + version: link:../.. + tmp: + specifier: ^0.2.3 + version: 0.2.3 + devDependencies: + '@types/bun': + specifier: ^1.1.6 + version: 1.1.8 + '@types/tmp': + specifier: ^0.2.6 + version: 0.2.6 + + packages/multipart-parser/examples/cf-workers: + dependencies: + '@mjackson/multipart-parser': + specifier: workspace:* + version: link:../.. + devDependencies: + '@cloudflare/workers-types': + specifier: ^4.20240725.0 + version: 4.20240821.1 + typescript: + specifier: ^5.5.2 + version: 5.5.4 + wrangler: + specifier: ^3.60.3 + version: 3.72.3(@cloudflare/workers-types@4.20240821.1) + + packages/multipart-parser/examples/deno: + dependencies: + '@mjackson/multipart-parser': + specifier: workspace:* + version: link:../.. + tmp: + specifier: ^0.2.3 + version: 0.2.3 + devDependencies: + '@types/tmp': + specifier: ^0.2.6 + version: 0.2.6 + + packages/multipart-parser/examples/node: + dependencies: + '@mjackson/multipart-parser': + specifier: workspace:* + version: link:../.. + tmp: + specifier: ^0.2.3 + version: 0.2.3 + devDependencies: + '@types/node': + specifier: ^20.14.10 + version: 20.16.1 + '@types/tmp': + specifier: ^0.2.6 + version: 0.2.6 + packages: + '@cloudflare/kv-asset-handler@0.3.4': + resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} + engines: {node: '>=16.13'} + + '@cloudflare/workerd-darwin-64@1.20240821.1': + resolution: {integrity: sha512-CDBpfZKrSy4YrIdqS84z67r3Tzal2pOhjCsIb63IuCnvVes59/ft1qhczBzk9EffeOE2iTCrA4YBT7Sbn7USew==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] + + '@cloudflare/workerd-darwin-arm64@1.20240821.1': + resolution: {integrity: sha512-Q+9RedvNbPcEt/dKni1oN94OxbvuNAeJkgHmrLFTGF8zu21wzOhVkQeRNxcYxrMa9mfStc457NAg13OVCj2kHQ==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] + + '@cloudflare/workerd-linux-64@1.20240821.1': + resolution: {integrity: sha512-j6z3KsPtawrscoLuP985LbqFrmsJL6q1mvSXOXTqXGODAHIzGBipHARdOjms3UQqovzvqB2lQaQsZtLBwCZxtA==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] + + '@cloudflare/workerd-linux-arm64@1.20240821.1': + resolution: {integrity: sha512-I9bHgZOxJQW0CV5gTdilyxzTG7ILzbTirehQWgfPx9X77E/7eIbR9sboOMgyeC69W4he0SKtpx0sYZuTJu4ERw==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] + + '@cloudflare/workerd-windows-64@1.20240821.1': + resolution: {integrity: sha512-keC97QPArs6LWbPejQM7/Y8Jy8QqyaZow4/ZdsGo+QjlOLiZRDpAenfZx3CBUoWwEeFwQTl2FLO+8hV1SWFFYw==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] + + '@cloudflare/workers-shared@0.4.0': + resolution: {integrity: sha512-XAFOldVQsbxQ7mjbqX2q1dNIgcLbKSytk41pwuZTn9e0p7OeTpFTosJef8uwosL6CcOAHqcW1f1HJxyjwmtGxw==} + engines: {node: '>=16.7.0'} + + '@cloudflare/workers-types@4.20240821.1': + resolution: {integrity: sha512-icAkbnAqgVl6ef9lgLTom8na+kj2RBw2ViPAQ586hbdj0xZcnrjK7P46Eu08OU9D/lNDgN2sKU/sxhe2iK/gIg==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + '@emnapi/core@1.2.0': resolution: {integrity: sha512-E7Vgw78I93we4ZWdYCb4DGAwRROGkMIXk7/y87UmANR+J6qsWusmC3gLt0H+O0KOt5e6O38U8oJamgbudrES/w==} @@ -23,10 +227,188 @@ packages: '@emnapi/wasi-threads@1.0.1': resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} + '@esbuild-plugins/node-globals-polyfill@0.2.3': + resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} + peerDependencies: + esbuild: '*' + + '@esbuild-plugins/node-modules-polyfill@0.2.2': + resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} + peerDependencies: + esbuild: '*' + + '@esbuild/android-arm64@0.17.19': + resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.17.19': + resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.17.19': + resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.17.19': + resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.17.19': + resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.17.19': + resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.17.19': + resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.17.19': + resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.17.19': + resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.17.19': + resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.17.19': + resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.17.19': + resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.17.19': + resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.17.19': + resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.17.19': + resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.17.19': + resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.17.19': + resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.17.19': + resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.17.19': + resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.17.19': + resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.17.19': + resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.17.19': + resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + + '@fastify/busboy@3.0.0': + resolution: {integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==} + + '@isaacs/cached@1.0.1': + resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} + + '@isaacs/catcher@1.0.4': + resolution: {integrity: sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + '@jest/schemas@29.6.3': resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@mjackson/headers@0.5.1': + resolution: {integrity: sha512-sJpFgecPT/zJvwk3GRNVWNs8EkwaJoUNU2D0VMlp+gDJs6cuSTm1q/aCZi3ZtuV6CgDEQ4l2ZjUG3A9JrQlbNA==} + + '@mjackson/lazy-file@2.2.0': + resolution: {integrity: sha512-51M2TAL5eMZj5mh1e22/qBl4C5udViZqSBEqwiHSi1lTAixCp4YiAOV62VaTSqVp771OkmgNCPsh8/LpJ/A/Yw==} + + '@mjackson/multipart-parser@0.6.2': + resolution: {integrity: sha512-xG3mINK6gFVposxu83x3n4ueJfjWoxOl3UaBADXNjh/NL84L+Zc/kmz2mTQA9GHvHFPAMlXqPSLTocIDkmhemQ==} + '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} @@ -94,12 +476,40 @@ packages: cpu: [x64] os: [win32] + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} '@tybys/wasm-util@0.9.0': resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + '@types/bun@1.1.8': + resolution: {integrity: sha512-PIwVFQKPviksiibobyvcWtMvMFMTj91T8dQEh9l1P3Ypr3ZuVn9w7HSr+5mTNrPqD1xpdDLEErzZPU8gqHBu6g==} + + '@types/busboy@1.5.4': + resolution: {integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==} + + '@types/node-forge@1.3.11': + resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} + + '@types/node@20.12.14': + resolution: {integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==} + + '@types/node@20.16.1': + resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==} + + '@types/node@22.5.0': + resolution: {integrity: sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==} + + '@types/tmp@0.2.6': + resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} + + '@types/ws@8.5.12': + resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} + '@yarnpkg/lockfile@1.1.0': resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} @@ -111,6 +521,15 @@ packages: resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} hasBin: true + acorn-walk@8.3.3: + resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} + engines: {node: '>=0.4.0'} + + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -119,6 +538,10 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -127,12 +550,23 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + as-table@1.0.55: + resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -145,19 +579,44 @@ packages: 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'} + bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + blake3-wasm@2.1.5: + resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + bun-types@1.1.26: + resolution: {integrity: sha512-n7jDe62LsB2+WE8Q8/mT3azkPaatKlj/2MyP6hi3mKvPz9oPpB6JW/Ll6JHtNLudasFFuvfgklYSE+rreGvBjw==} + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + capnp-ts@0.7.0: + resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -185,6 +644,33 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + + cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + data-uri-to-buffer@2.0.2: + resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} + + date-fns@3.6.0: + resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + + debug@4.3.6: + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} @@ -192,6 +678,9 @@ packages: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -211,9 +700,15 @@ packages: duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} @@ -221,6 +716,11 @@ packages: resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} engines: {node: '>=8.6'} + esbuild@0.17.19: + resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} + engines: {node: '>=12'} + hasBin: true + escalade@3.1.2: resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} engines: {node: '>=6'} @@ -229,15 +729,30 @@ packages: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} hasBin: true + estree-walker@0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + + exit-hook@2.2.1: + resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} + engines: {node: '>=6'} + figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true @@ -251,6 +766,10 @@ packages: debug: optional: true + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -265,10 +784,32 @@ packages: resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} engines: {node: '>=14.14'} + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-source@2.0.12: + resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -276,6 +817,10 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -286,19 +831,39 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} + is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} hasBin: true + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} @@ -307,6 +872,12 @@ packages: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jest-diff@29.7.0: resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -338,6 +909,12 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -346,20 +923,73 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + miniflare@3.20240821.0: + resolution: {integrity: sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==} + engines: {node: '>=16.13'} + hasBin: true + minimatch@9.0.3: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + engines: {node: '>=10'} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + multipasta@0.2.5: + resolution: {integrity: sha512-c8eMDb1WwZcE02WVjHoOmUVk7fnKU/RmUcosHACglrWAuPQsEJv+E8430sXj6jNc1jHw0zrS16aCjQh4BcEb4A==} + + mustache@4.2.0: + resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} + hasBin: true + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + node-fetch-native@1.6.4: + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + node-machine-id@1.1.12: resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} @@ -391,14 +1021,46 @@ packages: resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} engines: {node: '>=10'} + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-to-regexp@6.2.2: + resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + printable-characters@1.0.42: + resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -409,32 +1071,104 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + resolve.exports@2.0.2: + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + + rollup-plugin-inject@3.0.2: + resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. + + rollup-plugin-node-polyfills@0.2.1: + resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} + + rollup-pluginutils@2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + selfsigned@2.4.1: + resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} + engines: {node: '>=10'} + semver@7.6.3: resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} hasBin: true + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sock-daemon@1.4.2: + resolution: {integrity: sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg==} + engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} + + socket-post-message@1.0.3: + resolution: {integrity: sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + stacktracey@2.1.8: + resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} + + stoppable@1.1.0: + resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} + engines: {node: '>=4', npm: '>=6'} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -442,85 +1176,314 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strong-log-transformer@2.1.0: + resolution: {integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==} + engines: {node: '>=4'} + hasBin: true + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + tmp@0.2.3: + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + engines: {node: '>=14.14'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + + tsimp@2.0.11: + resolution: {integrity: sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==} + engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.1.0 + + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + undici@5.28.4: + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} + engines: {node: '>=14.0'} + + unenv-nightly@1.10.0-1717606461.a117952: + resolution: {integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + walk-up-path@3.0.1: + resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + workerd@1.20240821.1: + resolution: {integrity: sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==} + engines: {node: '>=16'} + hasBin: true + + wrangler@3.72.3: + resolution: {integrity: sha512-EBlJGOcwanbzFkiJkRB47WKhvevh1AZK0ty0MyD0gptsgWnAxBfmFGiBuzOuRXbvH45ZrFrTqgi8c67EwcV1nA==} + engines: {node: '>=16.17.0'} + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^4.20240821.1 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xxhash-wasm@1.0.2: + resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + youch@3.3.3: + resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} + + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + +snapshots: + + '@cloudflare/kv-asset-handler@0.3.4': + dependencies: + mime: 3.0.0 + + '@cloudflare/workerd-darwin-64@1.20240821.1': + optional: true + + '@cloudflare/workerd-darwin-arm64@1.20240821.1': + optional: true + + '@cloudflare/workerd-linux-64@1.20240821.1': + optional: true + + '@cloudflare/workerd-linux-arm64@1.20240821.1': + optional: true + + '@cloudflare/workerd-windows-64@1.20240821.1': + optional: true + + '@cloudflare/workers-shared@0.4.0': {} + + '@cloudflare/workers-types@4.20240821.1': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@emnapi/core@1.2.0': + dependencies: + '@emnapi/wasi-threads': 1.0.1 + tslib: 2.7.0 + + '@emnapi/runtime@1.2.0': + dependencies: + tslib: 2.7.0 + + '@emnapi/wasi-threads@1.0.1': + dependencies: + tslib: 2.7.0 + + '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': + dependencies: + esbuild: 0.17.19 + + '@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19)': + dependencies: + esbuild: 0.17.19 + escape-string-regexp: 4.0.0 + rollup-plugin-node-polyfills: 0.2.1 + + '@esbuild/android-arm64@0.17.19': + optional: true + + '@esbuild/android-arm@0.17.19': + optional: true + + '@esbuild/android-x64@0.17.19': + optional: true + + '@esbuild/darwin-arm64@0.17.19': + optional: true + + '@esbuild/darwin-x64@0.17.19': + optional: true + + '@esbuild/freebsd-arm64@0.17.19': + optional: true + + '@esbuild/freebsd-x64@0.17.19': + optional: true - strong-log-transformer@2.1.0: - resolution: {integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==} - engines: {node: '>=4'} - hasBin: true + '@esbuild/linux-arm64@0.17.19': + optional: true - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + '@esbuild/linux-arm@0.17.19': + optional: true - tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} + '@esbuild/linux-ia32@0.17.19': + optional: true - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + '@esbuild/linux-loong64@0.17.19': + optional: true - tmp@0.2.3: - resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} - engines: {node: '>=14.14'} + '@esbuild/linux-mips64el@0.17.19': + optional: true - tsconfig-paths@4.2.0: - resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} - engines: {node: '>=6'} + '@esbuild/linux-ppc64@0.17.19': + optional: true - tslib@2.7.0: - resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + '@esbuild/linux-riscv64@0.17.19': + optional: true - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} + '@esbuild/linux-s390x@0.17.19': + optional: true - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + '@esbuild/linux-x64@0.17.19': + optional: true - wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + '@esbuild/netbsd-x64@0.17.19': + optional: true - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + '@esbuild/openbsd-x64@0.17.19': + optional: true - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + '@esbuild/sunos-x64@0.17.19': + optional: true - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} + '@esbuild/win32-arm64@0.17.19': + optional: true - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} + '@esbuild/win32-ia32@0.17.19': + optional: true - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + '@esbuild/win32-x64@0.17.19': + optional: true -snapshots: + '@fastify/busboy@2.1.1': {} - '@emnapi/core@1.2.0': - dependencies: - '@emnapi/wasi-threads': 1.0.1 - tslib: 2.7.0 + '@fastify/busboy@3.0.0': {} - '@emnapi/runtime@1.2.0': + '@isaacs/cached@1.0.1': dependencies: - tslib: 2.7.0 + '@isaacs/catcher': 1.0.4 - '@emnapi/wasi-threads@1.0.1': + '@isaacs/catcher@1.0.4': {} + + '@isaacs/cliui@8.0.2': dependencies: - tslib: 2.7.0 + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 '@jest/schemas@29.6.3': dependencies: '@sinclair/typebox': 0.27.8 + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@mjackson/headers@0.5.1': {} + + '@mjackson/lazy-file@2.2.0': + dependencies: + mrmime: 2.0.0 + + '@mjackson/multipart-parser@0.6.2': + dependencies: + '@mjackson/headers': 0.5.1 + '@napi-rs/wasm-runtime@0.2.4': dependencies: '@emnapi/core': 1.2.0 @@ -566,12 +1529,45 @@ snapshots: '@nx/nx-win32-x64-msvc@19.6.3': optional: true + '@pkgjs/parseargs@0.11.0': + optional: true + '@sinclair/typebox@0.27.8': {} '@tybys/wasm-util@0.9.0': dependencies: tslib: 2.7.0 + '@types/bun@1.1.8': + dependencies: + bun-types: 1.1.26 + + '@types/busboy@1.5.4': + dependencies: + '@types/node': 22.5.0 + + '@types/node-forge@1.3.11': + dependencies: + '@types/node': 22.5.0 + + '@types/node@20.12.14': + dependencies: + undici-types: 5.26.5 + + '@types/node@20.16.1': + dependencies: + undici-types: 6.19.8 + + '@types/node@22.5.0': + dependencies: + undici-types: 6.19.8 + + '@types/tmp@0.2.6': {} + + '@types/ws@8.5.12': + dependencies: + '@types/node': 22.5.0 + '@yarnpkg/lockfile@1.1.0': {} '@yarnpkg/parsers@3.0.0-rc.46': @@ -583,22 +1579,41 @@ snapshots: dependencies: argparse: 2.0.1 + acorn-walk@8.3.3: + dependencies: + acorn: 8.12.1 + + acorn@8.12.1: {} + ansi-colors@4.1.3: {} ansi-regex@5.0.1: {} + ansi-regex@6.0.1: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 ansi-styles@5.2.0: {} + ansi-styles@6.2.1: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 argparse@2.0.1: {} + as-table@1.0.55: + dependencies: + printable-characters: 1.0.42 + asynckit@0.4.0: {} axios@1.7.5: @@ -613,26 +1628,62 @@ snapshots: base64-js@1.5.1: {} + binary-extensions@2.3.0: {} + bl@4.1.0: dependencies: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.2 + blake3-wasm@2.1.5: {} + brace-expansion@2.0.1: dependencies: balanced-match: 1.0.2 + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + buffer@5.7.1: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 + bun-types@1.1.26: + dependencies: + '@types/node': 20.12.14 + '@types/ws': 8.5.12 + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + capnp-ts@0.7.0: + dependencies: + debug: 4.3.6 + tslib: 2.7.0 + transitivePeerDependencies: + - supports-color + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + cli-cursor@3.1.0: dependencies: restore-cursor: 3.1.0 @@ -657,12 +1708,32 @@ snapshots: dependencies: delayed-stream: 1.0.0 + consola@3.2.3: {} + + cookie@0.5.0: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + data-uri-to-buffer@2.0.2: {} + + date-fns@3.6.0: {} + + debug@4.3.6: + dependencies: + ms: 2.1.2 + defaults@1.0.4: dependencies: clone: 1.0.4 define-lazy-prop@2.0.0: {} + defu@6.1.4: {} + delayed-stream@1.0.0: {} diff-sequences@29.6.3: {} @@ -675,8 +1746,12 @@ snapshots: duplexer@0.1.2: {} + eastasianwidth@0.2.0: {} + emoji-regex@8.0.0: {} + emoji-regex@9.2.2: {} + end-of-stream@1.4.4: dependencies: once: 1.4.0 @@ -685,20 +1760,60 @@ snapshots: dependencies: ansi-colors: 4.1.3 + esbuild@0.17.19: + optionalDependencies: + '@esbuild/android-arm': 0.17.19 + '@esbuild/android-arm64': 0.17.19 + '@esbuild/android-x64': 0.17.19 + '@esbuild/darwin-arm64': 0.17.19 + '@esbuild/darwin-x64': 0.17.19 + '@esbuild/freebsd-arm64': 0.17.19 + '@esbuild/freebsd-x64': 0.17.19 + '@esbuild/linux-arm': 0.17.19 + '@esbuild/linux-arm64': 0.17.19 + '@esbuild/linux-ia32': 0.17.19 + '@esbuild/linux-loong64': 0.17.19 + '@esbuild/linux-mips64el': 0.17.19 + '@esbuild/linux-ppc64': 0.17.19 + '@esbuild/linux-riscv64': 0.17.19 + '@esbuild/linux-s390x': 0.17.19 + '@esbuild/linux-x64': 0.17.19 + '@esbuild/netbsd-x64': 0.17.19 + '@esbuild/openbsd-x64': 0.17.19 + '@esbuild/sunos-x64': 0.17.19 + '@esbuild/win32-arm64': 0.17.19 + '@esbuild/win32-ia32': 0.17.19 + '@esbuild/win32-x64': 0.17.19 + escalade@3.1.2: {} escape-string-regexp@1.0.5: {} + escape-string-regexp@4.0.0: {} + esprima@4.0.1: {} + estree-walker@0.6.1: {} + + exit-hook@2.2.1: {} + figures@3.2.0: dependencies: escape-string-regexp: 1.0.5 + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + flat@5.0.2: {} follow-redirects@1.15.6: {} + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + form-data@4.0.0: dependencies: asynckit: 0.4.0 @@ -717,30 +1832,83 @@ snapshots: jsonfile: 6.1.0 universalify: 2.0.1 + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + get-caller-file@2.0.5: {} + get-source@2.0.12: + dependencies: + data-uri-to-buffer: 2.0.2 + source-map: 0.6.1 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regexp@0.4.1: {} + + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 1.11.1 + graceful-fs@4.2.11: {} has-flag@4.0.0: {} + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + ieee754@1.2.1: {} ignore@5.3.2: {} inherits@2.0.4: {} + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.15.1: + dependencies: + hasown: 2.0.2 + is-docker@2.2.1: {} + is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + is-interactive@1.0.0: {} + is-number@7.0.0: {} + is-unicode-supported@0.1.0: {} is-wsl@2.2.0: dependencies: is-docker: 2.2.1 + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + jest-diff@29.7.0: dependencies: chalk: 4.1.2 @@ -772,22 +1940,73 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + lru-cache@10.4.3: {} + + magic-string@0.25.9: + dependencies: + sourcemap-codec: 1.4.8 + mime-db@1.52.0: {} mime-types@2.1.35: dependencies: mime-db: 1.52.0 + mime@3.0.0: {} + mimic-fn@2.1.0: {} + miniflare@3.20240821.0: + dependencies: + '@cspotcode/source-map-support': 0.8.1 + acorn: 8.12.1 + acorn-walk: 8.3.3 + capnp-ts: 0.7.0 + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + stoppable: 1.1.0 + undici: 5.28.4 + workerd: 1.20240821.1 + ws: 8.18.0 + youch: 3.3.3 + zod: 3.23.8 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + minimatch@9.0.3: dependencies: brace-expansion: 2.0.1 + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + minimist@1.2.8: {} + minipass@7.1.2: {} + + mkdirp@3.0.1: {} + + mrmime@2.0.0: {} + + ms@2.1.2: {} + + multipasta@0.2.5: {} + + mustache@4.2.0: {} + + nanoid@3.3.7: {} + + node-fetch-native@1.6.4: {} + + node-forge@1.3.1: {} + node-machine-id@1.1.12: {} + normalize-path@3.0.0: {} + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 @@ -868,14 +2087,35 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 + package-json-from-dist@1.0.0: {} + path-key@3.1.1: {} + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-to-regexp@6.2.2: {} + + pathe@1.1.2: {} + + picomatch@2.3.1: {} + + pirates@4.0.6: {} + + prettier@3.3.3: {} + pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 react-is: 18.3.1 + printable-characters@1.0.42: {} + proxy-from-env@1.1.0: {} react-is@18.3.1: {} @@ -886,27 +2126,97 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + require-directory@2.1.1: {} + resolve.exports@2.0.2: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.15.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + restore-cursor@3.1.0: dependencies: onetime: 5.1.2 signal-exit: 3.0.7 + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + + rollup-plugin-inject@3.0.2: + dependencies: + estree-walker: 0.6.1 + magic-string: 0.25.9 + rollup-pluginutils: 2.8.2 + + rollup-plugin-node-polyfills@0.2.1: + dependencies: + rollup-plugin-inject: 3.0.2 + + rollup-pluginutils@2.8.2: + dependencies: + estree-walker: 0.6.1 + safe-buffer@5.2.1: {} + selfsigned@2.4.1: + dependencies: + '@types/node-forge': 1.3.11 + node-forge: 1.3.1 + semver@7.6.3: {} + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + signal-exit@3.0.7: {} + signal-exit@4.1.0: {} + + sock-daemon@1.4.2: + dependencies: + rimraf: 5.0.10 + signal-exit: 4.1.0 + socket-post-message: 1.0.3 + + socket-post-message@1.0.3: {} + + source-map@0.6.1: {} + + sourcemap-codec@1.4.8: {} + sprintf-js@1.0.3: {} + stacktracey@2.1.8: + dependencies: + as-table: 1.0.55 + get-source: 2.0.12 + + stoppable@1.1.0: {} + + streamsearch@1.1.0: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -915,6 +2225,10 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + strip-bom@3.0.0: {} strong-log-transformer@2.1.0: @@ -927,6 +2241,8 @@ snapshots: dependencies: has-flag: 4.0.0 + supports-preserve-symlinks-flag@1.0.0: {} + tar-stream@2.2.0: dependencies: bl: 4.1.0 @@ -939,30 +2255,120 @@ snapshots: tmp@0.2.3: {} + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + tsconfig-paths@4.2.0: dependencies: json5: 2.2.3 minimist: 1.2.8 strip-bom: 3.0.0 + tsimp@2.0.11(typescript@5.5.4): + dependencies: + '@isaacs/cached': 1.0.1 + '@isaacs/catcher': 1.0.4 + foreground-child: 3.3.0 + mkdirp: 3.0.1 + pirates: 4.0.6 + rimraf: 5.0.10 + signal-exit: 4.1.0 + sock-daemon: 1.4.2 + typescript: 5.5.4 + walk-up-path: 3.0.1 + tslib@2.7.0: {} + typescript@5.5.4: {} + + ufo@1.5.4: {} + + undici-types@5.26.5: {} + + undici-types@6.19.8: {} + + undici@5.28.4: + dependencies: + '@fastify/busboy': 2.1.1 + + unenv-nightly@1.10.0-1717606461.a117952: + dependencies: + consola: 3.2.3 + defu: 6.1.4 + mime: 3.0.0 + node-fetch-native: 1.6.4 + pathe: 1.1.2 + ufo: 1.5.4 + universalify@2.0.1: {} util-deprecate@1.0.2: {} + walk-up-path@3.0.1: {} + wcwidth@1.0.1: dependencies: defaults: 1.0.4 + which@2.0.2: + dependencies: + isexe: 2.0.0 + + workerd@1.20240821.1: + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20240821.1 + '@cloudflare/workerd-darwin-arm64': 1.20240821.1 + '@cloudflare/workerd-linux-64': 1.20240821.1 + '@cloudflare/workerd-linux-arm64': 1.20240821.1 + '@cloudflare/workerd-windows-64': 1.20240821.1 + + wrangler@3.72.3(@cloudflare/workers-types@4.20240821.1): + dependencies: + '@cloudflare/kv-asset-handler': 0.3.4 + '@cloudflare/workers-shared': 0.4.0 + '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) + '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) + blake3-wasm: 2.1.5 + chokidar: 3.6.0 + date-fns: 3.6.0 + esbuild: 0.17.19 + miniflare: 3.20240821.0 + nanoid: 3.3.7 + path-to-regexp: 6.2.2 + resolve: 1.22.8 + resolve.exports: 2.0.2 + selfsigned: 2.4.1 + source-map: 0.6.1 + unenv: unenv-nightly@1.10.0-1717606461.a117952 + workerd: 1.20240821.1 + xxhash-wasm: 1.0.2 + optionalDependencies: + '@cloudflare/workers-types': 4.20240821.1 + fsevents: 2.3.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + wrappy@1.0.2: {} + ws@8.18.0: {} + + xxhash-wasm@1.0.2: {} + y18n@5.0.8: {} yargs-parser@21.1.1: {} @@ -976,3 +2382,11 @@ snapshots: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 + + youch@3.3.3: + dependencies: + cookie: 0.5.0 + mustache: 4.2.0 + stacktracey: 2.1.8 + + zod@3.23.8: {} From 4c55cade06090f379ef5b9e7861dffa8c4afa6ac Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 17:38:57 -0700 Subject: [PATCH 354/730] Prep for monorepo migration --- .github/workflows/publish.yml | 32 -- .gitignore | 5 - .prettierrc | 4 - CHANGELOG.md => packages/headers/CHANGELOG.md | 0 LICENSE => packages/headers/LICENSE | 0 README.md => packages/headers/README.md | 0 package.json => packages/headers/package.json | 0 {src => packages/headers/src}/headers.ts | 0 .../headers/src}/lib/accept-language.spec.ts | 0 .../headers/src}/lib/accept-language.ts | 0 .../headers/src}/lib/cache-control.spec.ts | 0 .../headers/src}/lib/cache-control.ts | 0 .../src}/lib/content-disposition.spec.ts | 0 .../headers/src}/lib/content-disposition.ts | 0 .../headers/src}/lib/content-type.spec.ts | 0 .../headers/src}/lib/content-type.ts | 0 .../headers/src}/lib/cookie.spec.ts | 0 {src => packages/headers/src}/lib/cookie.ts | 0 .../headers/src}/lib/header-names.spec.ts | 0 .../headers/src}/lib/header-names.ts | 0 .../headers/src}/lib/header-value.ts | 0 .../headers/src}/lib/param-values.spec.ts | 0 .../headers/src}/lib/param-values.ts | 0 .../headers/src}/lib/set-cookie.spec.ts | 0 .../headers/src}/lib/set-cookie.ts | 0 .../headers/src}/lib/super-headers.spec.ts | 0 .../headers/src}/lib/super-headers.ts | 0 {src => packages/headers/src}/lib/utils.ts | 0 .../headers/tsconfig.json | 0 .../headers/tsconfig.lib.json | 0 .../headers/tsconfig.spec.json | 0 pnpm-lock.yaml | 388 ------------------ scripts/version.js | 30 -- 33 files changed, 459 deletions(-) delete mode 100644 .github/workflows/publish.yml delete mode 100644 .gitignore delete mode 100644 .prettierrc rename CHANGELOG.md => packages/headers/CHANGELOG.md (100%) rename LICENSE => packages/headers/LICENSE (100%) rename README.md => packages/headers/README.md (100%) rename package.json => packages/headers/package.json (100%) rename {src => packages/headers/src}/headers.ts (100%) rename {src => packages/headers/src}/lib/accept-language.spec.ts (100%) rename {src => packages/headers/src}/lib/accept-language.ts (100%) rename {src => packages/headers/src}/lib/cache-control.spec.ts (100%) rename {src => packages/headers/src}/lib/cache-control.ts (100%) rename {src => packages/headers/src}/lib/content-disposition.spec.ts (100%) rename {src => packages/headers/src}/lib/content-disposition.ts (100%) rename {src => packages/headers/src}/lib/content-type.spec.ts (100%) rename {src => packages/headers/src}/lib/content-type.ts (100%) rename {src => packages/headers/src}/lib/cookie.spec.ts (100%) rename {src => packages/headers/src}/lib/cookie.ts (100%) rename {src => packages/headers/src}/lib/header-names.spec.ts (100%) rename {src => packages/headers/src}/lib/header-names.ts (100%) rename {src => packages/headers/src}/lib/header-value.ts (100%) rename {src => packages/headers/src}/lib/param-values.spec.ts (100%) rename {src => packages/headers/src}/lib/param-values.ts (100%) rename {src => packages/headers/src}/lib/set-cookie.spec.ts (100%) rename {src => packages/headers/src}/lib/set-cookie.ts (100%) rename {src => packages/headers/src}/lib/super-headers.spec.ts (100%) rename {src => packages/headers/src}/lib/super-headers.ts (100%) rename {src => packages/headers/src}/lib/utils.ts (100%) rename tsconfig.json => packages/headers/tsconfig.json (100%) rename tsconfig.lib.json => packages/headers/tsconfig.lib.json (100%) rename tsconfig.spec.json => packages/headers/tsconfig.spec.json (100%) delete mode 100644 pnpm-lock.yaml delete mode 100644 scripts/version.js diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 1e2ee68c8b4..00000000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Publish - -on: - push: - tags: - - v[0-9]* - -jobs: - build: - runs-on: ubuntu-latest - - permissions: - contents: read - id-token: write - - steps: - - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - - - uses: actions/setup-node@v4 - with: - node-version: '20.x' - registry-url: 'https://registry.npmjs.org' - cache: 'pnpm' - - - run: pnpm install - - - name: Publish to npm - run: npm publish --provenance --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore deleted file mode 100644 index c9282d7e5e3..00000000000 --- a/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.tsimp -dist -node_modules - -*.tsbuildinfo \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index f018274ffc2..00000000000 --- a/.prettierrc +++ /dev/null @@ -1,4 +0,0 @@ -printWidth: 100 -semi: true -singleQuote: true -useTabs: false diff --git a/CHANGELOG.md b/packages/headers/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to packages/headers/CHANGELOG.md diff --git a/LICENSE b/packages/headers/LICENSE similarity index 100% rename from LICENSE rename to packages/headers/LICENSE diff --git a/README.md b/packages/headers/README.md similarity index 100% rename from README.md rename to packages/headers/README.md diff --git a/package.json b/packages/headers/package.json similarity index 100% rename from package.json rename to packages/headers/package.json diff --git a/src/headers.ts b/packages/headers/src/headers.ts similarity index 100% rename from src/headers.ts rename to packages/headers/src/headers.ts diff --git a/src/lib/accept-language.spec.ts b/packages/headers/src/lib/accept-language.spec.ts similarity index 100% rename from src/lib/accept-language.spec.ts rename to packages/headers/src/lib/accept-language.spec.ts diff --git a/src/lib/accept-language.ts b/packages/headers/src/lib/accept-language.ts similarity index 100% rename from src/lib/accept-language.ts rename to packages/headers/src/lib/accept-language.ts diff --git a/src/lib/cache-control.spec.ts b/packages/headers/src/lib/cache-control.spec.ts similarity index 100% rename from src/lib/cache-control.spec.ts rename to packages/headers/src/lib/cache-control.spec.ts diff --git a/src/lib/cache-control.ts b/packages/headers/src/lib/cache-control.ts similarity index 100% rename from src/lib/cache-control.ts rename to packages/headers/src/lib/cache-control.ts diff --git a/src/lib/content-disposition.spec.ts b/packages/headers/src/lib/content-disposition.spec.ts similarity index 100% rename from src/lib/content-disposition.spec.ts rename to packages/headers/src/lib/content-disposition.spec.ts diff --git a/src/lib/content-disposition.ts b/packages/headers/src/lib/content-disposition.ts similarity index 100% rename from src/lib/content-disposition.ts rename to packages/headers/src/lib/content-disposition.ts diff --git a/src/lib/content-type.spec.ts b/packages/headers/src/lib/content-type.spec.ts similarity index 100% rename from src/lib/content-type.spec.ts rename to packages/headers/src/lib/content-type.spec.ts diff --git a/src/lib/content-type.ts b/packages/headers/src/lib/content-type.ts similarity index 100% rename from src/lib/content-type.ts rename to packages/headers/src/lib/content-type.ts diff --git a/src/lib/cookie.spec.ts b/packages/headers/src/lib/cookie.spec.ts similarity index 100% rename from src/lib/cookie.spec.ts rename to packages/headers/src/lib/cookie.spec.ts diff --git a/src/lib/cookie.ts b/packages/headers/src/lib/cookie.ts similarity index 100% rename from src/lib/cookie.ts rename to packages/headers/src/lib/cookie.ts diff --git a/src/lib/header-names.spec.ts b/packages/headers/src/lib/header-names.spec.ts similarity index 100% rename from src/lib/header-names.spec.ts rename to packages/headers/src/lib/header-names.spec.ts diff --git a/src/lib/header-names.ts b/packages/headers/src/lib/header-names.ts similarity index 100% rename from src/lib/header-names.ts rename to packages/headers/src/lib/header-names.ts diff --git a/src/lib/header-value.ts b/packages/headers/src/lib/header-value.ts similarity index 100% rename from src/lib/header-value.ts rename to packages/headers/src/lib/header-value.ts diff --git a/src/lib/param-values.spec.ts b/packages/headers/src/lib/param-values.spec.ts similarity index 100% rename from src/lib/param-values.spec.ts rename to packages/headers/src/lib/param-values.spec.ts diff --git a/src/lib/param-values.ts b/packages/headers/src/lib/param-values.ts similarity index 100% rename from src/lib/param-values.ts rename to packages/headers/src/lib/param-values.ts diff --git a/src/lib/set-cookie.spec.ts b/packages/headers/src/lib/set-cookie.spec.ts similarity index 100% rename from src/lib/set-cookie.spec.ts rename to packages/headers/src/lib/set-cookie.spec.ts diff --git a/src/lib/set-cookie.ts b/packages/headers/src/lib/set-cookie.ts similarity index 100% rename from src/lib/set-cookie.ts rename to packages/headers/src/lib/set-cookie.ts diff --git a/src/lib/super-headers.spec.ts b/packages/headers/src/lib/super-headers.spec.ts similarity index 100% rename from src/lib/super-headers.spec.ts rename to packages/headers/src/lib/super-headers.spec.ts diff --git a/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts similarity index 100% rename from src/lib/super-headers.ts rename to packages/headers/src/lib/super-headers.ts diff --git a/src/lib/utils.ts b/packages/headers/src/lib/utils.ts similarity index 100% rename from src/lib/utils.ts rename to packages/headers/src/lib/utils.ts diff --git a/tsconfig.json b/packages/headers/tsconfig.json similarity index 100% rename from tsconfig.json rename to packages/headers/tsconfig.json diff --git a/tsconfig.lib.json b/packages/headers/tsconfig.lib.json similarity index 100% rename from tsconfig.lib.json rename to packages/headers/tsconfig.lib.json diff --git a/tsconfig.spec.json b/packages/headers/tsconfig.spec.json similarity index 100% rename from tsconfig.spec.json rename to packages/headers/tsconfig.spec.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index 8f8380b0963..00000000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,388 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - devDependencies: - '@types/node': - specifier: ^20.14.10 - version: 20.14.10 - prettier: - specifier: ^3.3.3 - version: 3.3.3 - tsimp: - specifier: ^2.0.11 - version: 2.0.11(typescript@5.5.3) - typescript: - specifier: ^5.5.3 - version: 5.5.3 - -packages: - - '@isaacs/cached@1.0.1': - resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} - - '@isaacs/catcher@1.0.4': - resolution: {integrity: sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA==} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@types/node@20.14.10': - resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - foreground-child@3.2.1: - resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} - engines: {node: '>=14'} - - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - mkdirp@3.0.1: - resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} - engines: {node: '>=10'} - hasBin: true - - package-json-from-dist@1.0.0: - resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} - engines: {node: '>= 6'} - - prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} - engines: {node: '>=14'} - hasBin: true - - rimraf@5.0.9: - resolution: {integrity: sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==} - engines: {node: 14 >=14.20 || 16 >=16.20 || >=18} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - sock-daemon@1.4.2: - resolution: {integrity: sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg==} - engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} - - socket-post-message@1.0.3: - resolution: {integrity: sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - tsimp@2.0.11: - resolution: {integrity: sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==} - engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} - hasBin: true - peerDependencies: - typescript: ^5.1.0 - - typescript@5.5.3: - resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} - engines: {node: '>=14.17'} - hasBin: true - - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - walk-up-path@3.0.1: - resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - -snapshots: - - '@isaacs/cached@1.0.1': - dependencies: - '@isaacs/catcher': 1.0.4 - - '@isaacs/catcher@1.0.4': {} - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@types/node@20.14.10': - dependencies: - undici-types: 5.26.5 - - ansi-regex@5.0.1: {} - - ansi-regex@6.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.1: {} - - balanced-match@1.0.2: {} - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - eastasianwidth@0.2.0: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - foreground-child@3.2.1: - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - - glob@10.4.5: - dependencies: - foreground-child: 3.2.1 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.0 - path-scurry: 1.11.1 - - is-fullwidth-code-point@3.0.0: {} - - isexe@2.0.0: {} - - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - lru-cache@10.4.3: {} - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.1 - - minipass@7.1.2: {} - - mkdirp@3.0.1: {} - - package-json-from-dist@1.0.0: {} - - path-key@3.1.1: {} - - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 - - pirates@4.0.6: {} - - prettier@3.3.3: {} - - rimraf@5.0.9: - dependencies: - glob: 10.4.5 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - signal-exit@4.1.0: {} - - sock-daemon@1.4.2: - dependencies: - rimraf: 5.0.9 - signal-exit: 4.1.0 - socket-post-message: 1.0.3 - - socket-post-message@1.0.3: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.0.1 - - tsimp@2.0.11(typescript@5.5.3): - dependencies: - '@isaacs/cached': 1.0.1 - '@isaacs/catcher': 1.0.4 - foreground-child: 3.2.1 - mkdirp: 3.0.1 - pirates: 4.0.6 - rimraf: 5.0.9 - signal-exit: 4.1.0 - sock-daemon: 1.4.2 - typescript: 5.5.3 - walk-up-path: 3.0.1 - - typescript@5.5.3: {} - - undici-types@5.26.5: {} - - walk-up-path@3.0.1: {} - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 diff --git a/scripts/version.js b/scripts/version.js deleted file mode 100644 index 960e20efa91..00000000000 --- a/scripts/version.js +++ /dev/null @@ -1,30 +0,0 @@ -import * as cp from 'node:child_process'; -import * as fs from 'node:fs'; -import * as path from 'node:path'; -import * as process from 'node:process'; - -const __dirname = path.dirname(new URL(import.meta.url).pathname); -const packageVersion = process.env.npm_package_version; - -// Update CHANGELOG.md with the current version -let changelogPath = path.resolve(__dirname, '../CHANGELOG.md'); -let changelog = fs.readFileSync(changelogPath, 'utf-8'); -let match = /^## HEAD\n/m.exec(changelog); -if (match) { - let today = new Date().toLocaleDateString('en-US', { - month: 'short', - day: 'numeric', - year: 'numeric', - }); - - changelog = - changelog.slice(0, match.index) + - `## v${packageVersion} (${today})\n` + - changelog.slice(match.index + match[0].length); - - fs.writeFileSync(changelogPath, changelog); - cp.execSync('git add CHANGELOG.md'); -} else { - console.error('Could not find "## HEAD" in CHANGELOG.md'); - process.exit(1); -} From 7d25edc057ae66b96892c44f456bdacbab770e8e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 17:42:42 -0700 Subject: [PATCH 355/730] Update headers package metadata --- packages/headers/package.json | 8 +++----- pnpm-lock.yaml | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/headers/package.json b/packages/headers/package.json index 0784530bcb2..de34f3f9a10 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -6,7 +6,8 @@ "license": "MIT", "repository": { "type": "git", - "url": "git+https://github.com/mjackson/headers.git" + "url": "git+https://github.com/mjackson/remix-the-web.git", + "directory": "packages/headers" }, "files": [ "dist", @@ -25,13 +26,10 @@ "typescript": "^5.5.3" }, "scripts": { - "clean": "git clean -fdX .", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import tsimp/import --test ./src/**/*.spec.ts", - "prepare": "npm run build", - "version": "node scripts/version.js" + "prepare": "pnpm run build" }, - "packageManager": "pnpm@9.4.0", "keywords": [ "fetch", "http", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 89bd384a040..bcdaa6edf19 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,6 +50,21 @@ importers: specifier: ^5.5.4 version: 5.5.4 + packages/headers: + devDependencies: + '@types/node': + specifier: ^20.14.10 + version: 20.16.1 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + tsimp: + specifier: ^2.0.11 + version: 2.0.11(typescript@5.5.4) + typescript: + specifier: ^5.5.3 + version: 5.5.4 + packages/lazy-file: dependencies: mrmime: From ab7a221a89876f5acfea5deaa3b4e383315666b4 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 19:05:35 -0700 Subject: [PATCH 356/730] Add README --- LICENSE | 21 +++++ README.md | 21 +++++ packages/file-storage/README.md | 6 +- packages/form-data-parser/README.md | 8 +- packages/form-data-parser/package.json | 2 +- packages/headers/README.md | 112 +++++++++++++------------ packages/lazy-file/README.md | 4 +- packages/multipart-parser/README.md | 53 ++++++------ 8 files changed, 139 insertions(+), 88 deletions(-) create mode 100644 LICENSE create mode 100644 README.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..717984c0442 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Michael Jackson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 00000000000..359972d13b2 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +This repository is a collection of packages for use with [Remix](https://remix.run) or any web framework you choose. + +## Philosophy + +The packages in this repository are designed around the [single responsibility principle](https://en.wikipedia.org/wiki/Single-responsibility_principle); they each do one thing really well. Where existing web standards and APIs exist, we build on them in creative ways to expand and extend their functionality. Where new APIs are needed, we design theme to interoperate seamlessly with existing standards. + +The goal is that these libraries should be really useful for anyone who is building for the web. If you're using [Remix](https://remix.run), we've designed it from the start to work with web standards. If you're using some other framework, you should easily be able to integrate these tools into your workflow as well without going full-blown Remix. + +## Packages + +We currently publish the following packages: + +- [file-storage](packages/file-storage): Key/value storage for JavaScript `File` objects +- [form-data-parser](packages/form-data-parser): A `request.formData()` wrapper with streaming file upload handling +- [headers](packages/headers): A toolkit for working with HTTP headers in JavaScript +- [lazy-file](packages/lazy-file): Lazy, streaming `Blob`s and `File`s for JavaScript +- [multipart-parser](packages/multipart-parser): Fast, efficient parser for multipart streams + +## License + +See [LICENSE](https://github.com/mjackson/remix-the-web/blob/main/LICENSE) diff --git a/packages/file-storage/README.md b/packages/file-storage/README.md index 75663f3b40e..14ffb5182d0 100644 --- a/packages/file-storage/README.md +++ b/packages/file-storage/README.md @@ -75,9 +75,9 @@ class CustomFileStorage implements FileStorage { ## Related Packages -- [`form-data-parser`](https://github.com/mjackson/form-data-parser) - Pairs well with this library for storing `FileUpload` objects received in `multipart/form-data` requests -- [`lazy-file`](https://github.com/mjackson/lazy-file) - The streaming `File` implementation used internally to stream files from storage +- [`form-data-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser) - Pairs well with this library for storing `FileUpload` objects received in `multipart/form-data` requests +- [`lazy-file`](https://github.com/mjackson/remix-the-web/tree/main/packages/lazy-file) - The streaming `File` implementation used internally to stream files from storage ## License -See [LICENSE](https://github.com/mjackson/file-storage/blob/main/LICENSE) +See [LICENSE](https://github.com/mjackson/remix-the-web/blob/main/LICENSE) diff --git a/packages/form-data-parser/README.md b/packages/form-data-parser/README.md index 49ac4730a2e..c87f40a868f 100644 --- a/packages/form-data-parser/README.md +++ b/packages/form-data-parser/README.md @@ -1,6 +1,6 @@ # form-data-parser -`form-data-parser` is a wrapper around `request.formData()` that provides pluggable support for file upload handling. This is useful in server contexts where large files should be streamed to disk or some cloud storage service like [AWS S3](https://aws.amazon.com/s3/) or [Cloudflare R2](https://www.cloudflare.com/developer-platform/r2/) instead of being buffered in memory. +`form-data-parser` is a wrapper around `request.formData()` that provides streaming support for handling file uploads. This is useful in server contexts where large files should be streamed to disk or some cloud storage service like [AWS S3](https://aws.amazon.com/s3/) or [Cloudflare R2](https://www.cloudflare.com/developer-platform/r2/) instead of being buffered in memory. ## Features @@ -62,9 +62,9 @@ async function requestHandler(request: Request) { ## Related Packages -- [`multipart-parser`](https://github.com/mjackson/multipart-parser) - The parser used internally for parsing `multipart/form-data` HTTP messages -- [`file-storage`](https://github.com/mjackson/file-storage) - A simple interface for storing `FileUpload` objects you get from the parser +- [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser) - The parser used internally for parsing `multipart/form-data` HTTP messages +- [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage) - A simple interface for storing `FileUpload` objects you get from the parser ## License -See [LICENSE](https://github.com/mjackson/form-data-parser/blob/main/LICENSE) +See [LICENSE](https://github.com/mjackson/remix-the-web/blob/main/LICENSE) diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index aa480dc49a9..dc43682a019 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -1,7 +1,7 @@ { "name": "@mjackson/form-data-parser", "version": "0.1.0", - "description": "A request.formData() wrapper with pluggable file upload handling", + "description": "A request.formData() wrapper with streaming file upload handling", "author": "Michael Jackson ", "repository": { "type": "git", diff --git a/packages/headers/README.md b/packages/headers/README.md index ebd64e19931..360e115021f 100644 --- a/packages/headers/README.md +++ b/packages/headers/README.md @@ -20,31 +20,31 @@ npm install @mjackson/headers ## Overview ```ts -import Headers from '@mjackson/headers'; +import Headers from "@mjackson/headers"; let headers = new Headers(); // Accept-Language -headers.acceptLanguage = 'en-US,en;q=0.9'; +headers.acceptLanguage = "en-US,en;q=0.9"; console.log(headers.acceptLanguage.languages); // [ 'en-US', 'en' ] console.log(headers.acceptLanguage.entries()); // [Map Entries] { [ 'en-US', 1 ], [ 'en', 0.9 ] } // Content-Type -headers.contentType = 'application/json; charset=utf-8'; +headers.contentType = "application/json; charset=utf-8"; console.log(headers.contentType.mediaType); // "application/json" console.log(headers.contentType.charset); // "utf-8" -headers.contentType.charset = 'iso-8859-1'; +headers.contentType.charset = "iso-8859-1"; -console.log(headers.get('Content-Type')); // "application/json; charset=iso-8859-1" +console.log(headers.get("Content-Type")); // "application/json; charset=iso-8859-1" // Content-Disposition headers.contentDisposition = - 'attachment; filename="example.pdf"; filename*=UTF-8\'\'%E4%BE%8B%E5%AD%90.pdf'; + "attachment; filename=\"example.pdf\"; filename*=UTF-8''%E4%BE%8B%E5%AD%90.pdf"; console.log(headers.contentDisposition.type); // 'attachment' console.log(headers.contentDisposition.filename); // 'example.pdf' @@ -52,16 +52,16 @@ console.log(headers.contentDisposition.filenameSplat); // 'UTF-8\'\'%E4%BE%8B%E5 console.log(headers.contentDisposition.preferredFilename); // '例子.pdf' // Cookie -headers.cookie = 'session_id=abc123; user_id=12345'; +headers.cookie = "session_id=abc123; user_id=12345"; -console.log(headers.cookie.get('session_id')); // 'abc123' -console.log(headers.cookie.get('user_id')); // '12345' +console.log(headers.cookie.get("session_id")); // 'abc123' +console.log(headers.cookie.get("user_id")); // '12345' -headers.cookie.set('theme', 'dark'); -console.log(headers.get('Cookie')); // 'session_id=abc123; user_id=12345; theme=dark' +headers.cookie.set("theme", "dark"); +console.log(headers.get("Cookie")); // 'session_id=abc123; user_id=12345; theme=dark' // Set-Cookie -headers.setCookie = 'session_id=abc123; Path=/; HttpOnly'; +headers.setCookie = "session_id=abc123; Path=/; HttpOnly"; console.log(headers.setCookie.name); // 'session_id' console.log(headers.setCookie.value); // 'abc123' @@ -72,11 +72,11 @@ console.log(headers.setCookie.httpOnly); // true headers.setCookie.maxAge = 3600; headers.setCookie.secure = true; -console.log(headers.get('Set-Cookie')); +console.log(headers.get("Set-Cookie")); // session_id=abc123; Path=/; HttpOnly; Max-Age=3600; Secure // Setting multiple cookies -headers.append('Set-Cookie', 'user_id=12345; Path=/api; Secure'); +headers.append("Set-Cookie", "user_id=12345; Path=/api; Secure"); // Accessing multiple Set-Cookie headers for (let cookie of headers.getSetCookie()) { @@ -91,13 +91,13 @@ for (let cookie of headers.getSetCookie()) { ```ts let headers = new Headers({ contentType: { - mediaType: 'text/html', - charset: 'utf-8', + mediaType: "text/html", + charset: "utf-8" }, setCookie: [ - { name: 'session', value: 'abc', path: '/' }, - { name: 'theme', value: 'dark', expires: new Date('2021-12-31T23:59:59Z') }, - ], + { name: "session", value: "abc", path: "/" }, + { name: "theme", value: "dark", expires: new Date("2021-12-31T23:59:59Z") } + ] }); console.log(`${headers}`); @@ -109,18 +109,18 @@ console.log(`${headers}`); `Headers` works just like [DOM's `Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers) (it's a subclass) so you can use them anywhere you need a `Headers`. ```ts -import Headers from '@mjackson/headers'; +import Headers from "@mjackson/headers"; // Use in a fetch() -let response = await fetch('https://example.com', { - headers: new Headers(), +let response = await fetch("https://example.com", { + headers: new Headers() }); // Convert from DOM Headers let headers = new Headers(response.headers); -headers.set('Content-Type', 'text/html'); -headers.get('Content-Type'); // "text/html" +headers.set("Content-Type", "text/html"); +headers.get("Content-Type"); // "text/html" ``` If you're familiar with using DOM `Headers`, everything works as you'd expect. @@ -129,9 +129,9 @@ If you're familiar with using DOM `Headers`, everything works as you'd expect. ```ts let headers = new Headers({ - 'Content-Type': 'application/json', - 'X-API-Key': 'secret-key', - 'Accept-Language': 'en-US,en;q=0.9', + "Content-Type": "application/json", + "X-API-Key": "secret-key", + "Accept-Language": "en-US,en;q=0.9" }); for (let [name, value] of headers) { @@ -146,8 +146,8 @@ If you're assembling HTTP messages, you can easily convert to a multiline string ```ts let headers = new Headers({ - 'Content-Type': 'application/json', - 'Accept-Language': 'en-US,en;q=0.9', + "Content-Type": "application/json", + "Accept-Language": "en-US,en;q=0.9" }); console.log(`${headers}`); @@ -170,32 +170,32 @@ The following headers are currently supported: - [`Cookie`](#cookie) - [`Set-Cookie`](#set-cookie) -If you need support for a header that isn't listed here, please [send a PR](https://github.com/mjackson/headers/pulls)! The goal is to have first-class support for all common HTTP headers. +If you need support for a header that isn't listed here, please [send a PR](https://github.com/mjackson/remix-the-web/pulls)! The goal is to have first-class support for all common HTTP headers. ### Accept-Language ```ts -let header = new AcceptLanguage('en-US,en;q=0.9'); -header.get('en-US'); // 1 -header.set('en-US', 0.8); -header.delete('en-US'); -header.has('en'); // true +let header = new AcceptLanguage("en-US,en;q=0.9"); +header.get("en-US"); // 1 +header.set("en-US", 0.8); +header.delete("en-US"); +header.has("en"); // true // Iterate over language/quality pairs for (let [language, quality] of header) { // ... } -let header = new AcceptLanguage(['en-US', ['en', 0.9]]); -let header = new AcceptLanguage({ 'en-US': 1, en: 0.9 }); +let header = new AcceptLanguage(["en-US", ["en", 0.9]]); +let header = new AcceptLanguage({ "en-US": 1, en: 0.9 }); ``` ### Cache-Control ```ts -import { CacheControl } from '@mjackson/headers'; +import { CacheControl } from "@mjackson/headers"; -let header = new CacheControl('public, max-age=3600, s-maxage=3600'); +let header = new CacheControl("public, max-age=3600, s-maxage=3600"); header.public; // true header.maxAge; // 3600 header.sMaxage; // 3600 @@ -204,9 +204,11 @@ header.sMaxage; // 3600 ### Content-Disposition ```ts -import { ContentDisposition } from '@mjackson/headers'; +import { ContentDisposition } from "@mjackson/headers"; -let header = new ContentDisposition('attachment; name=file1; filename=file1.txt'); +let header = new ContentDisposition( + "attachment; name=file1; filename=file1.txt" +); header.type; // "attachment" header.name; // "file1" header.filename; // "file1.txt" @@ -216,29 +218,29 @@ header.preferredFilename; // "file1.txt" ### Content-Type ```ts -import { ContentType } from '@mjackson/headers'; +import { ContentType } from "@mjackson/headers"; -let header = new ContentType('text/html; charset=utf-8'); +let header = new ContentType("text/html; charset=utf-8"); header.mediaType; // "text/html" header.boundary; // undefined header.charset; // "utf-8" let header = new ContentType({ - mediaType: 'multipart/form-data', - boundary: '------WebKitFormBoundary12345', + mediaType: "multipart/form-data", + boundary: "------WebKitFormBoundary12345" }); ``` ### Cookie ```ts -import { Cookie } from '@mjackson/headers'; +import { Cookie } from "@mjackson/headers"; -let header = new Cookie('theme=dark; session_id=123'); -header.get('theme'); // "dark" -header.set('theme', 'light'); -header.delete('theme'); -header.has('session_id'); // true +let header = new Cookie("theme=dark; session_id=123"); +header.get("theme"); // "dark" +header.set("theme", "light"); +header.delete("theme"); +header.has("session_id"); // true // Iterate over cookie name/value pairs for (let [name, value] of header) { @@ -249,9 +251,11 @@ for (let [name, value] of header) { ### Set-Cookie ```ts -import { SetCookie } from '@mjackson/headers'; +import { SetCookie } from "@mjackson/headers"; -let header = new SetCookie('session_id=abc; Domain=example.com; Path=/; Secure; HttpOnly'); +let header = new SetCookie( + "session_id=abc; Domain=example.com; Path=/; Secure; HttpOnly" +); header.name; // "session_id" header.value; // "abc" header.domain; // "example.com" @@ -265,4 +269,4 @@ header.expires; // undefined ## License -See [LICENSE](https://github.com/mjackson/headers/blob/main/LICENSE) +See [LICENSE](https://github.com/mjackson/remix-the-web/blob/main/LICENSE) diff --git a/packages/lazy-file/README.md b/packages/lazy-file/README.md index 19e05766d9a..0627489b2a3 100644 --- a/packages/lazy-file/README.md +++ b/packages/lazy-file/README.md @@ -91,8 +91,8 @@ let blob = imageFile.slice(100); ## Related Packages -- [`file-storage`](https://github.com/mjackson/file-storage) - Uses `lazy-file/fs` internally to create streaming `File` objects from storage on disk +- [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage) - Uses `lazy-file/fs` internally to create streaming `File` objects from storage on disk ## License -See [LICENSE](https://github.com/mjackson/lazy-file/blob/main/LICENSE) +See [LICENSE](https://github.com/mjackson/remix-the-web/blob/main/LICENSE) diff --git a/packages/multipart-parser/README.md b/packages/multipart-parser/README.md index 67a3172728a..412d6c239ea 100644 --- a/packages/multipart-parser/README.md +++ b/packages/multipart-parser/README.md @@ -8,12 +8,11 @@ ## Features -- Runs anywhere JavaScript runs (see [examples for Node.js, Bun, Deno, and Cloudflare - Workers](https://github.com/mjackson/multipart-parser/tree/main/examples)) +- Runs anywhere JavaScript runs (see [examples for Node.js, Bun, Deno, and Cloudflare Workers](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples)) - Built on the standard [web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) - Supports the entire spectrum of `multipart/*` message types - Memory efficient and does not buffer anything in normal usage -- [As fast or faster than](https://github.com/mjackson/multipart-parser#benchmark) other popular multipart libraries +- [As fast or faster than](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser#benchmark) other popular multipart libraries ## Installation @@ -34,7 +33,10 @@ deno add @mjackson/multipart-parser The most common use case for `multipart-parser` is handling file uploads when you're building a web server. For this case, the `parseMultipartRequest` function is your friend. It will automatically validate the request is `multipart/form-data`, extract the multipart boundary from the `Content-Type` header, parse all fields and files in the `request.body` stream, and `yield` each one to you as a `MultipartPart` object so you can save it to disk or upload it somewhere. ```typescript -import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser'; +import { + MultipartParseError, + parseMultipartRequest +} from "@mjackson/multipart-parser"; async function handleMultipartRequest(request: Request): void { try { @@ -51,9 +53,9 @@ async function handleMultipartRequest(request: Request): void { } } catch (error) { if (error instanceof MultipartParseError) { - console.error('Failed to parse multipart request:', error.message); + console.error("Failed to parse multipart request:", error.message); } else { - console.error('An unexpected error occurred:', error); + console.error("An unexpected error occurred:", error); } } } @@ -64,11 +66,11 @@ The main module (`import from "@mjackson/multipart-parser"`) assumes you're work If however you're building a server for Node.js that relies on node-specific APIs like `http.IncomingMessage`, `stream.Readable`, and `buffer.Buffer` (ala Express or `http.createServer`), `multipart-parser` ships with an additional module that works directly with these APIs. ```typescript -import * as http from 'node:http'; +import * as http from "node:http"; -import { MultipartParseError } from '@mjackson/multipart-parser'; +import { MultipartParseError } from "@mjackson/multipart-parser"; // Note: Import from multipart-parser/node for node-specific APIs -import { parseMultipartRequest } from '@mjackson/multipart-parser/node'; +import { parseMultipartRequest } from "@mjackson/multipart-parser/node"; const server = http.createServer(async (req, res) => { try { @@ -81,9 +83,9 @@ const server = http.createServer(async (req, res) => { } } catch (error) { if (error instanceof MultipartParseError) { - console.error('Failed to parse multipart request:', error.message); + console.error("Failed to parse multipart request:", error.message); } else { - console.error('An unexpected error occurred:', error); + console.error("An unexpected error occurred:", error); } } }); @@ -96,7 +98,7 @@ server.listen(8080); If you're working directly with multipart boundaries and buffers/streams of multipart data that are not necessarily part of a request, `multipart-parser` provides a lower-level API that you can use directly: ```typescript -import { parseMultipart } from '@mjackson/multipart-parser'; +import { parseMultipart } from "@mjackson/multipart-parser"; // Get the multipart data from some API, filesystem, etc. let multipartMessage = new Uint8Array(); @@ -104,7 +106,7 @@ let multipartMessage = new Uint8Array(); // let multipartMessage = new ReadableStream(...); // let multipartMessage = [new Uint8Array(...), new Uint8Array(...)]; -let boundary = '----WebKitFormBoundary56eac3x'; +let boundary = "----WebKitFormBoundary56eac3x"; for await (let part of parseMultipart(multipartMessage, boundary)) { // Do whatever you want with the part... @@ -114,16 +116,19 @@ for await (let part of parseMultipart(multipartMessage, boundary)) { If you'd prefer a callback-based API, instantiate your own `MultipartParser` and go for it: ```typescript -import { MultipartParseError, MultipartParser } from '@mjackson/multipart-parser'; +import { + MultipartParseError, + MultipartParser +} from "@mjackson/multipart-parser"; let multipartMessage = new Uint8Array(); // or ReadableStream, etc. -let boundary = '...'; +let boundary = "..."; let parser = new MultipartParser(boundary); try { // parse() resolves once the parse is finished and all your callbacks are done - await parser.parse(multipartMessage, async (part) => { + await parser.parse(multipartMessage, async part => { // Do whatever you need... }); } catch (error) { @@ -137,12 +142,12 @@ try { ## Examples -The [`examples` directory](https://github.com/mjackson/multipart-parser/tree/main/examples) contains a few working examples of how you can use this library: +The [`examples` directory](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples) contains a few working examples of how you can use this library: -- [`examples/bun`](https://github.com/mjackson/multipart-parser/tree/main/examples/bun) - using multipart-parser in Bun -- [`examples/cf-workers`](https://github.com/mjackson/multipart-parser/tree/main/examples/cf-workers) - using multipart-parser in a Cloudflare Worker and storing file uploads in R2 -- [`examples/deno`](https://github.com/mjackson/multipart-parser/tree/main/examples/deno) - using multipart-parser in Deno -- [`examples/node`](https://github.com/mjackson/multipart-parser/tree/main/examples/node) - using multipart-parser in Node.js +- [`examples/bun`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples/bun) - using multipart-parser in Bun +- [`examples/cf-workers`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples/cf-workers) - using multipart-parser in a Cloudflare Worker and storing file uploads in R2 +- [`examples/deno`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples/deno) - using multipart-parser in Deno +- [`examples/node`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples/node) - using multipart-parser in Node.js ## Benchmark @@ -210,9 +215,9 @@ pnpm run bench ## Related Packages -- [`headers`](https://github.com/mjackson/headers) - Used internally to parse HTTP headers and get +- [`headers`](https://github.com/mjackson/remix-the-web/tree/main/packages/headers) - Used internally to parse HTTP headers and get metadata (filename, content type) for each `MultipartPart` -- [`form-data-parser`](https://github.com/mjackson/form-data-parser) - Uses `multipart-parser` +- [`form-data-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser) - Uses `multipart-parser` internally to parse multipart requests and generate `FileUpload`s for storage ## Credits @@ -221,4 +226,4 @@ Thanks to Jacob Ebey who gave me several code reviews on this project prior to p ## License -See [LICENSE](https://github.com/mjackson/multipart-parser/blob/main/LICENSE) +See [LICENSE](https://github.com/mjackson/remix-the-web/blob/main/LICENSE) From c86113d4c0b65ffc39a2f8fa089455034174fa84 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 19:58:54 -0700 Subject: [PATCH 357/730] Update README --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 359972d13b2..5bab1dc1135 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,16 @@ This repository is a collection of packages for use with [Remix](https://remix.r The packages in this repository are designed around the [single responsibility principle](https://en.wikipedia.org/wiki/Single-responsibility_principle); they each do one thing really well. Where existing web standards and APIs exist, we build on them in creative ways to expand and extend their functionality. Where new APIs are needed, we design theme to interoperate seamlessly with existing standards. -The goal is that these libraries should be really useful for anyone who is building for the web. If you're using [Remix](https://remix.run), we've designed it from the start to work with web standards. If you're using some other framework, you should easily be able to integrate these tools into your workflow as well without going full-blown Remix. +The goal is that these libraries should be really useful for anyone who is building for the web. If you're using [Remix](https://remix.run), we've designed it from the start to work with web standards. If you're using some other framework, you should easily be able to integrate these tools into your workflow as well without going full-blown Remix. If you're building your own framework, we hope you'll be able to use these tools as well. + +What exactly does it mean when we say "web standards"? It means we use: + +- [The Web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) instead of Node.js streams +- [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) instead of Node.js `Buffer`s +- [The Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) instead of the Node.js crypto library +- [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) and [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) instead of some bespoke runtime-specific API + +You get the idea. The benefit of writing JavaScript like this is that it's incredibly portable between various runtimes. All of the packages in this repository work on any JavaScript runtime you might be using: Node.js, Bun, Deno, Cloudflare Workers, etc. ## Packages From cd9f55ebdb2700cd8bd35db41327b7d7ad647f2a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 20:20:44 -0700 Subject: [PATCH 358/730] Move common dev deps to repo root --- package.json | 5 ++- packages/file-storage/package.json | 5 +-- packages/form-data-parser/package.json | 5 +-- packages/headers/package.json | 5 +-- packages/lazy-file/package.json | 5 +-- packages/multipart-parser/package.json | 5 +-- pnpm-lock.yaml | 54 +++++--------------------- 7 files changed, 18 insertions(+), 66 deletions(-) diff --git a/package.json b/package.json index 4fc0a125cfe..36d1653a32d 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,10 @@ "private": true, "packageManager": "pnpm@9.9.0", "devDependencies": { - "nx": "19.6.3" + "nx": "19.6.3", + "prettier": "^3.3.3", + "tsimp": "^2.0.11", + "typescript": "^5.5.4" }, "scripts": { "clean": "git clean -fdX ." diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index b4c8117ae14..6df14b1dead 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -25,10 +25,7 @@ "@mjackson/lazy-file": "^2.2.0" }, "devDependencies": { - "@types/node": "^20.14.10", - "prettier": "^3.3.3", - "tsimp": "^2.0.11", - "typescript": "^5.5.3" + "@types/node": "^20.14.10" }, "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index dc43682a019..36157caebd1 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -23,10 +23,7 @@ "@mjackson/multipart-parser": "^0.6.1" }, "devDependencies": { - "@types/node": "^22.4.1", - "prettier": "^3.3.3", - "tsimp": "^2.0.11", - "typescript": "^5.5.4" + "@types/node": "^22.4.1" }, "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", diff --git a/packages/headers/package.json b/packages/headers/package.json index de34f3f9a10..0f0b2af95d2 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -20,10 +20,7 @@ "./package.json": "./package.json" }, "devDependencies": { - "@types/node": "^20.14.10", - "prettier": "^3.3.3", - "tsimp": "^2.0.11", - "typescript": "^5.5.3" + "@types/node": "^20.14.10" }, "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index 7c70c4f6eda..c05360448d8 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -24,10 +24,7 @@ "mrmime": "^2.0.0" }, "devDependencies": { - "@types/node": "^22.5.0", - "prettier": "^3.3.3", - "tsimp": "^2.0.11", - "typescript": "^5.5.4" + "@types/node": "^22.5.0" }, "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index aa4580bf099..2c4e35a938e 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -24,10 +24,7 @@ "@mjackson/headers": "^0.5.0" }, "devDependencies": { - "@types/node": "^20.14.10", - "prettier": "^3.3.3", - "tsimp": "^2.0.11", - "typescript": "^5.5.3" + "@types/node": "^20.14.10" }, "scripts": { "bench": "pnpm run bench:node && pnpm run bench:bun && pnpm run bench:deno", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bcdaa6edf19..24a5118ebf8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,15 @@ importers: nx: specifier: 19.6.3 version: 19.6.3 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + tsimp: + specifier: ^2.0.11 + version: 2.0.11(typescript@5.5.4) + typescript: + specifier: ^5.5.4 + version: 5.5.4 packages/file-storage: dependencies: @@ -21,15 +30,6 @@ importers: '@types/node': specifier: ^20.14.10 version: 20.16.1 - prettier: - specifier: ^3.3.3 - version: 3.3.3 - tsimp: - specifier: ^2.0.11 - version: 2.0.11(typescript@5.5.4) - typescript: - specifier: ^5.5.3 - version: 5.5.4 packages/form-data-parser: dependencies: @@ -40,30 +40,12 @@ importers: '@types/node': specifier: ^22.4.1 version: 22.5.0 - prettier: - specifier: ^3.3.3 - version: 3.3.3 - tsimp: - specifier: ^2.0.11 - version: 2.0.11(typescript@5.5.4) - typescript: - specifier: ^5.5.4 - version: 5.5.4 packages/headers: devDependencies: '@types/node': specifier: ^20.14.10 version: 20.16.1 - prettier: - specifier: ^3.3.3 - version: 3.3.3 - tsimp: - specifier: ^2.0.11 - version: 2.0.11(typescript@5.5.4) - typescript: - specifier: ^5.5.3 - version: 5.5.4 packages/lazy-file: dependencies: @@ -74,15 +56,6 @@ importers: '@types/node': specifier: ^22.5.0 version: 22.5.0 - prettier: - specifier: ^3.3.3 - version: 3.3.3 - tsimp: - specifier: ^2.0.11 - version: 2.0.11(typescript@5.5.4) - typescript: - specifier: ^5.5.4 - version: 5.5.4 packages/multipart-parser: dependencies: @@ -93,15 +66,6 @@ importers: '@types/node': specifier: ^20.14.10 version: 20.16.1 - prettier: - specifier: ^3.3.3 - version: 3.3.3 - tsimp: - specifier: ^2.0.11 - version: 2.0.11(typescript@5.5.4) - typescript: - specifier: ^5.5.3 - version: 5.5.4 packages/multipart-parser/bench: dependencies: From 74f04d803b1b8b8efeb869a4d2cf172942583e29 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 20:20:56 -0700 Subject: [PATCH 359/730] Add Prettier config --- .prettierrc | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000000..f018274ffc2 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +printWidth: 100 +semi: true +singleQuote: true +useTabs: false From b35975e4755d55f81000a4ff90c3a9a5b029b0b8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 22:27:56 -0700 Subject: [PATCH 360/730] Use swc-node/register instead of tsimp --- .gitignore | 1 - nx.json | 4 - package.json | 5 +- packages/file-storage/package.json | 2 +- packages/form-data-parser/package.json | 2 +- packages/headers/package.json | 2 +- packages/lazy-file/package.json | 2 +- packages/multipart-parser/package.json | 4 +- pnpm-lock.yaml | 1330 +++++------------------- 9 files changed, 242 insertions(+), 1110 deletions(-) delete mode 100644 nx.json diff --git a/.gitignore b/.gitignore index 2400b8e91e7..74d9c201ad9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -**/.tsimp/ **/dist/ **/node_modules/ diff --git a/nx.json b/nx.json deleted file mode 100644 index f8e2b253a36..00000000000 --- a/nx.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "./node_modules/nx/schemas/nx-schema.json", - "defaultBase": "main" -} \ No newline at end of file diff --git a/package.json b/package.json index 36d1653a32d..4ab74067ce5 100644 --- a/package.json +++ b/package.json @@ -3,12 +3,11 @@ "private": true, "packageManager": "pnpm@9.9.0", "devDependencies": { - "nx": "19.6.3", + "@swc-node/register": "^1.10.9", "prettier": "^3.3.3", - "tsimp": "^2.0.11", "typescript": "^5.5.4" }, "scripts": { "clean": "git clean -fdX ." } -} \ No newline at end of file +} diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index 6df14b1dead..ac2bf1f81ec 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -29,7 +29,7 @@ }, "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", - "test": "node --import tsimp/import --test ./src/**/*.spec.ts", + "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", "prepare": "pnpm run build" }, "keywords": [ diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index 36157caebd1..e7a68fb2c94 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -27,7 +27,7 @@ }, "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", - "test": "node --import tsimp/import --test ./src/**/*.spec.ts", + "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", "prepare": "pnpm run build" }, "keywords": [ diff --git a/packages/headers/package.json b/packages/headers/package.json index 0f0b2af95d2..56695a107d2 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -24,7 +24,7 @@ }, "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", - "test": "node --import tsimp/import --test ./src/**/*.spec.ts", + "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", "prepare": "pnpm run build" }, "keywords": [ diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index c05360448d8..e8ecc708994 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -28,7 +28,7 @@ }, "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", - "test": "node --import tsimp/import --test ./src/**/*.spec.ts", + "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", "prepare": "pnpm run build" }, "keywords": [ diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 2c4e35a938e..5d041fe03b5 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -30,9 +30,9 @@ "bench": "pnpm run bench:node && pnpm run bench:bun && pnpm run bench:deno", "bench:bun": "bun run ./bench/runner.ts", "bench:deno": "deno --unstable-byonm --unstable-sloppy-imports run --allow-sys ./bench/runner.ts", - "bench:node": "node --import tsimp/import ./bench/runner.ts", + "bench:node": "node --import @swc-node/register/esm-register ./bench/runner.ts", "build": "tsc --outDir dist --project tsconfig.lib.json", - "test": "node --import tsimp/import --test ./src/**/*.spec.ts", + "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", "prepare": "pnpm run build" }, "keywords": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 24a5118ebf8..53523e212de 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,15 +8,12 @@ importers: .: devDependencies: - nx: - specifier: 19.6.3 - version: 19.6.3 + '@swc-node/register': + specifier: ^1.10.9 + version: 1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4) prettier: specifier: ^3.3.3 version: 3.3.3 - tsimp: - specifier: ^2.0.11 - version: 2.0.11(typescript@5.5.4) typescript: specifier: ^5.5.4 version: 5.5.4 @@ -355,20 +352,6 @@ packages: '@fastify/busboy@3.0.0': resolution: {integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==} - '@isaacs/cached@1.0.1': - resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} - - '@isaacs/catcher@1.0.4': - resolution: {integrity: sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA==} - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -391,76 +374,151 @@ packages: '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} - '@nrwl/tao@19.6.3': - resolution: {integrity: sha512-j4vPU87yBhTrdyPFSNhlUkN29w4BQ+M14khT8PFGe+Y26gHMxNRNXNFUCwtVARYAc6IwxS8Uvlwy7AwXG2ETPA==} - hasBin: true - - '@nx/nx-darwin-arm64@19.6.3': - resolution: {integrity: sha512-P7WlX5YDZOABAlyfpR6eObigQTNuUuy3iJVUuGwp1Nuo3VPMPkpK1GMWKWLwOR9+2jGnF5MzuqWHk7CdF33uqQ==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-darwin-arm64@1.11.0': + resolution: {integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==} cpu: [arm64] os: [darwin] - '@nx/nx-darwin-x64@19.6.3': - resolution: {integrity: sha512-HF28dPc7h0EmEGYJWJUPA3cBvjXyHbSbGQP5oP885gos9zcyVBjQ2kdJEUZDNMHB9KlZraeXbmV1umFkikjn6A==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-darwin-x64@1.11.0': + resolution: {integrity: sha512-w/svTRKnuRinojYAVsWRozVoPar7XUPlJhpfnsYlReRjls6A53/ziTzHfpmcKjdBrP/AXPcDVJDnM4pOSsvWvA==} cpu: [x64] os: [darwin] - '@nx/nx-freebsd-x64@19.6.3': - resolution: {integrity: sha512-y52dWxQ/x2ccyPqA4Vou4CnTqZX4gr/wV9myJX56G1CyEpWasmcqmPFeOKQd6dj7llGM/KJ/4Gz29RYxcWffcA==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-freebsd-x64@1.11.0': + resolution: {integrity: sha512-thGp8g8maYUx7vYJqD0vSsuUO95vWNJwKS2AXchq212J5dQ0Dybq4gjt2O2N9iU+lxj1QzmIDXGw7q5HCagOiw==} cpu: [x64] os: [freebsd] - '@nx/nx-linux-arm-gnueabihf@19.6.3': - resolution: {integrity: sha512-RneCg1tglLbP4cmGnGUs4FgZVT0aOA9wA53tO4IbyxLnlRXNY9OE452YLgqv3H7sLtNjsey2Lkq1seBHtr3p/Q==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-linux-arm-gnueabihf@1.11.0': + resolution: {integrity: sha512-8G99bs4cnwpJRjRK2cEJXiJVyLogzPJq4JgLlcMEKSGhdkoMV1Ia0dghLk9lAFog33U4lWIwKmPgqQzTO6JM8g==} cpu: [arm] os: [linux] - '@nx/nx-linux-arm64-gnu@19.6.3': - resolution: {integrity: sha512-Y+vgqaxrPQUEtCzxK25QY4ahO90l0eWgVrvCALexGmq0lW41JrVpfTTsbH/BAPLsx+u8A/GPAQAgrmg7d5lSxw==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-linux-arm64-gnu@1.11.0': + resolution: {integrity: sha512-hNcB/wbuCFbsspg4h9+Nz5gSL8PbRW7zG/eVvmEpzGhmVubzDFuNmlYtmaUaZ6b9jzOrrqTkYCt9t7Q2TDHnBA==} cpu: [arm64] os: [linux] - '@nx/nx-linux-arm64-musl@19.6.3': - resolution: {integrity: sha512-o/99DBgafbjiJ4e9KFxaldvtlZta/FdzEiQQW+SQQ0JGSYlLCZZ8tIT6t3edV7cmG+gQLNMwolJzgpY53O9wjA==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-linux-arm64-musl@1.11.0': + resolution: {integrity: sha512-H9rjqCcNQT9aip1VLrtsiyj9So0DEKUoutMNu1oL9UuD3H5lWIaxhDlHTAFsobWeUHCnuaCbizhGb9wyLRHSuA==} cpu: [arm64] os: [linux] - '@nx/nx-linux-x64-gnu@19.6.3': - resolution: {integrity: sha512-ppp0NBOhwJ39U1vR7h8jhFSfiur6CZPSUYjXsV44BlaNGc1wHZ+7FDXhzOTokgTNWHavYgYOJuVan5LtTLKJkA==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-linux-x64-gnu@1.11.0': + resolution: {integrity: sha512-6hdv/kmaGysK3/hUaGTYG07yX+nvk6hGoWombmOuc0vBnGLRtSjqvvgDBdAs9/iIcOSQI2YNUEiJvTyy6eb5GA==} cpu: [x64] os: [linux] - '@nx/nx-linux-x64-musl@19.6.3': - resolution: {integrity: sha512-H7xgsT5OTtVYCXjXBLZu28v+rIInhbUggrgVJ2iQJFGBT2A2qmvGmDJdcDz8+K90ku1f4VuWmm8i+TEyDEcBuQ==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-linux-x64-musl@1.11.0': + resolution: {integrity: sha512-AYUvI4VwQkBq0rcYI3Z7a9+BpllbllbxQCD30ZRgHghvqXvDECWfP8r98iynz7u0oKGO8ZPf15d/l9VrkRtiuQ==} cpu: [x64] os: [linux] - '@nx/nx-win32-arm64-msvc@19.6.3': - resolution: {integrity: sha512-o9O6lSmx67zUnqOtlDC4YpC++fiUkixgIsQEG8J/2jdNgAATqOtERcqCNra/uke/Q94Vht2tVXjXF3uj92APhw==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-wasm32-wasi@1.11.0': + resolution: {integrity: sha512-vhXnOs34q8p7QhqQ04bIGy7ZzLEHBaBTsqh2wpAzSBCmjL7MmTpM8KWwXFPFB+Wj0P7/parjGDHzbZG20pEePg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-resolver/binding-win32-arm64-msvc@1.11.0': + resolution: {integrity: sha512-5XMm8EELDkAVQoMGv4QKqi+SjWnhcU1aq5B9q59iqiXIBNAs72f0d3LAldLrqE2XomP2QweorpsoxuGuIk2Cnw==} cpu: [arm64] os: [win32] - '@nx/nx-win32-x64-msvc@19.6.3': - resolution: {integrity: sha512-6NQhc7jYQ/sqPt5fDy8C+br73kTd5jhb8ZkPtEy2Amr1aA1K9SAxZAYfyvxLHS2z1nBEelNFgXe6HBmDX92FkA==} + '@oxc-resolver/binding-win32-x64-msvc@1.11.0': + resolution: {integrity: sha512-rVKiZSTgao4SBWyqWvStxDhKmwbKEN/E8+H3CJzIP4FcsL7MQtWH2HT86bmoefkyRe1yO+m2/mG7j3TfADh/Fg==} + cpu: [x64] + os: [win32] + + '@swc-node/core@1.13.3': + resolution: {integrity: sha512-OGsvXIid2Go21kiNqeTIn79jcaX4l0G93X2rAnas4LFoDyA9wAwVK7xZdm+QsKoMn5Mus2yFLCc4OtX2dD/PWA==} engines: {node: '>= 10'} + peerDependencies: + '@swc/core': '>= 1.4.13' + '@swc/types': '>= 0.1' + + '@swc-node/register@1.10.9': + resolution: {integrity: sha512-iXy2sjP0phPEpK2yivjRC3PAgoLaT4sjSk0LDWCTdcTBJmR4waEog0E6eJbvoOkLkOtWw37SB8vCkl/bbh4+8A==} + peerDependencies: + '@swc/core': '>= 1.4.13' + typescript: '>= 4.3' + + '@swc-node/sourcemap-support@0.5.1': + resolution: {integrity: sha512-JxIvIo/Hrpv0JCHSyRpetAdQ6lB27oFYhv0PKCNf1g2gUXOjpeR1exrXccRxLMuAV5WAmGFBwRnNOJqN38+qtg==} + + '@swc/core-darwin-arm64@1.7.18': + resolution: {integrity: sha512-MwLc5U+VGPMZm8MjlFBjEB2wyT1EK0NNJ3tn+ps9fmxdFP+PL8EpMiY1O1F2t1ydy2OzBtZz81sycjM9RieFBg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.7.18': + resolution: {integrity: sha512-IkukOQUw7/14VkHp446OkYGCZEHqZg9pTmTdBawlUyz2JwZMSn2VodCl7aFSdGCsU4Cwni8zKA8CCgkCCAELhw==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.7.18': + resolution: {integrity: sha512-ATnb6jJaBeXCqrTUawWdoOy7eP9SCI7UMcfXlYIMxX4otKKspLPAEuGA5RaNxlCcj9ObyO0J3YGbtZ6hhD2pjg==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.7.18': + resolution: {integrity: sha512-poHtH7zL7lEp9K2inY90lGHJABWxURAOgWNeZqrcR5+jwIe7q5KBisysH09Zf/JNF9+6iNns+U0xgWTNJzBuGA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.7.18': + resolution: {integrity: sha512-qnNI1WmcOV7Wz1ZDyK6WrOlzLvJ01rnni8ec950mMHWkLRMP53QvCvhF3S+7gFplWBwWJTOOPPUqJp/PlSxWyQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.7.18': + resolution: {integrity: sha512-x9SCqCLzwtlqtD5At3I1a7Gco+EuXnzrJGoucmkpeQohshHuwa+cskqsXO6u1Dz0jXJEuHbBZB9va1wYYfjgFg==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.7.18': + resolution: {integrity: sha512-qtj8iOpMMgKjzxTv+islmEY0JBsbd93nka0gzcTTmGZxKtL5jSUsYQvkxwNPZr5M9NU1fgaR3n1vE6lFmtY0IQ==} + engines: {node: '>=10'} cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.7.18': + resolution: {integrity: sha512-ltX/Ol9+Qu4SXmISCeuwVgAjSa8nzHTymknpozzVMgjXUoZMoz6lcynfKL1nCh5XLgqh0XNHUKLti5YFF8LrrA==} + engines: {node: '>=10'} + cpu: [arm64] os: [win32] - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} + '@swc/core-win32-ia32-msvc@1.7.18': + resolution: {integrity: sha512-RgTcFP3wgyxnQbTCJrlgBJmgpeTXo8t807GU9GxApAXfpLZJ3swJ2GgFUmIJVdLWyffSHF5BEkF3FmF6mtH5AQ==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.7.18': + resolution: {integrity: sha512-XbZ0wAgzR757+DhQcnv60Y/bK9yuWPhDNRQVFFQVRsowvK3+c6EblyfUSytIidpXgyYFzlprq/9A9ZlO/wvDWw==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.7.18': + resolution: {integrity: sha512-qL9v5N5S38ijmqiQRvCFUUx2vmxWT/JJ2rswElnyaHkOHuVoAFhBB90Ywj4RKjh3R0zOjhEcemENTyF3q3G6WQ==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '*' + peerDependenciesMeta: + '@swc/helpers': + optional: true - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/types@0.1.12': + resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==} '@tybys/wasm-util@0.9.0': resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} @@ -489,17 +547,6 @@ packages: '@types/ws@8.5.12': resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} - '@yarnpkg/lockfile@1.1.0': - resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} - - '@yarnpkg/parsers@3.0.0-rc.46': - resolution: {integrity: sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==} - engines: {node: '>=14.15.0'} - - '@zkochan/js-yaml@0.0.7': - resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} - hasBin: true - acorn-walk@8.3.3: resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} engines: {node: '>=0.4.0'} @@ -509,74 +556,26 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - as-table@1.0.55: resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - axios@1.7.5: - resolution: {integrity: sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==} - - 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'} - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - blake3-wasm@2.1.5: resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} bun-types@1.1.26: resolution: {integrity: sha512-n7jDe62LsB2+WE8Q8/mT3azkPaatKlj/2MyP6hi3mKvPz9oPpB6JW/Ll6JHtNLudasFFuvfgklYSE+rreGvBjw==} @@ -588,40 +587,12 @@ packages: capnp-ts@0.7.0: resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} - cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - - cli-spinners@2.6.1: - resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} - engines: {node: '>=6'} - - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - - clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} consola@3.2.3: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} @@ -631,10 +602,6 @@ packages: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - data-uri-to-buffer@2.0.2: resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} @@ -650,73 +617,18 @@ packages: supports-color: optional: true - defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - - define-lazy-prop@2.0.0: - resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} - engines: {node: '>=8'} - defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - dotenv-expand@11.0.6: - resolution: {integrity: sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==} - engines: {node: '>=12'} - - dotenv@16.4.5: - resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} - engines: {node: '>=12'} - - duplexer@0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - - enquirer@2.3.6: - resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} - engines: {node: '>=8.6'} - esbuild@0.17.19: resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} engines: {node: '>=12'} hasBin: true - escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} - engines: {node: '>=6'} - - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - estree-walker@0.6.1: resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} @@ -724,45 +636,10 @@ packages: resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} engines: {node: '>=6'} - figures@3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} - hasBin: true - - follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - - foreground-child@3.3.0: - resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} - engines: {node: '>=14'} - - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - - front-matter@4.0.2: - resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} - - fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - - fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} - engines: {node: '>=14.14'} - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -771,10 +648,6 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - get-source@2.0.12: resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} @@ -785,31 +658,10 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -818,124 +670,31 @@ packages: resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} engines: {node: '>= 0.4'} - is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - - is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - - jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - jsonc-parser@3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - - lines-and-columns@2.0.4: - resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - mime@3.0.0: resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} engines: {node: '>=10.0.0'} hasBin: true - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - miniflare@3.20240821.0: resolution: {integrity: sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==} engines: {node: '>=16.13'} hasBin: true - minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - mkdirp@3.0.1: - resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} - engines: {node: '>=10'} - hasBin: true - mrmime@2.0.0: resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} engines: {node: '>=10'} @@ -962,58 +721,16 @@ packages: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} - node-machine-id@1.1.12: - resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} - normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - - nx@19.6.3: - resolution: {integrity: sha512-JbgrEKaIBvTfhw3mG3GeyyzJHBAMfuQkMNrxxIto1fn94gxdjXdMfqUnAzrW6xRAt5OEEU+rf7v2OA3vEXYc3A==} - hasBin: true - peerDependencies: - '@swc-node/register': ^1.8.0 - '@swc/core': ^1.3.85 - peerDependenciesMeta: - '@swc-node/register': - optional: true - '@swc/core': - optional: true - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - - open@8.4.2: - resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} - engines: {node: '>=12'} - - ora@5.3.0: - resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} - engines: {node: '>=10'} - - package-json-from-dist@1.0.0: - resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + oxc-resolver@1.11.0: + resolution: {integrity: sha512-N3qMse2AM7uST8PaiUMXZkcACyGAMN073tomyvzHTICSzaOqKHvVS0IZ3vj/OqoE140QP4CyOiWmgC1Hw5Urmg==} path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - path-to-regexp@6.2.2: resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} @@ -1033,31 +750,13 @@ packages: engines: {node: '>=14'} hasBin: true - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - printable-characters@1.0.42: resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - resolve.exports@2.0.2: resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} engines: {node: '>=10'} @@ -1066,14 +765,6 @@ packages: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true - restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - - rimraf@5.0.10: - resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} - hasBin: true - rollup-plugin-inject@3.0.2: resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. @@ -1084,39 +775,12 @@ packages: rollup-pluginutils@2.8.2: resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - selfsigned@2.4.1: resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} engines: {node: '>=10'} - semver@7.6.3: - resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} - engines: {node: '>=10'} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - sock-daemon@1.4.2: - resolution: {integrity: sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg==} - engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} - - socket-post-message@1.0.3: - resolution: {integrity: sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==} + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} @@ -1126,9 +790,6 @@ packages: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} deprecated: Please use @jridgewell/sourcemap-codec instead - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - stacktracey@2.1.8: resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} @@ -1140,49 +801,10 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - 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'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - - strong-log-transformer@2.1.0: - resolution: {integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==} - engines: {node: '>=4'} - hasBin: true - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - tmp@0.2.3: resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} engines: {node: '>=14.14'} @@ -1191,19 +813,8 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - tsconfig-paths@4.2.0: - resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} - engines: {node: '>=6'} - - tsimp@2.0.11: - resolution: {integrity: sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==} - engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} - hasBin: true - peerDependencies: - typescript: ^5.1.0 - - tslib@2.7.0: - resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} typescript@5.5.4: resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} @@ -1226,24 +837,6 @@ packages: unenv-nightly@1.10.0-1717606461.a117952: resolution: {integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==} - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - walk-up-path@3.0.1: - resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} - - wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - workerd@1.20240821.1: resolution: {integrity: sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==} engines: {node: '>=16'} @@ -1259,17 +852,6 @@ packages: '@cloudflare/workers-types': optional: true - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - ws@8.18.0: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} @@ -1285,18 +867,6 @@ packages: xxhash-wasm@1.0.2: resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - youch@3.3.3: resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} @@ -1336,14 +906,17 @@ snapshots: dependencies: '@emnapi/wasi-threads': 1.0.1 tslib: 2.7.0 + optional: true '@emnapi/runtime@1.2.0': dependencies: tslib: 2.7.0 + optional: true '@emnapi/wasi-threads@1.0.1': dependencies: tslib: 2.7.0 + optional: true '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': dependencies: @@ -1425,25 +998,6 @@ snapshots: '@fastify/busboy@3.0.0': {} - '@isaacs/cached@1.0.1': - dependencies: - '@isaacs/catcher': 1.0.4 - - '@isaacs/catcher@1.0.4': {} - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@jest/schemas@29.6.3': - dependencies: - '@sinclair/typebox': 0.27.8 - '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.5.0': {} @@ -1468,54 +1022,124 @@ snapshots: '@emnapi/core': 1.2.0 '@emnapi/runtime': 1.2.0 '@tybys/wasm-util': 0.9.0 + optional: true + + '@oxc-resolver/binding-darwin-arm64@1.11.0': + optional: true + + '@oxc-resolver/binding-darwin-x64@1.11.0': + optional: true + + '@oxc-resolver/binding-freebsd-x64@1.11.0': + optional: true + + '@oxc-resolver/binding-linux-arm-gnueabihf@1.11.0': + optional: true + + '@oxc-resolver/binding-linux-arm64-gnu@1.11.0': + optional: true + + '@oxc-resolver/binding-linux-arm64-musl@1.11.0': + optional: true + + '@oxc-resolver/binding-linux-x64-gnu@1.11.0': + optional: true + + '@oxc-resolver/binding-linux-x64-musl@1.11.0': + optional: true - '@nrwl/tao@19.6.3': + '@oxc-resolver/binding-wasm32-wasi@1.11.0': dependencies: - nx: 19.6.3 + '@napi-rs/wasm-runtime': 0.2.4 + optional: true + + '@oxc-resolver/binding-win32-arm64-msvc@1.11.0': + optional: true + + '@oxc-resolver/binding-win32-x64-msvc@1.11.0': + optional: true + + '@swc-node/core@1.13.3(@swc/core@1.7.18)(@swc/types@0.1.12)': + dependencies: + '@swc/core': 1.7.18 + '@swc/types': 0.1.12 + + '@swc-node/register@1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4)': + dependencies: + '@swc-node/core': 1.13.3(@swc/core@1.7.18)(@swc/types@0.1.12) + '@swc-node/sourcemap-support': 0.5.1 + '@swc/core': 1.7.18 + colorette: 2.0.20 + debug: 4.3.6 + oxc-resolver: 1.11.0 + pirates: 4.0.6 tslib: 2.7.0 + typescript: 5.5.4 transitivePeerDependencies: - - '@swc-node/register' - - '@swc/core' - - debug + - '@swc/types' + - supports-color - '@nx/nx-darwin-arm64@19.6.3': - optional: true + '@swc-node/sourcemap-support@0.5.1': + dependencies: + source-map-support: 0.5.21 + tslib: 2.7.0 - '@nx/nx-darwin-x64@19.6.3': + '@swc/core-darwin-arm64@1.7.18': optional: true - '@nx/nx-freebsd-x64@19.6.3': + '@swc/core-darwin-x64@1.7.18': optional: true - '@nx/nx-linux-arm-gnueabihf@19.6.3': + '@swc/core-linux-arm-gnueabihf@1.7.18': optional: true - '@nx/nx-linux-arm64-gnu@19.6.3': + '@swc/core-linux-arm64-gnu@1.7.18': optional: true - '@nx/nx-linux-arm64-musl@19.6.3': + '@swc/core-linux-arm64-musl@1.7.18': optional: true - '@nx/nx-linux-x64-gnu@19.6.3': + '@swc/core-linux-x64-gnu@1.7.18': optional: true - '@nx/nx-linux-x64-musl@19.6.3': + '@swc/core-linux-x64-musl@1.7.18': optional: true - '@nx/nx-win32-arm64-msvc@19.6.3': + '@swc/core-win32-arm64-msvc@1.7.18': optional: true - '@nx/nx-win32-x64-msvc@19.6.3': + '@swc/core-win32-ia32-msvc@1.7.18': optional: true - '@pkgjs/parseargs@0.11.0': + '@swc/core-win32-x64-msvc@1.7.18': optional: true - '@sinclair/typebox@0.27.8': {} + '@swc/core@1.7.18': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.12 + optionalDependencies: + '@swc/core-darwin-arm64': 1.7.18 + '@swc/core-darwin-x64': 1.7.18 + '@swc/core-linux-arm-gnueabihf': 1.7.18 + '@swc/core-linux-arm64-gnu': 1.7.18 + '@swc/core-linux-arm64-musl': 1.7.18 + '@swc/core-linux-x64-gnu': 1.7.18 + '@swc/core-linux-x64-musl': 1.7.18 + '@swc/core-win32-arm64-msvc': 1.7.18 + '@swc/core-win32-ia32-msvc': 1.7.18 + '@swc/core-win32-x64-msvc': 1.7.18 + + '@swc/counter@0.1.3': {} + + '@swc/types@0.1.12': + dependencies: + '@swc/counter': 0.1.3 '@tybys/wasm-util@0.9.0': dependencies: tslib: 2.7.0 + optional: true '@types/bun@1.1.8': dependencies: @@ -1547,88 +1171,30 @@ snapshots: dependencies: '@types/node': 22.5.0 - '@yarnpkg/lockfile@1.1.0': {} - - '@yarnpkg/parsers@3.0.0-rc.46': - dependencies: - js-yaml: 3.14.1 - tslib: 2.7.0 - - '@zkochan/js-yaml@0.0.7': - dependencies: - argparse: 2.0.1 - acorn-walk@8.3.3: dependencies: acorn: 8.12.1 acorn@8.12.1: {} - ansi-colors@4.1.3: {} - - ansi-regex@5.0.1: {} - - ansi-regex@6.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@5.2.0: {} - - ansi-styles@6.2.1: {} - anymatch@3.1.3: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - - argparse@2.0.1: {} - as-table@1.0.55: dependencies: printable-characters: 1.0.42 - asynckit@0.4.0: {} - - axios@1.7.5: - dependencies: - follow-redirects: 1.15.6 - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - balanced-match@1.0.2: {} - - base64-js@1.5.1: {} - binary-extensions@2.3.0: {} - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - blake3-wasm@2.1.5: {} - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - braces@3.0.3: dependencies: fill-range: 7.1.1 - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 + buffer-from@1.1.2: {} bun-types@1.1.26: dependencies: @@ -1646,11 +1212,6 @@ snapshots: transitivePeerDependencies: - supports-color - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -1663,40 +1224,12 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - cli-cursor@3.1.0: - dependencies: - restore-cursor: 3.1.0 - - cli-spinners@2.6.1: {} - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - clone@1.0.4: {} - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 + colorette@2.0.20: {} consola@3.2.3: {} cookie@0.5.0: {} - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - data-uri-to-buffer@2.0.2: {} date-fns@3.6.0: {} @@ -1705,40 +1238,8 @@ snapshots: dependencies: ms: 2.1.2 - defaults@1.0.4: - dependencies: - clone: 1.0.4 - - define-lazy-prop@2.0.0: {} - defu@6.1.4: {} - delayed-stream@1.0.0: {} - - diff-sequences@29.6.3: {} - - dotenv-expand@11.0.6: - dependencies: - dotenv: 16.4.5 - - dotenv@16.4.5: {} - - duplexer@0.1.2: {} - - eastasianwidth@0.2.0: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - end-of-stream@1.4.4: - dependencies: - once: 1.4.0 - - enquirer@2.3.6: - dependencies: - ansi-colors: 4.1.3 - esbuild@0.17.19: optionalDependencies: '@esbuild/android-arm': 0.17.19 @@ -1764,60 +1265,21 @@ snapshots: '@esbuild/win32-ia32': 0.17.19 '@esbuild/win32-x64': 0.17.19 - escalade@3.1.2: {} - - escape-string-regexp@1.0.5: {} - escape-string-regexp@4.0.0: {} - esprima@4.0.1: {} - estree-walker@0.6.1: {} exit-hook@2.2.1: {} - figures@3.2.0: - dependencies: - escape-string-regexp: 1.0.5 - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 - flat@5.0.2: {} - - follow-redirects@1.15.6: {} - - foreground-child@3.3.0: - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - - form-data@4.0.0: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - - front-matter@4.0.2: - dependencies: - js-yaml: 3.14.1 - - fs-constants@1.0.0: {} - - fs-extra@11.2.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - fsevents@2.3.3: optional: true function-bind@1.1.2: {} - get-caller-file@2.0.5: {} - get-source@2.0.12: dependencies: data-uri-to-buffer: 2.0.2 @@ -1829,29 +1291,10 @@ snapshots: glob-to-regexp@0.4.1: {} - glob@10.4.5: - dependencies: - foreground-child: 3.3.0 - jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 - package-json-from-dist: 1.0.0 - path-scurry: 1.11.1 - - graceful-fs@4.2.11: {} - - has-flag@4.0.0: {} - hasown@2.0.2: dependencies: function-bind: 1.1.2 - ieee754@1.2.1: {} - - ignore@5.3.2: {} - - inherits@2.0.4: {} - is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 @@ -1860,81 +1303,20 @@ snapshots: dependencies: hasown: 2.0.2 - is-docker@2.2.1: {} - is-extglob@2.1.1: {} - is-fullwidth-code-point@3.0.0: {} - is-glob@4.0.3: dependencies: is-extglob: 2.1.1 - is-interactive@1.0.0: {} - is-number@7.0.0: {} - is-unicode-supported@0.1.0: {} - - is-wsl@2.2.0: - dependencies: - is-docker: 2.2.1 - - isexe@2.0.0: {} - - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - jest-diff@29.7.0: - dependencies: - chalk: 4.1.2 - diff-sequences: 29.6.3 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-get-type@29.6.3: {} - - js-yaml@3.14.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - json5@2.2.3: {} - - jsonc-parser@3.2.0: {} - - jsonfile@6.1.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - lines-and-columns@2.0.4: {} - - log-symbols@4.1.0: - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - - lru-cache@10.4.3: {} - magic-string@0.25.9: dependencies: sourcemap-codec: 1.4.8 - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - mime@3.0.0: {} - mimic-fn@2.1.0: {} - miniflare@3.20240821.0: dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -1954,20 +1336,6 @@ snapshots: - supports-color - utf-8-validate - minimatch@9.0.3: - dependencies: - brace-expansion: 2.0.1 - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.1 - - minimist@1.2.8: {} - - minipass@7.1.2: {} - - mkdirp@3.0.1: {} - mrmime@2.0.0: {} ms@2.1.2: {} @@ -1982,101 +1350,24 @@ snapshots: node-forge@1.3.1: {} - node-machine-id@1.1.12: {} - normalize-path@3.0.0: {} - npm-run-path@4.0.1: - dependencies: - path-key: 3.1.1 - - nx@19.6.3: - dependencies: - '@napi-rs/wasm-runtime': 0.2.4 - '@nrwl/tao': 19.6.3 - '@yarnpkg/lockfile': 1.1.0 - '@yarnpkg/parsers': 3.0.0-rc.46 - '@zkochan/js-yaml': 0.0.7 - axios: 1.7.5 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.6.1 - cliui: 8.0.1 - dotenv: 16.4.5 - dotenv-expand: 11.0.6 - enquirer: 2.3.6 - figures: 3.2.0 - flat: 5.0.2 - front-matter: 4.0.2 - fs-extra: 11.2.0 - ignore: 5.3.2 - jest-diff: 29.7.0 - jsonc-parser: 3.2.0 - lines-and-columns: 2.0.4 - minimatch: 9.0.3 - node-machine-id: 1.1.12 - npm-run-path: 4.0.1 - open: 8.4.2 - ora: 5.3.0 - semver: 7.6.3 - string-width: 4.2.3 - strong-log-transformer: 2.1.0 - tar-stream: 2.2.0 - tmp: 0.2.3 - tsconfig-paths: 4.2.0 - tslib: 2.7.0 - yargs: 17.7.2 - yargs-parser: 21.1.1 + oxc-resolver@1.11.0: optionalDependencies: - '@nx/nx-darwin-arm64': 19.6.3 - '@nx/nx-darwin-x64': 19.6.3 - '@nx/nx-freebsd-x64': 19.6.3 - '@nx/nx-linux-arm-gnueabihf': 19.6.3 - '@nx/nx-linux-arm64-gnu': 19.6.3 - '@nx/nx-linux-arm64-musl': 19.6.3 - '@nx/nx-linux-x64-gnu': 19.6.3 - '@nx/nx-linux-x64-musl': 19.6.3 - '@nx/nx-win32-arm64-msvc': 19.6.3 - '@nx/nx-win32-x64-msvc': 19.6.3 - transitivePeerDependencies: - - debug - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - open@8.4.2: - dependencies: - define-lazy-prop: 2.0.0 - is-docker: 2.2.1 - is-wsl: 2.2.0 - - ora@5.3.0: - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.6.1 - is-interactive: 1.0.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - - package-json-from-dist@1.0.0: {} - - path-key@3.1.1: {} + '@oxc-resolver/binding-darwin-arm64': 1.11.0 + '@oxc-resolver/binding-darwin-x64': 1.11.0 + '@oxc-resolver/binding-freebsd-x64': 1.11.0 + '@oxc-resolver/binding-linux-arm-gnueabihf': 1.11.0 + '@oxc-resolver/binding-linux-arm64-gnu': 1.11.0 + '@oxc-resolver/binding-linux-arm64-musl': 1.11.0 + '@oxc-resolver/binding-linux-x64-gnu': 1.11.0 + '@oxc-resolver/binding-linux-x64-musl': 1.11.0 + '@oxc-resolver/binding-wasm32-wasi': 1.11.0 + '@oxc-resolver/binding-win32-arm64-msvc': 1.11.0 + '@oxc-resolver/binding-win32-x64-msvc': 1.11.0 path-parse@1.0.7: {} - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 - path-to-regexp@6.2.2: {} pathe@1.1.2: {} @@ -2087,30 +1378,12 @@ snapshots: prettier@3.3.3: {} - pretty-format@29.7.0: - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.3.1 - printable-characters@1.0.42: {} - proxy-from-env@1.1.0: {} - - react-is@18.3.1: {} - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - readdirp@3.6.0: dependencies: picomatch: 2.3.1 - require-directory@2.1.1: {} - resolve.exports@2.0.2: {} resolve@1.22.8: @@ -2119,15 +1392,6 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - restore-cursor@3.1.0: - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - - rimraf@5.0.10: - dependencies: - glob: 10.4.5 - rollup-plugin-inject@3.0.2: dependencies: estree-walker: 0.6.1 @@ -2142,39 +1406,20 @@ snapshots: dependencies: estree-walker: 0.6.1 - safe-buffer@5.2.1: {} - selfsigned@2.4.1: dependencies: '@types/node-forge': 1.3.11 node-forge: 1.3.1 - semver@7.6.3: {} - - shebang-command@2.0.0: + source-map-support@0.5.21: dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - signal-exit@3.0.7: {} - - signal-exit@4.1.0: {} - - sock-daemon@1.4.2: - dependencies: - rimraf: 5.0.10 - signal-exit: 4.1.0 - socket-post-message: 1.0.3 - - socket-post-message@1.0.3: {} + buffer-from: 1.1.2 + source-map: 0.6.1 source-map@0.6.1: {} sourcemap-codec@1.4.8: {} - sprintf-js@1.0.3: {} - stacktracey@2.1.8: dependencies: as-table: 1.0.55 @@ -2184,79 +1429,14 @@ snapshots: streamsearch@1.1.0: {} - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - 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 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.0.1 - - strip-bom@3.0.0: {} - - strong-log-transformer@2.1.0: - dependencies: - duplexer: 0.1.2 - minimist: 1.2.8 - through: 2.3.8 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - supports-preserve-symlinks-flag@1.0.0: {} - tar-stream@2.2.0: - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.4 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - - through@2.3.8: {} - tmp@0.2.3: {} to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - tsconfig-paths@4.2.0: - dependencies: - json5: 2.2.3 - minimist: 1.2.8 - strip-bom: 3.0.0 - - tsimp@2.0.11(typescript@5.5.4): - dependencies: - '@isaacs/cached': 1.0.1 - '@isaacs/catcher': 1.0.4 - foreground-child: 3.3.0 - mkdirp: 3.0.1 - pirates: 4.0.6 - rimraf: 5.0.10 - signal-exit: 4.1.0 - sock-daemon: 1.4.2 - typescript: 5.5.4 - walk-up-path: 3.0.1 - tslib@2.7.0: {} typescript@5.5.4: {} @@ -2280,20 +1460,6 @@ snapshots: pathe: 1.1.2 ufo: 1.5.4 - universalify@2.0.1: {} - - util-deprecate@1.0.2: {} - - walk-up-path@3.0.1: {} - - wcwidth@1.0.1: - dependencies: - defaults: 1.0.4 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - workerd@1.20240821.1: optionalDependencies: '@cloudflare/workerd-darwin-64': 1.20240821.1 @@ -2330,38 +1496,10 @@ snapshots: - supports-color - utf-8-validate - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - wrappy@1.0.2: {} - ws@8.18.0: {} xxhash-wasm@1.0.2: {} - y18n@5.0.8: {} - - yargs-parser@21.1.1: {} - - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.1.2 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - youch@3.3.3: dependencies: cookie: 0.5.0 From d73a26f15e1e1c4860a8a0b0ee8f5d19eddc805b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 23:09:08 -0700 Subject: [PATCH 361/730] Update CHANGELOG --- packages/file-storage/CHANGELOG.md | 2 +- packages/headers/CHANGELOG.md | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 318cb897c33..364b64fa30a 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -1,4 +1,4 @@ -# `file-storage` CHANGELOG +# file-storage CHANGELOG ## v0.2.0 (Aug 26, 2024) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 50f18ba859d..bedde2ce734 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -1,4 +1,8 @@ -# `headers` CHANGELOG +# headers CHANGELOG + +## HEAD + +- Added support for the `Accept-Language` header ## v0.6.1 (Aug 13, 2024) From 8b4e962cb8ca179eb4a2a567f943f2dc7d17298b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 27 Aug 2024 23:57:04 -0700 Subject: [PATCH 362/730] Release headers@0.7.0 --- packages/headers/CHANGELOG.md | 4 ++-- packages/headers/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index bedde2ce734..5b727e9390b 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -1,8 +1,8 @@ # headers CHANGELOG -## HEAD +## v0.7.0 (Aug 27, 2024) -- Added support for the `Accept-Language` header +- Added support for the `Accept-Language` header (https://github.com/mjackson/remix-the-web/pull/8, thanks [@ArnoSaine](https://github.com/ArnoSaine)) ## v0.6.1 (Aug 13, 2024) diff --git a/packages/headers/package.json b/packages/headers/package.json index 56695a107d2..b21ad8ede80 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/headers", - "version": "0.6.1", + "version": "0.7.0", "description": "A toolkit for working with HTTP headers in JavaScript", "author": "Michael Jackson ", "license": "MIT", From 93b1223684f41a81aecee4a78aadf5ff9939965f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 28 Aug 2024 08:59:16 -0700 Subject: [PATCH 363/730] Add string init type --- packages/headers/CHANGELOG.md | 4 ++++ .../headers/src/lib/super-headers.spec.ts | 24 ++++++++++--------- packages/headers/src/lib/super-headers.ts | 2 +- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 5b727e9390b..371a0fd3b85 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -1,5 +1,9 @@ # headers CHANGELOG +## HEAD + +- Added `string` init type to `new Headers({ acceptLanguage })` + ## v0.7.0 (Aug 27, 2024) - Added support for the `Accept-Language` header (https://github.com/mjackson/remix-the-web/pull/8, thanks [@ArnoSaine](https://github.com/ArnoSaine)) diff --git a/packages/headers/src/lib/super-headers.spec.ts b/packages/headers/src/lib/super-headers.spec.ts index c8bfee2edf8..3f61bdccf45 100644 --- a/packages/headers/src/lib/super-headers.spec.ts +++ b/packages/headers/src/lib/super-headers.spec.ts @@ -196,20 +196,13 @@ describe('SuperHeaders', () => { }); describe('header-specific getters and setters', () => { - it('handles Age header', () => { - let headers = new SuperHeaders(); - headers.age = 42; - - assert.equal(headers.age, 42); - assert.equal(headers.get('Age'), '42'); - }); - it('handles Accept-Language header', () => { - let headers = new SuperHeaders(); - headers.acceptLanguage = 'en-US,en;q=0.9'; + let headers = new SuperHeaders({ + acceptLanguage: 'en-US,en;q=0.9', + }); assert.ok(headers.acceptLanguage instanceof AcceptLanguage); - assert.deepStrictEqual(headers.acceptLanguage.languages, ['en-US', 'en']); + assert.deepEqual(headers.acceptLanguage.languages, ['en-US', 'en']); headers.acceptLanguage.set('en', 0.8); assert.equal(headers.get('Accept-Language'), 'en-US,en;q=0.8'); @@ -218,6 +211,15 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Accept-Language'), 'fi-FI,fi;q=0.9'); }); + it('handles Age header', () => { + let headers = new SuperHeaders({ age: 42 }); + assert.equal(headers.age, 42); + assert.equal(headers.get('Age'), '42'); + headers.age = 100; + assert.equal(headers.age, 100); + assert.equal(headers.get('Age'), '100'); + }); + it('handles Cache-Control header', () => { let headers = new SuperHeaders(); headers.cacheControl = 'public, max-age=3600'; diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index 305ecc9cbcf..f927539f57e 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -12,7 +12,7 @@ const CRLF = '\r\n'; const SetCookieKey = 'set-cookie'; interface SuperHeadersPropertyInit { - acceptLanguage?: AcceptLanguageInit; + acceptLanguage?: string | AcceptLanguageInit; age?: string | number; cacheControl?: string | CacheControlInit; contentDisposition?: string | ContentDispositionInit; From 0117703ca2cc96fc48cdc148e7a9d91bb3959ad6 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 28 Aug 2024 13:07:05 -0700 Subject: [PATCH 364/730] Add a bunch of doc comments --- packages/headers/src/lib/super-headers.ts | 156 +++++++++++++++++++++- 1 file changed, 154 insertions(+), 2 deletions(-) diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index f927539f57e..5fff3c68446 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -34,9 +34,9 @@ export type SuperHeadersInit = /** * An enhanced JavaScript `Headers` interface with type-safe access. * - * [API Reference](https://github.com/mjackson/headers) + * [API Reference](https://github.com/mjackson/remix-the-web/tree/main/packages/headers) * - * [MDN Reference for `Headers` base class](https://developer.mozilla.org/en-US/docs/Web/API/Headers) + * [MDN `Headers` Base Class Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers) */ export class SuperHeaders extends Headers implements Iterable<[string, string]> { #map: Map; @@ -79,6 +79,12 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } } + /** + * Appends a new header value to the existing set of values for a header, + * or adds the header if it does not already exist. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/append) + */ append(name: string, value: string | HeaderValue): void { let key = name.toLowerCase(); if (key === SetCookieKey) { @@ -89,6 +95,11 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } } + /** + * Removes a header. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/delete) + */ delete(name: string): void { let key = name.toLowerCase(); if (key === SetCookieKey) { @@ -98,6 +109,11 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } } + /** + * Returns a string of all the values for a header, or `null` if the header does not exist. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/get) + */ get(name: string): string | null { let key = name.toLowerCase(); if (key === SetCookieKey) { @@ -116,10 +132,22 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } } + /** + * Returns an array of all values associated with the `Set-Cookie` header. This is + * useful when building headers for a HTTP response since multiple `Set-Cookie` headers + * must be sent on separate lines. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/getSetCookie) + */ getSetCookie(): string[] { return this.#setCookieValues.map((value) => value.toString()); } + /** + * Returns `true` if the header is present in the list of headers. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/has) + */ has(name: string): boolean { let key = name.toLowerCase(); if (key === SetCookieKey) { @@ -129,6 +157,12 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } } + /** + * Sets a new value for the given header. If the header already exists, the new value + * will replace the existing value. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/set) + */ set(name: string, value: string | HeaderValue): void { let key = name.toLowerCase(); if (key === SetCookieKey) { @@ -138,6 +172,11 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } } + /** + * Returns an iterator of all header key/value pairs. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries) + */ *entries(): IterableIterator<[string, string]> { for (let [key] of this.#map) { let stringValue = this.get(key); @@ -154,12 +193,22 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } } + /** + * Returns an iterator of all header keys (lowercase). + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/keys) + */ *keys(): IterableIterator { for (let [key] of this) { yield key; } } + /** + * Returns an iterator of all header values. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/values) + */ *values(): IterableIterator { for (let [, value] of this) { yield value; @@ -170,6 +219,11 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> return this.entries(); } + /** + * Invokes the `callback` for each header key/value pair. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/forEach) + */ forEach( callback: (value: string, key: string, parent: SuperHeaders) => void, thisArg?: any, @@ -179,6 +233,9 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> } } + /** + * Returns a string representation of the headers suitable for use in a HTTP message. + */ toString(): string { let lines: string[] = []; @@ -191,6 +248,14 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> // Header-specific getters and setters + /** + * The `Accept-Language` header contains information about preferred natural language for the + * response. + * + * [MDN `Accept-Language` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.5) + */ get acceptLanguage(): AcceptLanguage { return this.#getHeaderValue('accept-language', AcceptLanguage); } @@ -199,6 +264,13 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.#setHeaderValue('accept-language', AcceptLanguage, value); } + /** + * The `Age` header contains the time in seconds an object was in a proxy cache. + * + * [MDN `Age` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Age) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7234#section-5.1) + */ get age(): number | undefined { return this.#getNumberValue('age'); } @@ -207,6 +279,13 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.#map.set('age', value); } + /** + * The `Cache-Control` header contains directives for caching mechanisms in both requests and responses. + * + * [MDN `Cache-Control` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7234#section-5.2) + */ get cacheControl(): CacheControl { return this.#getHeaderValue('cache-control', CacheControl); } @@ -215,6 +294,13 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.#setHeaderValue('cache-control', CacheControl, value); } + /** + * The `Content-Disposition` header is a response-type header that describes how the payload is displayed. + * + * [MDN `Content-Disposition` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) + * + * [RFC 6266](https://datatracker.ietf.org/doc/html/rfc6266) + */ get contentDisposition(): ContentDisposition { return this.#getHeaderValue('content-disposition', ContentDisposition); } @@ -223,6 +309,13 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.#setHeaderValue('content-disposition', ContentDisposition, value); } + /** + * The `Content-Length` header indicates the size of the entity-body in bytes. + * + * [MDN `Content-Length` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Length) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2) + */ get contentLength(): number | undefined { return this.#getNumberValue('content-length'); } @@ -231,6 +324,13 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.#map.set('content-length', value); } + /** + * The `Content-Type` header indicates the media type of the resource. + * + * [MDN `Content-Type` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-3.1.1.5) + */ get contentType(): ContentType { return this.#getHeaderValue('content-type', ContentType); } @@ -239,6 +339,14 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.#setHeaderValue('content-type', ContentType, value); } + /** + * The `Cookie` request header contains stored HTTP cookies previously sent by the server with + * the `Set-Cookie` header. + * + * [MDN `Cookie` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc6265#section-5.4) + */ get cookie(): Cookie { return this.#getHeaderValue('cookie', Cookie); } @@ -247,6 +355,13 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.#setHeaderValue('cookie', Cookie, value); } + /** + * The `Date` header contains the date and time at which the message was sent. + * + * [MDN `Date` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Date) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.2) + */ get date(): Date | undefined { return this.#getDateValue('date'); } @@ -255,6 +370,13 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.#map.set('date', value); } + /** + * The `Expires` header contains the date/time after which the response is considered stale. + * + * [MDN `Expires` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7234#section-5.3) + */ get expires(): Date | undefined { return this.#getDateValue('expires'); } @@ -263,6 +385,14 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.#map.set('expires', value); } + /** + * The `If-Modified-Since` header makes a request conditional on the last modification date of the + * requested resource. + * + * [MDN `If-Modified-Since` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-3.3) + */ get ifModifiedSince(): Date | undefined { return this.#getDateValue('if-modified-since'); } @@ -271,6 +401,14 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.#map.set('if-modified-since', value); } + /** + * The `If-Unmodified-Since` header makes a request conditional on the last modification date of the + * requested resource. + * + * [MDN `If-Unmodified-Since` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Unmodified-Since) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-3.4) + */ get ifUnmodifiedSince(): Date | undefined { return this.#getDateValue('if-unmodified-since'); } @@ -279,6 +417,13 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.#map.set('if-unmodified-since', value); } + /** + * The `Last-Modified` header contains the date and time at which the resource was last modified. + * + * [MDN `Last-Modified` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-2.2) + */ get lastModified(): Date | undefined { return this.#getDateValue('last-modified'); } @@ -287,6 +432,13 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> this.#map.set('last-modified', value); } + /** + * The `Set-Cookie` header is used to send cookies from the server to the user agent. + * + * [MDN `Set-Cookie` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc6265#section-4.1) + */ get setCookie(): SetCookie[] { for (let i = 0; i < this.#setCookieValues.length; ++i) { let value = this.#setCookieValues[i]; From 4e75ed5d21f159a1a92c1f009ba1b4ff308ad208 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 28 Aug 2024 14:34:42 -0700 Subject: [PATCH 365/730] Add some more doc comments --- packages/headers/src/lib/accept-language.ts | 4 +++- packages/headers/src/lib/cache-control.ts | 4 +++- packages/headers/src/lib/content-disposition.ts | 4 +++- packages/headers/src/lib/content-type.ts | 4 +++- packages/headers/src/lib/cookie.ts | 6 ++++-- packages/headers/src/lib/set-cookie.ts | 4 +++- 6 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/headers/src/lib/accept-language.ts b/packages/headers/src/lib/accept-language.ts index 299aa41f271..fa94f3e67f7 100644 --- a/packages/headers/src/lib/accept-language.ts +++ b/packages/headers/src/lib/accept-language.ts @@ -9,7 +9,9 @@ export type AcceptLanguageInit = /** * The value of a `Accept-Language` HTTP header. * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) + * [MDN `Accept-Language` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.5) */ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { #map: Map; diff --git a/packages/headers/src/lib/cache-control.ts b/packages/headers/src/lib/cache-control.ts index 6a82516e59b..3f617db85e8 100644 --- a/packages/headers/src/lib/cache-control.ts +++ b/packages/headers/src/lib/cache-control.ts @@ -153,7 +153,9 @@ export interface CacheControlInit { /** * The value of a `Cache-Control` HTTP header. * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) + * [MDN `Cache-Control` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7234#section-5.2) */ export class CacheControl implements HeaderValue, CacheControlInit { maxAge?: number; diff --git a/packages/headers/src/lib/content-disposition.ts b/packages/headers/src/lib/content-disposition.ts index 793b3378703..1c38ce68178 100644 --- a/packages/headers/src/lib/content-disposition.ts +++ b/packages/headers/src/lib/content-disposition.ts @@ -24,7 +24,9 @@ export interface ContentDispositionInit { /** * The value of a `Content-Disposition` HTTP header. * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) + * [MDN `Content-Disposition` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) + * + * [RFC 6266](https://tools.ietf.org/html/rfc6266) */ export class ContentDisposition implements HeaderValue, ContentDispositionInit { filename?: string; diff --git a/packages/headers/src/lib/content-type.ts b/packages/headers/src/lib/content-type.ts index b0d2a14f6b8..3ba2575bce1 100644 --- a/packages/headers/src/lib/content-type.ts +++ b/packages/headers/src/lib/content-type.ts @@ -25,7 +25,9 @@ export interface ContentTypeInit { /** * The value of a `Content-Type` HTTP header. * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) + * [MDN `Content-Type` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-3.1.1.5) */ export class ContentType implements HeaderValue, ContentTypeInit { boundary?: string; diff --git a/packages/headers/src/lib/cookie.ts b/packages/headers/src/lib/cookie.ts index cba42b43efc..f778435ec0d 100644 --- a/packages/headers/src/lib/cookie.ts +++ b/packages/headers/src/lib/cookie.ts @@ -7,7 +7,9 @@ export type CookieInit = Iterable<[string, string]> | Record; /** * The value of a `Cookie` HTTP header. * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie) + * [MDN `Cookie` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc6265#section-4.2) */ export class Cookie implements HeaderValue, Iterable<[string, string]> { #map: Map; @@ -87,7 +89,7 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> { forEach( callback: (value: string, key: string, map: Map) => void, - thisArg?: any + thisArg?: any, ): void { this.#map.forEach(callback, thisArg); } diff --git a/packages/headers/src/lib/set-cookie.ts b/packages/headers/src/lib/set-cookie.ts index 3efc533879d..c9a51b5c946 100644 --- a/packages/headers/src/lib/set-cookie.ts +++ b/packages/headers/src/lib/set-cookie.ts @@ -65,7 +65,9 @@ export interface SetCookieInit { /** * The value of a `Set-Cookie` HTTP header. * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) + * [MDN `Set-Cookie` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc6265#section-4.1) */ export class SetCookie implements HeaderValue, SetCookieInit { domain?: string; From 3bf084e1f46f46ff43c61827ed5b00a0eba45f70 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 28 Aug 2024 14:36:54 -0700 Subject: [PATCH 366/730] Release headers@0.7.1 --- packages/headers/CHANGELOG.md | 2 +- packages/headers/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 371a0fd3b85..97f5b8b0364 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -1,6 +1,6 @@ # headers CHANGELOG -## HEAD +## v0.7.1 (Aug 28, 2024) - Added `string` init type to `new Headers({ acceptLanguage })` diff --git a/packages/headers/package.json b/packages/headers/package.json index b21ad8ede80..0028a7d0666 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/headers", - "version": "0.7.0", + "version": "0.7.1", "description": "A toolkit for working with HTTP headers in JavaScript", "author": "Michael Jackson ", "license": "MIT", From 49a19e5faf25aca46da7ca005d22f4a5474cb28a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 28 Aug 2024 14:45:51 -0700 Subject: [PATCH 367/730] Update README --- packages/headers/README.md | 138 ++++++++++++++++++++++--------------- 1 file changed, 82 insertions(+), 56 deletions(-) diff --git a/packages/headers/README.md b/packages/headers/README.md index 360e115021f..ece3e29891c 100644 --- a/packages/headers/README.md +++ b/packages/headers/README.md @@ -20,31 +20,31 @@ npm install @mjackson/headers ## Overview ```ts -import Headers from "@mjackson/headers"; +import Headers from '@mjackson/headers'; let headers = new Headers(); // Accept-Language -headers.acceptLanguage = "en-US,en;q=0.9"; +headers.acceptLanguage = 'en-US,en;q=0.9'; console.log(headers.acceptLanguage.languages); // [ 'en-US', 'en' ] console.log(headers.acceptLanguage.entries()); // [Map Entries] { [ 'en-US', 1 ], [ 'en', 0.9 ] } // Content-Type -headers.contentType = "application/json; charset=utf-8"; +headers.contentType = 'application/json; charset=utf-8'; console.log(headers.contentType.mediaType); // "application/json" console.log(headers.contentType.charset); // "utf-8" -headers.contentType.charset = "iso-8859-1"; +headers.contentType.charset = 'iso-8859-1'; -console.log(headers.get("Content-Type")); // "application/json; charset=iso-8859-1" +console.log(headers.get('Content-Type')); // "application/json; charset=iso-8859-1" // Content-Disposition headers.contentDisposition = - "attachment; filename=\"example.pdf\"; filename*=UTF-8''%E4%BE%8B%E5%AD%90.pdf"; + 'attachment; filename="example.pdf"; filename*=UTF-8\'\'%E4%BE%8B%E5%AD%90.pdf'; console.log(headers.contentDisposition.type); // 'attachment' console.log(headers.contentDisposition.filename); // 'example.pdf' @@ -52,16 +52,16 @@ console.log(headers.contentDisposition.filenameSplat); // 'UTF-8\'\'%E4%BE%8B%E5 console.log(headers.contentDisposition.preferredFilename); // '例子.pdf' // Cookie -headers.cookie = "session_id=abc123; user_id=12345"; +headers.cookie = 'session_id=abc123; user_id=12345'; -console.log(headers.cookie.get("session_id")); // 'abc123' -console.log(headers.cookie.get("user_id")); // '12345' +console.log(headers.cookie.get('session_id')); // 'abc123' +console.log(headers.cookie.get('user_id')); // '12345' -headers.cookie.set("theme", "dark"); -console.log(headers.get("Cookie")); // 'session_id=abc123; user_id=12345; theme=dark' +headers.cookie.set('theme', 'dark'); +console.log(headers.get('Cookie')); // 'session_id=abc123; user_id=12345; theme=dark' // Set-Cookie -headers.setCookie = "session_id=abc123; Path=/; HttpOnly"; +headers.setCookie = 'session_id=abc123; Path=/; HttpOnly'; console.log(headers.setCookie.name); // 'session_id' console.log(headers.setCookie.value); // 'abc123' @@ -72,11 +72,11 @@ console.log(headers.setCookie.httpOnly); // true headers.setCookie.maxAge = 3600; headers.setCookie.secure = true; -console.log(headers.get("Set-Cookie")); +console.log(headers.get('Set-Cookie')); // session_id=abc123; Path=/; HttpOnly; Max-Age=3600; Secure // Setting multiple cookies -headers.append("Set-Cookie", "user_id=12345; Path=/api; Secure"); +headers.append('Set-Cookie', 'user_id=12345; Path=/api; Secure'); // Accessing multiple Set-Cookie headers for (let cookie of headers.getSetCookie()) { @@ -91,13 +91,13 @@ for (let cookie of headers.getSetCookie()) { ```ts let headers = new Headers({ contentType: { - mediaType: "text/html", - charset: "utf-8" + mediaType: 'text/html', + charset: 'utf-8', }, setCookie: [ - { name: "session", value: "abc", path: "/" }, - { name: "theme", value: "dark", expires: new Date("2021-12-31T23:59:59Z") } - ] + { name: 'session', value: 'abc', path: '/' }, + { name: 'theme', value: 'dark', expires: new Date('2021-12-31T23:59:59Z') }, + ], }); console.log(`${headers}`); @@ -109,18 +109,18 @@ console.log(`${headers}`); `Headers` works just like [DOM's `Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers) (it's a subclass) so you can use them anywhere you need a `Headers`. ```ts -import Headers from "@mjackson/headers"; +import Headers from '@mjackson/headers'; // Use in a fetch() -let response = await fetch("https://example.com", { - headers: new Headers() +let response = await fetch('https://example.com', { + headers: new Headers(), }); // Convert from DOM Headers let headers = new Headers(response.headers); -headers.set("Content-Type", "text/html"); -headers.get("Content-Type"); // "text/html" +headers.set('Content-Type', 'text/html'); +headers.get('Content-Type'); // "text/html" ``` If you're familiar with using DOM `Headers`, everything works as you'd expect. @@ -129,9 +129,9 @@ If you're familiar with using DOM `Headers`, everything works as you'd expect. ```ts let headers = new Headers({ - "Content-Type": "application/json", - "X-API-Key": "secret-key", - "Accept-Language": "en-US,en;q=0.9" + 'Content-Type': 'application/json', + 'X-API-Key': 'secret-key', + 'Accept-Language': 'en-US,en;q=0.9', }); for (let [name, value] of headers) { @@ -146,8 +146,8 @@ If you're assembling HTTP messages, you can easily convert to a multiline string ```ts let headers = new Headers({ - "Content-Type": "application/json", - "Accept-Language": "en-US,en;q=0.9" + 'Content-Type': 'application/json', + 'Accept-Language': 'en-US,en;q=0.9', }); console.log(`${headers}`); @@ -175,87 +175,103 @@ If you need support for a header that isn't listed here, please [send a PR](http ### Accept-Language ```ts -let header = new AcceptLanguage("en-US,en;q=0.9"); -header.get("en-US"); // 1 -header.set("en-US", 0.8); -header.delete("en-US"); -header.has("en"); // true +let header = new AcceptLanguage('en-US,en;q=0.9'); +header.get('en-US'); // 1 +header.set('en-US', 0.8); +header.delete('en-US'); +header.has('en'); // true // Iterate over language/quality pairs for (let [language, quality] of header) { // ... } -let header = new AcceptLanguage(["en-US", ["en", 0.9]]); -let header = new AcceptLanguage({ "en-US": 1, en: 0.9 }); +// Alternative init styles +let header = new AcceptLanguage({ 'en-US': 1, en: 0.9 }); +let header = new AcceptLanguage(['en-US', ['en', 0.9]]); ``` ### Cache-Control ```ts -import { CacheControl } from "@mjackson/headers"; +import { CacheControl } from '@mjackson/headers'; -let header = new CacheControl("public, max-age=3600, s-maxage=3600"); +let header = new CacheControl('public, max-age=3600, s-maxage=3600'); header.public; // true header.maxAge; // 3600 header.sMaxage; // 3600 + +// Alternative init style +let header = new CacheControl({ public: true, maxAge: 3600 }); ``` ### Content-Disposition ```ts -import { ContentDisposition } from "@mjackson/headers"; +import { ContentDisposition } from '@mjackson/headers'; -let header = new ContentDisposition( - "attachment; name=file1; filename=file1.txt" -); +let header = new ContentDisposition('attachment; name=file1; filename=file1.txt'); header.type; // "attachment" header.name; // "file1" header.filename; // "file1.txt" header.preferredFilename; // "file1.txt" + +// Alternative init style +let header = new ContentDisposition({ + type: 'attachment', + name: 'file1', + filename: 'file1.txt', +}); ``` ### Content-Type ```ts -import { ContentType } from "@mjackson/headers"; +import { ContentType } from '@mjackson/headers'; -let header = new ContentType("text/html; charset=utf-8"); +let header = new ContentType('text/html; charset=utf-8'); header.mediaType; // "text/html" header.boundary; // undefined header.charset; // "utf-8" +// Alternative init style let header = new ContentType({ - mediaType: "multipart/form-data", - boundary: "------WebKitFormBoundary12345" + mediaType: 'multipart/form-data', + boundary: '------WebKitFormBoundary12345', + charset: 'utf-8', }); ``` ### Cookie ```ts -import { Cookie } from "@mjackson/headers"; +import { Cookie } from '@mjackson/headers'; -let header = new Cookie("theme=dark; session_id=123"); -header.get("theme"); // "dark" -header.set("theme", "light"); -header.delete("theme"); -header.has("session_id"); // true +let header = new Cookie('theme=dark; session_id=123'); +header.get('theme'); // "dark" +header.set('theme', 'light'); +header.delete('theme'); +header.has('session_id'); // true // Iterate over cookie name/value pairs for (let [name, value] of header) { // ... } + +// Alternative init styles +let header = new Cookie({ theme: 'dark', session_id: '123' }); +let header = new Cookie([ + ['theme', 'dark'], + ['session_id', '123'], +]); ``` ### Set-Cookie ```ts -import { SetCookie } from "@mjackson/headers"; +import { SetCookie } from '@mjackson/headers'; -let header = new SetCookie( - "session_id=abc; Domain=example.com; Path=/; Secure; HttpOnly" -); +let header = new SetCookie('session_id=abc; Domain=example.com; Path=/; Secure; HttpOnly'); header.name; // "session_id" header.value; // "abc" header.domain; // "example.com" @@ -265,6 +281,16 @@ header.httpOnly; // true header.sameSite; // undefined header.maxAge; // undefined header.expires; // undefined + +// Alternative init styles +let header = new SetCookie({ + name: 'session_id', + value: 'abc', + domain: 'example.com', + path: '/', + secure: true, + httpOnly: true, +}); ``` ## License From af18396cf90f55445bfcee7bb3dcf062d3218af7 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 28 Aug 2024 22:15:08 -0700 Subject: [PATCH 368/730] Remove unneeded tsconfig --- packages/lazy-file/tsconfig.lib.json | 2 +- packages/lazy-file/tsconfig.spec.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/lazy-file/tsconfig.lib.json b/packages/lazy-file/tsconfig.lib.json index c9819aa7ed5..8e712f7d6c8 100644 --- a/packages/lazy-file/tsconfig.lib.json +++ b/packages/lazy-file/tsconfig.lib.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts", "src/test/**/*.ts"], + "exclude": ["src/**/*.spec.ts"], "compilerOptions": { "composite": true, "rootDir": "src" diff --git a/packages/lazy-file/tsconfig.spec.json b/packages/lazy-file/tsconfig.spec.json index 0dcc65f3ce6..ccfefc4d957 100644 --- a/packages/lazy-file/tsconfig.spec.json +++ b/packages/lazy-file/tsconfig.spec.json @@ -1,6 +1,6 @@ { "extends": "./tsconfig.json", - "include": ["src/**/*.spec.ts", "src/test/**/*.ts"], + "include": ["src/**/*.spec.ts"], "compilerOptions": { "composite": true, "types": ["node"] From 165b010422092fcb8152fc50eb7c696bd95b3264 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 28 Aug 2024 23:22:05 -0700 Subject: [PATCH 369/730] Add missing FileUpload export --- packages/form-data-parser/CHANGELOG.md | 4 ++++ packages/form-data-parser/src/form-data-parser.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index 54806607959..0a226ad5675 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -1,5 +1,9 @@ # form-data-parser CHANGELOG +## HEAD + +- Add missing `FileUpload` export 🤦‍♂️ + ## v0.1.0 (Aug 24, 2024) - Initial release diff --git a/packages/form-data-parser/src/form-data-parser.ts b/packages/form-data-parser/src/form-data-parser.ts index cd1863ef275..e57a4d6d872 100644 --- a/packages/form-data-parser/src/form-data-parser.ts +++ b/packages/form-data-parser/src/form-data-parser.ts @@ -1 +1 @@ -export { type FileUploadHandler, parseFormData } from "./lib/form-data.js"; +export { FileUpload, type FileUploadHandler, parseFormData } from './lib/form-data.js'; From 8ca1ec8ce075bfdbb9e3037af1f6eb01f42ee2a2 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 28 Aug 2024 23:23:03 -0700 Subject: [PATCH 370/730] Release form-data-parser@0.2.0 --- packages/form-data-parser/CHANGELOG.md | 2 +- packages/form-data-parser/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index 0a226ad5675..77c9c1ed2b5 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -1,6 +1,6 @@ # form-data-parser CHANGELOG -## HEAD +## v0.2.0 (Aug 28, 2024) - Add missing `FileUpload` export 🤦‍♂️ diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index e7a68fb2c94..5d671d0a4c4 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/form-data-parser", - "version": "0.1.0", + "version": "0.2.0", "description": "A request.formData() wrapper with streaming file upload handling", "author": "Michael Jackson ", "repository": { From f5497c976260990407b0bbf3a192a83076a7df3e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 08:03:55 -0700 Subject: [PATCH 371/730] Treat headers as iterable --- packages/headers/CHANGELOG.md | 4 ++++ packages/headers/src/lib/super-headers.ts | 6 +----- packages/headers/tsconfig.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 97f5b8b0364..691c93f5f87 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -1,5 +1,9 @@ # headers CHANGELOG +## HEAD + +- Treat `Headers` as iterable in the constructor + ## v0.7.1 (Aug 28, 2024) - Added `string` init type to `new Headers({ acceptLanguage })` diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index 5fff3c68446..ee0a92af63f 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -38,7 +38,7 @@ export type SuperHeadersInit = * * [MDN `Headers` Base Class Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers) */ -export class SuperHeaders extends Headers implements Iterable<[string, string]> { +export class SuperHeaders extends Headers { #map: Map; #setCookieValues: (string | SetCookie)[] = []; @@ -60,10 +60,6 @@ export class SuperHeaders extends Headers implements Iterable<[string, string]> for (let [name, value] of init) { this.append(name, value); } - } else if (init instanceof Headers) { - init.forEach((value, name) => { - this.append(name, value); - }); } else if (typeof init === 'object') { for (let name in init) { if (Object.prototype.hasOwnProperty.call(init, name)) { diff --git a/packages/headers/tsconfig.json b/packages/headers/tsconfig.json index d8aaef54f9d..4f02f2c73c9 100644 --- a/packages/headers/tsconfig.json +++ b/packages/headers/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "lib": ["DOM", "ES2020"], + "lib": ["DOM", "DOM.Iterable", "ES2020"], "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true From 63d45dfd263f527a867c8a3b670a5dfd82bcd418 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 28 Aug 2024 09:19:46 -0700 Subject: [PATCH 372/730] Add Nx --- nx.json | 13 + package.json | 5 +- pnpm-lock.yaml | 920 ++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 932 insertions(+), 6 deletions(-) create mode 100644 nx.json diff --git a/nx.json b/nx.json new file mode 100644 index 00000000000..e79256232a1 --- /dev/null +++ b/nx.json @@ -0,0 +1,13 @@ +{ + "$schema": "./node_modules/nx/schemas/nx-schema.json", + "targetDefaults": { + "build": { + "dependsOn": ["^build"], + "outputs": ["{projectRoot}/dist"], + "cache": true + }, + "test": { + "cache": true + } + } +} diff --git a/package.json b/package.json index 4ab74067ce5..1ea5d6395ed 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,10 @@ "devDependencies": { "@swc-node/register": "^1.10.9", "prettier": "^3.3.3", - "typescript": "^5.5.4" + "typescript": "^5.5.4", + "nx": "19.6.3" }, "scripts": { "clean": "git clean -fdX ." } -} +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 53523e212de..355096512dd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@swc-node/register': specifier: ^1.10.9 version: 1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4) + nx: + specifier: 19.6.3 + version: 19.6.3(@swc-node/register@1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.7.18) prettier: specifier: ^3.3.3 version: 3.3.3 @@ -352,6 +355,10 @@ packages: '@fastify/busboy@3.0.0': resolution: {integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==} + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -374,6 +381,70 @@ packages: '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} + '@nrwl/tao@19.6.3': + resolution: {integrity: sha512-j4vPU87yBhTrdyPFSNhlUkN29w4BQ+M14khT8PFGe+Y26gHMxNRNXNFUCwtVARYAc6IwxS8Uvlwy7AwXG2ETPA==} + hasBin: true + + '@nx/nx-darwin-arm64@19.6.3': + resolution: {integrity: sha512-P7WlX5YDZOABAlyfpR6eObigQTNuUuy3iJVUuGwp1Nuo3VPMPkpK1GMWKWLwOR9+2jGnF5MzuqWHk7CdF33uqQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@nx/nx-darwin-x64@19.6.3': + resolution: {integrity: sha512-HF28dPc7h0EmEGYJWJUPA3cBvjXyHbSbGQP5oP885gos9zcyVBjQ2kdJEUZDNMHB9KlZraeXbmV1umFkikjn6A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@nx/nx-freebsd-x64@19.6.3': + resolution: {integrity: sha512-y52dWxQ/x2ccyPqA4Vou4CnTqZX4gr/wV9myJX56G1CyEpWasmcqmPFeOKQd6dj7llGM/KJ/4Gz29RYxcWffcA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@nx/nx-linux-arm-gnueabihf@19.6.3': + resolution: {integrity: sha512-RneCg1tglLbP4cmGnGUs4FgZVT0aOA9wA53tO4IbyxLnlRXNY9OE452YLgqv3H7sLtNjsey2Lkq1seBHtr3p/Q==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@nx/nx-linux-arm64-gnu@19.6.3': + resolution: {integrity: sha512-Y+vgqaxrPQUEtCzxK25QY4ahO90l0eWgVrvCALexGmq0lW41JrVpfTTsbH/BAPLsx+u8A/GPAQAgrmg7d5lSxw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@nx/nx-linux-arm64-musl@19.6.3': + resolution: {integrity: sha512-o/99DBgafbjiJ4e9KFxaldvtlZta/FdzEiQQW+SQQ0JGSYlLCZZ8tIT6t3edV7cmG+gQLNMwolJzgpY53O9wjA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@nx/nx-linux-x64-gnu@19.6.3': + resolution: {integrity: sha512-ppp0NBOhwJ39U1vR7h8jhFSfiur6CZPSUYjXsV44BlaNGc1wHZ+7FDXhzOTokgTNWHavYgYOJuVan5LtTLKJkA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@nx/nx-linux-x64-musl@19.6.3': + resolution: {integrity: sha512-H7xgsT5OTtVYCXjXBLZu28v+rIInhbUggrgVJ2iQJFGBT2A2qmvGmDJdcDz8+K90ku1f4VuWmm8i+TEyDEcBuQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@nx/nx-win32-arm64-msvc@19.6.3': + resolution: {integrity: sha512-o9O6lSmx67zUnqOtlDC4YpC++fiUkixgIsQEG8J/2jdNgAATqOtERcqCNra/uke/Q94Vht2tVXjXF3uj92APhw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@nx/nx-win32-x64-msvc@19.6.3': + resolution: {integrity: sha512-6NQhc7jYQ/sqPt5fDy8C+br73kTd5jhb8ZkPtEy2Amr1aA1K9SAxZAYfyvxLHS2z1nBEelNFgXe6HBmDX92FkA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + '@oxc-resolver/binding-darwin-arm64@1.11.0': resolution: {integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==} cpu: [arm64] @@ -429,6 +500,9 @@ packages: cpu: [x64] os: [win32] + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@swc-node/core@1.13.3': resolution: {integrity: sha512-OGsvXIid2Go21kiNqeTIn79jcaX4l0G93X2rAnas4LFoDyA9wAwVK7xZdm+QsKoMn5Mus2yFLCc4OtX2dD/PWA==} engines: {node: '>= 10'} @@ -547,6 +621,17 @@ packages: '@types/ws@8.5.12': resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} + '@yarnpkg/lockfile@1.1.0': + resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} + + '@yarnpkg/parsers@3.0.0-rc.46': + resolution: {integrity: sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==} + engines: {node: '>=14.15.0'} + + '@zkochan/js-yaml@0.0.7': + resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} + hasBin: true + acorn-walk@8.3.3: resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} engines: {node: '>=0.4.0'} @@ -556,20 +641,60 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + as-table@1.0.55: resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.7.5: + resolution: {integrity: sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==} + + 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'} + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + blake3-wasm@2.1.5: resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -577,6 +702,9 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + bun-types@1.1.26: resolution: {integrity: sha512-n7jDe62LsB2+WE8Q8/mT3azkPaatKlj/2MyP6hi3mKvPz9oPpB6JW/Ll6JHtNLudasFFuvfgklYSE+rreGvBjw==} @@ -587,13 +715,44 @@ packages: capnp-ts@0.7.0: resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + + cli-spinners@2.6.1: + resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} + engines: {node: '>=6'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + consola@3.2.3: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} engines: {node: ^14.18.0 || >=16.10.0} @@ -617,18 +776,67 @@ packages: supports-color: optional: true + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + dotenv-expand@11.0.6: + resolution: {integrity: sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==} + engines: {node: '>=12'} + + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + enquirer@2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + esbuild@0.17.19: resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} engines: {node: '>=12'} hasBin: true + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + estree-walker@0.6.1: resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} @@ -636,10 +844,41 @@ packages: resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} engines: {node: '>=6'} + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + front-matter@4.0.2: + resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -648,6 +887,10 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + get-source@2.0.12: resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} @@ -658,10 +901,27 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -670,31 +930,102 @@ packages: resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} engines: {node: '>= 0.4'} + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + lines-and-columns@2.0.4: + resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + mime@3.0.0: resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} engines: {node: '>=10.0.0'} hasBin: true + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + miniflare@3.20240821.0: resolution: {integrity: sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==} engines: {node: '>=16.13'} hasBin: true + minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + mrmime@2.0.0: resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} engines: {node: '>=10'} @@ -721,13 +1052,51 @@ packages: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} + node-machine-id@1.1.12: + resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + nx@19.6.3: + resolution: {integrity: sha512-JbgrEKaIBvTfhw3mG3GeyyzJHBAMfuQkMNrxxIto1fn94gxdjXdMfqUnAzrW6xRAt5OEEU+rf7v2OA3vEXYc3A==} + hasBin: true + peerDependencies: + '@swc-node/register': ^1.8.0 + '@swc/core': ^1.3.85 + peerDependenciesMeta: + '@swc-node/register': + optional: true + '@swc/core': + optional: true + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + ora@5.3.0: + resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} + engines: {node: '>=10'} + oxc-resolver@1.11.0: resolution: {integrity: sha512-N3qMse2AM7uST8PaiUMXZkcACyGAMN073tomyvzHTICSzaOqKHvVS0IZ3vj/OqoE140QP4CyOiWmgC1Hw5Urmg==} + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -750,13 +1119,31 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + printable-characters@1.0.42: resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + resolve.exports@2.0.2: resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} engines: {node: '>=10'} @@ -765,6 +1152,10 @@ packages: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + rollup-plugin-inject@3.0.2: resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. @@ -775,10 +1166,21 @@ packages: rollup-pluginutils@2.8.2: resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + selfsigned@2.4.1: resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} engines: {node: '>=10'} + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -790,6 +1192,9 @@ packages: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} deprecated: Please use @jridgewell/sourcemap-codec instead + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + stacktracey@2.1.8: resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} @@ -801,10 +1206,41 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + 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'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strong-log-transformer@2.1.0: + resolution: {integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==} + engines: {node: '>=4'} + hasBin: true + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + tmp@0.2.3: resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} engines: {node: '>=14.14'} @@ -813,6 +1249,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} @@ -837,6 +1277,16 @@ packages: unenv-nightly@1.10.0-1717606461.a117952: resolution: {integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + workerd@1.20240821.1: resolution: {integrity: sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==} engines: {node: '>=16'} @@ -852,6 +1302,13 @@ packages: '@cloudflare/workers-types': optional: true + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@8.18.0: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} @@ -867,6 +1324,18 @@ packages: xxhash-wasm@1.0.2: resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + youch@3.3.3: resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} @@ -906,17 +1375,14 @@ snapshots: dependencies: '@emnapi/wasi-threads': 1.0.1 tslib: 2.7.0 - optional: true '@emnapi/runtime@1.2.0': dependencies: tslib: 2.7.0 - optional: true '@emnapi/wasi-threads@1.0.1': dependencies: tslib: 2.7.0 - optional: true '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': dependencies: @@ -998,6 +1464,10 @@ snapshots: '@fastify/busboy@3.0.0': {} + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.5.0': {} @@ -1022,6 +1492,44 @@ snapshots: '@emnapi/core': 1.2.0 '@emnapi/runtime': 1.2.0 '@tybys/wasm-util': 0.9.0 + + '@nrwl/tao@19.6.3(@swc-node/register@1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.7.18)': + dependencies: + nx: 19.6.3(@swc-node/register@1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.7.18) + tslib: 2.7.0 + transitivePeerDependencies: + - '@swc-node/register' + - '@swc/core' + - debug + + '@nx/nx-darwin-arm64@19.6.3': + optional: true + + '@nx/nx-darwin-x64@19.6.3': + optional: true + + '@nx/nx-freebsd-x64@19.6.3': + optional: true + + '@nx/nx-linux-arm-gnueabihf@19.6.3': + optional: true + + '@nx/nx-linux-arm64-gnu@19.6.3': + optional: true + + '@nx/nx-linux-arm64-musl@19.6.3': + optional: true + + '@nx/nx-linux-x64-gnu@19.6.3': + optional: true + + '@nx/nx-linux-x64-musl@19.6.3': + optional: true + + '@nx/nx-win32-arm64-msvc@19.6.3': + optional: true + + '@nx/nx-win32-x64-msvc@19.6.3': optional: true '@oxc-resolver/binding-darwin-arm64@1.11.0': @@ -1059,6 +1567,8 @@ snapshots: '@oxc-resolver/binding-win32-x64-msvc@1.11.0': optional: true + '@sinclair/typebox@0.27.8': {} + '@swc-node/core@1.13.3(@swc/core@1.7.18)(@swc/types@0.1.12)': dependencies: '@swc/core': 1.7.18 @@ -1139,7 +1649,6 @@ snapshots: '@tybys/wasm-util@0.9.0': dependencies: tslib: 2.7.0 - optional: true '@types/bun@1.1.8': dependencies: @@ -1171,31 +1680,87 @@ snapshots: dependencies: '@types/node': 22.5.0 + '@yarnpkg/lockfile@1.1.0': {} + + '@yarnpkg/parsers@3.0.0-rc.46': + dependencies: + js-yaml: 3.14.1 + tslib: 2.7.0 + + '@zkochan/js-yaml@0.0.7': + dependencies: + argparse: 2.0.1 + acorn-walk@8.3.3: dependencies: acorn: 8.12.1 acorn@8.12.1: {} + ansi-colors@4.1.3: {} + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + as-table@1.0.55: dependencies: printable-characters: 1.0.42 + asynckit@0.4.0: {} + + axios@1.7.5: + dependencies: + follow-redirects: 1.15.6 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + base64-js@1.5.1: {} + binary-extensions@2.3.0: {} + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + blake3-wasm@2.1.5: {} + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + braces@3.0.3: dependencies: fill-range: 7.1.1 buffer-from@1.1.2: {} + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + bun-types@1.1.26: dependencies: '@types/node': 20.12.14 @@ -1212,6 +1777,11 @@ snapshots: transitivePeerDependencies: - supports-color + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -1224,8 +1794,32 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + cli-spinners@2.6.1: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@1.0.4: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + colorette@2.0.20: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + consola@3.2.3: {} cookie@0.5.0: {} @@ -1238,8 +1832,36 @@ snapshots: dependencies: ms: 2.1.2 + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + define-lazy-prop@2.0.0: {} + defu@6.1.4: {} + delayed-stream@1.0.0: {} + + diff-sequences@29.6.3: {} + + dotenv-expand@11.0.6: + dependencies: + dotenv: 16.4.5 + + dotenv@16.4.5: {} + + duplexer@0.1.2: {} + + emoji-regex@8.0.0: {} + + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + enquirer@2.3.6: + dependencies: + ansi-colors: 4.1.3 + esbuild@0.17.19: optionalDependencies: '@esbuild/android-arm': 0.17.19 @@ -1265,21 +1887,55 @@ snapshots: '@esbuild/win32-ia32': 0.17.19 '@esbuild/win32-x64': 0.17.19 + escalade@3.1.2: {} + + escape-string-regexp@1.0.5: {} + escape-string-regexp@4.0.0: {} + esprima@4.0.1: {} + estree-walker@0.6.1: {} exit-hook@2.2.1: {} + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 + flat@5.0.2: {} + + follow-redirects@1.15.6: {} + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + front-matter@4.0.2: + dependencies: + js-yaml: 3.14.1 + + fs-constants@1.0.0: {} + + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + fsevents@2.3.3: optional: true function-bind@1.1.2: {} + get-caller-file@2.0.5: {} + get-source@2.0.12: dependencies: data-uri-to-buffer: 2.0.2 @@ -1291,10 +1947,20 @@ snapshots: glob-to-regexp@0.4.1: {} + graceful-fs@4.2.11: {} + + has-flag@4.0.0: {} + hasown@2.0.2: dependencies: function-bind: 1.1.2 + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + inherits@2.0.4: {} + is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 @@ -1303,20 +1969,71 @@ snapshots: dependencies: hasown: 2.0.2 + is-docker@2.2.1: {} + is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 + is-interactive@1.0.0: {} + is-number@7.0.0: {} + is-unicode-supported@0.1.0: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-get-type@29.6.3: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + json5@2.2.3: {} + + jsonc-parser@3.2.0: {} + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + lines-and-columns@2.0.4: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + magic-string@0.25.9: dependencies: sourcemap-codec: 1.4.8 + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + mime@3.0.0: {} + mimic-fn@2.1.0: {} + miniflare@3.20240821.0: dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -1336,6 +2053,12 @@ snapshots: - supports-color - utf-8-validate + minimatch@9.0.3: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + mrmime@2.0.0: {} ms@2.1.2: {} @@ -1350,8 +2073,92 @@ snapshots: node-forge@1.3.1: {} + node-machine-id@1.1.12: {} + normalize-path@3.0.0: {} + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.7.18): + dependencies: + '@napi-rs/wasm-runtime': 0.2.4 + '@nrwl/tao': 19.6.3(@swc-node/register@1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.7.18) + '@yarnpkg/lockfile': 1.1.0 + '@yarnpkg/parsers': 3.0.0-rc.46 + '@zkochan/js-yaml': 0.0.7 + axios: 1.7.5 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.6.1 + cliui: 8.0.1 + dotenv: 16.4.5 + dotenv-expand: 11.0.6 + enquirer: 2.3.6 + figures: 3.2.0 + flat: 5.0.2 + front-matter: 4.0.2 + fs-extra: 11.2.0 + ignore: 5.3.2 + jest-diff: 29.7.0 + jsonc-parser: 3.2.0 + lines-and-columns: 2.0.4 + minimatch: 9.0.3 + node-machine-id: 1.1.12 + npm-run-path: 4.0.1 + open: 8.4.2 + ora: 5.3.0 + semver: 7.6.3 + string-width: 4.2.3 + strong-log-transformer: 2.1.0 + tar-stream: 2.2.0 + tmp: 0.2.3 + tsconfig-paths: 4.2.0 + tslib: 2.7.0 + yargs: 17.7.2 + yargs-parser: 21.1.1 + optionalDependencies: + '@nx/nx-darwin-arm64': 19.6.3 + '@nx/nx-darwin-x64': 19.6.3 + '@nx/nx-freebsd-x64': 19.6.3 + '@nx/nx-linux-arm-gnueabihf': 19.6.3 + '@nx/nx-linux-arm64-gnu': 19.6.3 + '@nx/nx-linux-arm64-musl': 19.6.3 + '@nx/nx-linux-x64-gnu': 19.6.3 + '@nx/nx-linux-x64-musl': 19.6.3 + '@nx/nx-win32-arm64-msvc': 19.6.3 + '@nx/nx-win32-x64-msvc': 19.6.3 + '@swc-node/register': 1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4) + '@swc/core': 1.7.18 + transitivePeerDependencies: + - debug + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + ora@5.3.0: + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.6.1 + is-interactive: 1.0.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + oxc-resolver@1.11.0: optionalDependencies: '@oxc-resolver/binding-darwin-arm64': 1.11.0 @@ -1366,6 +2173,8 @@ snapshots: '@oxc-resolver/binding-win32-arm64-msvc': 1.11.0 '@oxc-resolver/binding-win32-x64-msvc': 1.11.0 + path-key@3.1.1: {} + path-parse@1.0.7: {} path-to-regexp@6.2.2: {} @@ -1378,12 +2187,30 @@ snapshots: prettier@3.3.3: {} + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + printable-characters@1.0.42: {} + proxy-from-env@1.1.0: {} + + react-is@18.3.1: {} + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + readdirp@3.6.0: dependencies: picomatch: 2.3.1 + require-directory@2.1.1: {} + resolve.exports@2.0.2: {} resolve@1.22.8: @@ -1392,6 +2219,11 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + rollup-plugin-inject@3.0.2: dependencies: estree-walker: 0.6.1 @@ -1406,11 +2238,17 @@ snapshots: dependencies: estree-walker: 0.6.1 + safe-buffer@5.2.1: {} + selfsigned@2.4.1: dependencies: '@types/node-forge': 1.3.11 node-forge: 1.3.1 + semver@7.6.3: {} + + signal-exit@3.0.7: {} + source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 @@ -1420,6 +2258,8 @@ snapshots: sourcemap-codec@1.4.8: {} + sprintf-js@1.0.3: {} + stacktracey@2.1.8: dependencies: as-table: 1.0.55 @@ -1429,14 +2269,56 @@ snapshots: streamsearch@1.1.0: {} + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@3.0.0: {} + + strong-log-transformer@2.1.0: + dependencies: + duplexer: 0.1.2 + minimist: 1.2.8 + through: 2.3.8 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + supports-preserve-symlinks-flag@1.0.0: {} + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + through@2.3.8: {} + tmp@0.2.3: {} to-regex-range@5.0.1: dependencies: is-number: 7.0.0 + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + tslib@2.7.0: {} typescript@5.5.4: {} @@ -1460,6 +2342,14 @@ snapshots: pathe: 1.1.2 ufo: 1.5.4 + universalify@2.0.1: {} + + util-deprecate@1.0.2: {} + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + workerd@1.20240821.1: optionalDependencies: '@cloudflare/workerd-darwin-64': 1.20240821.1 @@ -1496,10 +2386,32 @@ snapshots: - supports-color - utf-8-validate + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + ws@8.18.0: {} xxhash-wasm@1.0.2: {} + y18n@5.0.8: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + youch@3.3.3: dependencies: cookie: 0.5.0 From 17e0dacbbceb3517a9a26f8e9c3d4a0ac1fde7d8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 28 Aug 2024 09:25:03 -0700 Subject: [PATCH 373/730] Add @nx/js --- package.json | 9 +- pnpm-lock.yaml | 2454 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 2387 insertions(+), 76 deletions(-) diff --git a/package.json b/package.json index 1ea5d6395ed..952556abe11 100644 --- a/package.json +++ b/package.json @@ -3,12 +3,15 @@ "private": true, "packageManager": "pnpm@9.9.0", "devDependencies": { + "@nx/js": "19.6.3", "@swc-node/register": "^1.10.9", + "@swc/core": "~1.5.7", + "@swc/helpers": "~0.5.11", + "nx": "19.6.3", "prettier": "^3.3.3", - "typescript": "^5.5.4", - "nx": "19.6.3" + "typescript": "^5.5.4" }, "scripts": { "clean": "git clean -fdX ." } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 355096512dd..c55b0112157 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,12 +8,21 @@ importers: .: devDependencies: + '@nx/js': + specifier: 19.6.3 + version: 19.6.3(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) '@swc-node/register': specifier: ^1.10.9 - version: 1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4) + version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) + '@swc/core': + specifier: ~1.5.7 + version: 1.5.29(@swc/helpers@0.5.12) + '@swc/helpers': + specifier: ~0.5.11 + version: 0.5.12 nx: specifier: 19.6.3 - version: 19.6.3(@swc-node/register@1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.7.18) + version: 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) prettier: specifier: ^3.3.3 version: 3.3.3 @@ -152,6 +161,624 @@ importers: packages: + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.25.4': + resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.25.2': + resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.25.5': + resolution: {integrity: sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.24.7': + resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': + resolution: {integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.25.2': + resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.25.4': + resolution: {integrity: sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.25.2': + resolution: {integrity: sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.6.2': + resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + '@babel/helper-member-expression-to-functions@7.24.8': + resolution: {integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.24.7': + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.25.2': + resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.24.7': + resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.24.8': + resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.25.0': + resolution: {integrity: sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.25.0': + resolution: {integrity: sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-simple-access@7.24.7': + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.24.8': + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.24.8': + resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-wrap-function@7.25.0': + resolution: {integrity: sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.25.0': + resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.25.4': + resolution: {integrity: sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.3': + resolution: {integrity: sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.0': + resolution: {integrity: sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.0': + resolution: {integrity: sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7': + resolution: {integrity: sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.0': + resolution: {integrity: sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-proposal-decorators@7.24.7': + resolution: {integrity: sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-decorators@7.24.7': + resolution: {integrity: sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-dynamic-import@7.8.3': + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-export-namespace-from@7.8.3': + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-assertions@7.24.7': + resolution: {integrity: sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.24.7': + resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.24.7': + resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.25.4': + resolution: {integrity: sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-arrow-functions@7.24.7': + resolution: {integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-generator-functions@7.25.4': + resolution: {integrity: sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-to-generator@7.24.7': + resolution: {integrity: sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoped-functions@7.24.7': + resolution: {integrity: sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoping@7.25.0': + resolution: {integrity: sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-properties@7.25.4': + resolution: {integrity: sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-static-block@7.24.7': + resolution: {integrity: sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + + '@babel/plugin-transform-classes@7.25.4': + resolution: {integrity: sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-computed-properties@7.24.7': + resolution: {integrity: sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.24.8': + resolution: {integrity: sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-dotall-regex@7.24.7': + resolution: {integrity: sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-keys@7.24.7': + resolution: {integrity: sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.0': + resolution: {integrity: sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-dynamic-import@7.24.7': + resolution: {integrity: sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-exponentiation-operator@7.24.7': + resolution: {integrity: sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-export-namespace-from@7.24.7': + resolution: {integrity: sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-for-of@7.24.7': + resolution: {integrity: sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-function-name@7.25.1': + resolution: {integrity: sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-json-strings@7.24.7': + resolution: {integrity: sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-literals@7.25.2': + resolution: {integrity: sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-logical-assignment-operators@7.24.7': + resolution: {integrity: sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-member-expression-literals@7.24.7': + resolution: {integrity: sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-amd@7.24.7': + resolution: {integrity: sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.24.8': + resolution: {integrity: sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-systemjs@7.25.0': + resolution: {integrity: sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-umd@7.24.7': + resolution: {integrity: sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-named-capturing-groups-regex@7.24.7': + resolution: {integrity: sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-new-target@7.24.7': + resolution: {integrity: sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-nullish-coalescing-operator@7.24.7': + resolution: {integrity: sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-numeric-separator@7.24.7': + resolution: {integrity: sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-rest-spread@7.24.7': + resolution: {integrity: sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-super@7.24.7': + resolution: {integrity: sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-catch-binding@7.24.7': + resolution: {integrity: sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-chaining@7.24.8': + resolution: {integrity: sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.24.7': + resolution: {integrity: sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-methods@7.25.4': + resolution: {integrity: sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-property-in-object@7.24.7': + resolution: {integrity: sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-property-literals@7.24.7': + resolution: {integrity: sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regenerator@7.24.7': + resolution: {integrity: sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-reserved-words@7.24.7': + resolution: {integrity: sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-runtime@7.25.4': + resolution: {integrity: sha512-8hsyG+KUYGY0coX6KUCDancA0Vw225KJ2HJO0yCNr1vq5r+lJTleDaJf0K7iOhjw4SWhu03TMBzYTJ9krmzULQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-shorthand-properties@7.24.7': + resolution: {integrity: sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-spread@7.24.7': + resolution: {integrity: sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-sticky-regex@7.24.7': + resolution: {integrity: sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-template-literals@7.24.7': + resolution: {integrity: sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typeof-symbol@7.24.8': + resolution: {integrity: sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.25.2': + resolution: {integrity: sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-escapes@7.24.7': + resolution: {integrity: sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-property-regex@7.24.7': + resolution: {integrity: sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-regex@7.24.7': + resolution: {integrity: sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-sets-regex@7.25.4': + resolution: {integrity: sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/preset-env@7.25.4': + resolution: {integrity: sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-modules@0.1.6-no-external-plugins': + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + + '@babel/preset-typescript@7.24.7': + resolution: {integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/regjsgen@0.8.0': + resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} + + '@babel/runtime@7.25.4': + resolution: {integrity: sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.25.0': + resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.25.4': + resolution: {integrity: sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.25.4': + resolution: {integrity: sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==} + engines: {node: '>=6.9.0'} + '@cloudflare/kv-asset-handler@0.3.4': resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} engines: {node: '>=16.13'} @@ -359,13 +986,24 @@ packages: resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} @@ -381,10 +1019,44 @@ packages: '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nrwl/devkit@19.6.3': + resolution: {integrity: sha512-zrAboArNfrEMjimBl/0YeM08HfjqOEG/VHdCHKO+5QMDg65w7vDJ2flwyNhlmnMl8BMJSy9fNo6PNGhboOf3+w==} + + '@nrwl/js@19.6.3': + resolution: {integrity: sha512-Z5tYcUQNfgmNFMJpGmZd6fB0D1pCKNiS3aci2gxHAUIP0Z5cznTyCuzcJSIRx3uMHENhxXwzLwv2l/cqOqnD8A==} + '@nrwl/tao@19.6.3': resolution: {integrity: sha512-j4vPU87yBhTrdyPFSNhlUkN29w4BQ+M14khT8PFGe+Y26gHMxNRNXNFUCwtVARYAc6IwxS8Uvlwy7AwXG2ETPA==} hasBin: true + '@nrwl/workspace@19.6.3': + resolution: {integrity: sha512-NGJ6Mxpw8U6tZRT4ijGzqthr1NMgT/22uteu4otetLEdlqkh1VvLqJC9tjzLkYXmXF9QuoUrkwQib/HafsZmkg==} + + '@nx/devkit@19.6.3': + resolution: {integrity: sha512-/d8Z5/Cy/H/1rIHxW3VjeK5dlvHwRxRj8rCm8/sj5Pz3GmGX03uuEK+J/p+VlP3gP8dAYMgZu3ImeqTAu6rBtw==} + peerDependencies: + nx: '>= 17 <= 20' + + '@nx/js@19.6.3': + resolution: {integrity: sha512-Ip7DseodvJSRM2sKhUjNMlNLegBtsB1u6TuQUiYOJa2FnIGzXETT2HuDMxBcL+u23xDTNyNvifNZ92mFywa00Q==} + peerDependencies: + verdaccio: ^5.0.4 + peerDependenciesMeta: + verdaccio: + optional: true + '@nx/nx-darwin-arm64@19.6.3': resolution: {integrity: sha512-P7WlX5YDZOABAlyfpR6eObigQTNuUuy3iJVUuGwp1Nuo3VPMPkpK1GMWKWLwOR9+2jGnF5MzuqWHk7CdF33uqQ==} engines: {node: '>= 10'} @@ -445,6 +1117,9 @@ packages: cpu: [x64] os: [win32] + '@nx/workspace@19.6.3': + resolution: {integrity: sha512-DTvVJZuXHQd+F4M9JkTHGjLQADQZfUTs/h+v9/NC+YQHml8eixaNXSSvoHQcvBqO8HntbJz5LAJfQuiJ4IGBKw==} + '@oxc-resolver/binding-darwin-arm64@1.11.0': resolution: {integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==} cpu: [arm64] @@ -519,68 +1194,68 @@ packages: '@swc-node/sourcemap-support@0.5.1': resolution: {integrity: sha512-JxIvIo/Hrpv0JCHSyRpetAdQ6lB27oFYhv0PKCNf1g2gUXOjpeR1exrXccRxLMuAV5WAmGFBwRnNOJqN38+qtg==} - '@swc/core-darwin-arm64@1.7.18': - resolution: {integrity: sha512-MwLc5U+VGPMZm8MjlFBjEB2wyT1EK0NNJ3tn+ps9fmxdFP+PL8EpMiY1O1F2t1ydy2OzBtZz81sycjM9RieFBg==} + '@swc/core-darwin-arm64@1.5.29': + resolution: {integrity: sha512-6F/sSxpHaq3nzg2ADv9FHLi4Fu2A8w8vP8Ich8gIl16D2htStlwnaPmCLjRswO+cFkzgVqy/l01gzNGWd4DFqA==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.7.18': - resolution: {integrity: sha512-IkukOQUw7/14VkHp446OkYGCZEHqZg9pTmTdBawlUyz2JwZMSn2VodCl7aFSdGCsU4Cwni8zKA8CCgkCCAELhw==} + '@swc/core-darwin-x64@1.5.29': + resolution: {integrity: sha512-rF/rXkvUOTdTIfoYbmszbSUGsCyvqACqy1VeP3nXONS+LxFl4bRmRcUTRrblL7IE5RTMCKUuPbqbQSE2hK7bqg==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.7.18': - resolution: {integrity: sha512-ATnb6jJaBeXCqrTUawWdoOy7eP9SCI7UMcfXlYIMxX4otKKspLPAEuGA5RaNxlCcj9ObyO0J3YGbtZ6hhD2pjg==} + '@swc/core-linux-arm-gnueabihf@1.5.29': + resolution: {integrity: sha512-2OAPL8iWBsmmwkjGXqvuUhbmmoLxS1xNXiMq87EsnCNMAKohGc7wJkdAOUL6J/YFpean/vwMWg64rJD4pycBeg==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.7.18': - resolution: {integrity: sha512-poHtH7zL7lEp9K2inY90lGHJABWxURAOgWNeZqrcR5+jwIe7q5KBisysH09Zf/JNF9+6iNns+U0xgWTNJzBuGA==} + '@swc/core-linux-arm64-gnu@1.5.29': + resolution: {integrity: sha512-eH/Q9+8O5qhSxMestZnhuS1xqQMr6M7SolZYxiXJqxArXYILLCF+nq2R9SxuMl0CfjHSpb6+hHPk/HXy54eIRA==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.7.18': - resolution: {integrity: sha512-qnNI1WmcOV7Wz1ZDyK6WrOlzLvJ01rnni8ec950mMHWkLRMP53QvCvhF3S+7gFplWBwWJTOOPPUqJp/PlSxWyQ==} + '@swc/core-linux-arm64-musl@1.5.29': + resolution: {integrity: sha512-TERh2OICAJz+SdDIK9+0GyTUwF6r4xDlFmpoiHKHrrD/Hh3u+6Zue0d7jQ/he/i80GDn4tJQkHlZys+RZL5UZg==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.7.18': - resolution: {integrity: sha512-x9SCqCLzwtlqtD5At3I1a7Gco+EuXnzrJGoucmkpeQohshHuwa+cskqsXO6u1Dz0jXJEuHbBZB9va1wYYfjgFg==} + '@swc/core-linux-x64-gnu@1.5.29': + resolution: {integrity: sha512-WMDPqU7Ji9dJpA+Llek2p9t7pcy7Bob8ggPUvgsIlv3R/eesF9DIzSbrgl6j3EAEPB9LFdSafsgf6kT/qnvqFg==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.7.18': - resolution: {integrity: sha512-qtj8iOpMMgKjzxTv+islmEY0JBsbd93nka0gzcTTmGZxKtL5jSUsYQvkxwNPZr5M9NU1fgaR3n1vE6lFmtY0IQ==} + '@swc/core-linux-x64-musl@1.5.29': + resolution: {integrity: sha512-DO14glwpdKY4POSN0201OnGg1+ziaSVr6/RFzuSLggshwXeeyVORiHv3baj7NENhJhWhUy3NZlDsXLnRFkmhHQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.7.18': - resolution: {integrity: sha512-ltX/Ol9+Qu4SXmISCeuwVgAjSa8nzHTymknpozzVMgjXUoZMoz6lcynfKL1nCh5XLgqh0XNHUKLti5YFF8LrrA==} + '@swc/core-win32-arm64-msvc@1.5.29': + resolution: {integrity: sha512-V3Y1+a1zG1zpYXUMqPIHEMEOd+rHoVnIpO/KTyFwAmKVu8v+/xPEVx/AGoYE67x4vDAAvPQrKI3Aokilqa5yVg==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.7.18': - resolution: {integrity: sha512-RgTcFP3wgyxnQbTCJrlgBJmgpeTXo8t807GU9GxApAXfpLZJ3swJ2GgFUmIJVdLWyffSHF5BEkF3FmF6mtH5AQ==} + '@swc/core-win32-ia32-msvc@1.5.29': + resolution: {integrity: sha512-OrM6yfXw4wXhnVFosOJzarw0Fdz5Y0okgHfn9oFbTPJhoqxV5Rdmd6kXxWu2RiVKs6kGSJFZXHDeUq2w5rTIMg==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.7.18': - resolution: {integrity: sha512-XbZ0wAgzR757+DhQcnv60Y/bK9yuWPhDNRQVFFQVRsowvK3+c6EblyfUSytIidpXgyYFzlprq/9A9ZlO/wvDWw==} + '@swc/core-win32-x64-msvc@1.5.29': + resolution: {integrity: sha512-eD/gnxqKyZQQR0hR7TMkIlJ+nCF9dzYmVVNbYZWuA1Xy94aBPUsEk3Uw3oG7q6R3ErrEUPP0FNf2ztEnv+I+dw==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.7.18': - resolution: {integrity: sha512-qL9v5N5S38ijmqiQRvCFUUx2vmxWT/JJ2rswElnyaHkOHuVoAFhBB90Ywj4RKjh3R0zOjhEcemENTyF3q3G6WQ==} + '@swc/core@1.5.29': + resolution: {integrity: sha512-nvTtHJI43DUSOAf3h9XsqYg8YXKc0/N4il9y4j0xAkO0ekgDNo+3+jbw6MInawjKJF9uulyr+f5bAutTsOKVlw==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '*' @@ -591,9 +1266,24 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + '@swc/helpers@0.5.12': + resolution: {integrity: sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==} + '@swc/types@0.1.12': resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==} + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@tybys/wasm-util@0.9.0': resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} @@ -615,6 +1305,9 @@ packages: '@types/node@22.5.0': resolution: {integrity: sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==} + '@types/parse-json@4.0.2': + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + '@types/tmp@0.2.6': resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} @@ -641,6 +1334,10 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -649,6 +1346,10 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -661,6 +1362,9 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -670,12 +1374,47 @@ packages: as-table@1.0.55: resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} axios@1.7.5: resolution: {integrity: sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==} + babel-plugin-const-enum@1.2.0: + resolution: {integrity: sha512-o1m/6iyyFnp9MRsK1dHF3bneqyf3AlM2q3A/YbgQr2pCat6B6XJVDv2TXqzfY2RYUi4mak6WAksSBPlyYGx9dg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + babel-plugin-macros@2.8.0: + resolution: {integrity: sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==} + + babel-plugin-polyfill-corejs2@0.4.11: + resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.10.6: + resolution: {integrity: sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-regenerator@0.6.2: + resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-transform-typescript-metadata@0.3.2: + resolution: {integrity: sha512-mWEvCQTgXQf48yDqgN7CH50waTyYBeP2Lpqx4nNWab9sxEpdXVeKgfj1qYI2/TgUPQtNFZ85i3PemRtnXVYYJg==} + peerDependencies: + '@babel/core': ^7 + '@babel/traverse': ^7 + peerDependenciesMeta: + '@babel/traverse': + optional: true + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -692,6 +1431,9 @@ packages: blake3-wasm@2.1.5: resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} @@ -699,7 +1441,12 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - buffer-from@1.1.2: + browserslist@4.23.3: + resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} buffer@5.7.1: @@ -712,9 +1459,20 @@ packages: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001653: + resolution: {integrity: sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==} + capnp-ts@0.7.0: resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -739,28 +1497,54 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + columnify@1.6.0: + resolution: {integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==} + engines: {node: '>=8.0.0'} + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + consola@3.2.3: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} engines: {node: ^14.18.0 || >=16.10.0} + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie@0.5.0: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} + core-js-compat@3.38.1: + resolution: {integrity: sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==} + + cosmiconfig@6.0.0: + resolution: {integrity: sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==} + engines: {node: '>=8'} + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + data-uri-to-buffer@2.0.2: resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} @@ -790,10 +1574,19 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + detect-port@1.6.1: + resolution: {integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==} + engines: {node: '>= 4.0.0'} + hasBin: true + diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dotenv-expand@11.0.6: resolution: {integrity: sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==} engines: {node: '>=12'} @@ -805,6 +1598,14 @@ packages: duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + + electron-to-chromium@1.5.13: + resolution: {integrity: sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -815,6 +1616,9 @@ packages: resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} engines: {node: '>=8.6'} + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + esbuild@0.17.19: resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} engines: {node: '>=12'} @@ -840,14 +1644,28 @@ packages: estree-walker@0.6.1: resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + exit-hook@2.2.1: resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} engines: {node: '>=6'} + fast-glob@3.2.7: + resolution: {integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==} + engines: {node: '>=8'} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} + filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -887,6 +1705,10 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -901,9 +1723,17 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -912,6 +1742,10 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hosted-git-info@7.0.2: + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -919,9 +1753,16 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -963,6 +1804,11 @@ packages: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} + jake@10.9.2: + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} + engines: {node: '>=10'} + hasBin: true + jest-diff@29.7.0: resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -971,10 +1817,25 @@ packages: resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true + jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -986,17 +1847,40 @@ packages: jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + lines-and-columns@2.0.4: resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -1019,6 +1903,13 @@ packages: engines: {node: '>=16.13'} hasBin: true + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + minimatch@9.0.3: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} @@ -1055,10 +1946,17 @@ packages: node-machine-id@1.1.12: resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + npm-package-arg@11.0.1: + resolution: {integrity: sha512-M7s1BD4NxdAvBKUPqqRW957Xwcl/4Zvo8Aj+ANrzvIPzGJZElrH7Z//rSaec2ORcND6FHHLnZeY8qgTpXDMFQQ==} + engines: {node: ^16.14.0 || >=18.0.0} + npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} @@ -1093,6 +1991,14 @@ packages: oxc-resolver@1.11.0: resolution: {integrity: sha512-N3qMse2AM7uST8PaiUMXZkcACyGAMN073tomyvzHTICSzaOqKHvVS0IZ3vj/OqoE140QP4CyOiWmgC1Hw5Urmg==} + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -1103,9 +2009,16 @@ packages: path-to-regexp@6.2.2: resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -1126,9 +2039,16 @@ packages: printable-characters@1.0.42: resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + proc-log@3.0.0: + resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} @@ -1140,10 +2060,35 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + regenerate-unicode-properties@10.1.1: + resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regenerator-transform@0.15.2: + resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + + regexpu-core@5.3.2: + resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + engines: {node: '>=4'} + + regjsparser@0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + resolve.exports@2.0.2: resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} engines: {node: '>=10'} @@ -1156,6 +2101,10 @@ packages: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rollup-plugin-inject@3.0.2: resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. @@ -1166,6 +2115,9 @@ packages: rollup-pluginutils@2.8.2: resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -1173,6 +2125,10 @@ packages: resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} engines: {node: '>=10'} + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + semver@7.6.3: resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} @@ -1181,6 +2137,9 @@ packages: signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + source-map-support@0.5.19: + resolution: {integrity: sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==} + source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -1226,6 +2185,10 @@ packages: engines: {node: '>=4'} hasBin: true + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -1245,10 +2208,28 @@ packages: resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} engines: {node: '>=14.14'} + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + ts-node@10.9.1: + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + tsconfig-paths@4.2.0: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} @@ -1277,13 +2258,42 @@ packages: unenv-nightly@1.10.0-1717606461.a117952: resolution: {integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==} + unicode-canonical-property-names-ecmascript@2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.1.0: + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + update-browserslist-db@1.1.0: + resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + validate-npm-package-name@5.0.1: + resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} @@ -1321,28 +2331,863 @@ packages: utf-8-validate: optional: true - xxhash-wasm@1.0.2: - resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} + xxhash-wasm@1.0.2: + resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + youch@3.3.3: + resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} + + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + +snapshots: + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@babel/code-frame@7.24.7': + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.1 + + '@babel/compat-data@7.25.4': {} + + '@babel/core@7.25.2': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.5 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helpers': 7.25.0 + '@babel/parser': 7.25.4 + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 + convert-source-map: 2.0.0 + debug: 4.3.6 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.25.5': + dependencies: + '@babel/types': 7.25.4 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + + '@babel/helper-annotate-as-pure@7.24.7': + dependencies: + '@babel/types': 7.25.4 + + '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': + dependencies: + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-compilation-targets@7.25.2': + dependencies: + '@babel/compat-data': 7.25.4 + '@babel/helper-validator-option': 7.24.8 + browserslist: 4.23.3 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.25.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-member-expression-to-functions': 7.24.8 + '@babel/helper-optimise-call-expression': 7.24.7 + '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/traverse': 7.25.4 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.25.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + regexpu-core: 5.3.2 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + debug: 4.3.6 + lodash.debounce: 4.0.8 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-member-expression-to-functions@7.24.8': + dependencies: + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.24.7': + dependencies: + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + '@babel/traverse': 7.25.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.24.7': + dependencies: + '@babel/types': 7.25.4 + + '@babel/helper-plugin-utils@7.24.8': {} + + '@babel/helper-remap-async-to-generator@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-wrap-function': 7.25.0 + '@babel/traverse': 7.25.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-member-expression-to-functions': 7.24.8 + '@babel/helper-optimise-call-expression': 7.24.7 + '@babel/traverse': 7.25.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-simple-access@7.24.7': + dependencies: + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + dependencies: + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.24.8': {} + + '@babel/helper-validator-identifier@7.24.7': {} + + '@babel/helper-validator-option@7.24.8': {} + + '@babel/helper-wrap-function@7.25.0': + dependencies: + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.4 + '@babel/types': 7.25.4 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.25.0': + dependencies: + '@babel/template': 7.25.0 + '@babel/types': 7.25.4 + + '@babel/highlight@7.24.7': + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.1 + + '@babel/parser@7.25.4': + dependencies: + '@babel/types': 7.25.4 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/traverse': 7.25.4 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/traverse': 7.25.4 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-decorators@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-decorators': 7.24.7(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-decorators@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-import-assertions@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-typescript@7.25.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-arrow-functions@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-async-generator-functions@7.25.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-remap-async-to-generator': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) + '@babel/traverse': 7.25.4 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-remap-async-to-generator': 7.25.0(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-block-scoping@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-class-properties@7.25.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.25.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) + '@babel/traverse': 7.25.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/template': 7.25.0 + + '@babel/plugin-transform-destructuring@7.24.8(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-dotall-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-duplicate-keys@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-dynamic-import@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-exponentiation-operator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.24.7 + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-export-namespace-from@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-for-of@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.25.1(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/traverse': 7.25.4 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-json-strings@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-literals@7.25.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-logical-assignment-operators@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) + + '@babel/plugin-transform-member-expression-literals@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-modules-amd@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.24.8(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-simple-access': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-systemjs@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + '@babel/traverse': 7.25.4 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-named-capturing-groups-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-new-target@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-nullish-coalescing-operator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-numeric-separator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) + + '@babel/plugin-transform-object-rest-spread@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.25.2) + + '@babel/plugin-transform-object-super@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-catch-binding@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-optional-chaining@7.24.8(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-private-methods@7.25.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-private-property-in-object@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-property-literals@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-regenerator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + regenerator-transform: 0.15.2 + + '@babel/plugin-transform-reserved-words@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-runtime@7.25.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-plugin-utils': 7.24.8 + babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.25.2) + babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.25.2) + babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.25.2) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-shorthand-properties@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-spread@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-sticky-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-template-literals@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-typeof-symbol@7.24.8(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-typescript@7.25.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/plugin-syntax-typescript': 7.25.4(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-unicode-escapes@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-unicode-property-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-unicode-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-unicode-sets-regex@7.25.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/preset-env@7.25.4(@babel/core@7.25.2)': + dependencies: + '@babel/compat-data': 7.25.4 + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-validator-option': 7.24.8 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.3(@babel/core@7.25.2) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.2) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-import-assertions': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.25.2) + '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-async-generator-functions': 7.25.4(@babel/core@7.25.2) + '@babel/plugin-transform-async-to-generator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-block-scoped-functions': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-block-scoping': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-transform-class-properties': 7.25.4(@babel/core@7.25.2) + '@babel/plugin-transform-class-static-block': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-classes': 7.25.4(@babel/core@7.25.2) + '@babel/plugin-transform-computed-properties': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-destructuring': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-dotall-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-duplicate-keys': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-transform-dynamic-import': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-exponentiation-operator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-export-namespace-from': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-for-of': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-function-name': 7.25.1(@babel/core@7.25.2) + '@babel/plugin-transform-json-strings': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-literals': 7.25.2(@babel/core@7.25.2) + '@babel/plugin-transform-logical-assignment-operators': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-member-expression-literals': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-modules-amd': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-modules-systemjs': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-transform-modules-umd': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-named-capturing-groups-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-new-target': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-nullish-coalescing-operator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-numeric-separator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-object-rest-spread': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-object-super': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-optional-catch-binding': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-private-methods': 7.25.4(@babel/core@7.25.2) + '@babel/plugin-transform-private-property-in-object': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-property-literals': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-regenerator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-reserved-words': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-shorthand-properties': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-spread': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-sticky-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-template-literals': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-typeof-symbol': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-escapes': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-property-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-sets-regex': 7.25.4(@babel/core@7.25.2) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.25.2) + babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.25.2) + babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.25.2) + babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.25.2) + core-js-compat: 3.38.1 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/types': 7.25.4 + esutils: 2.0.3 - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} + '@babel/preset-typescript@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-validator-option': 7.24.8 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-typescript': 7.25.2(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} + '@babel/regjsgen@0.8.0': {} - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + '@babel/runtime@7.25.4': + dependencies: + regenerator-runtime: 0.14.1 - youch@3.3.3: - resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} + '@babel/template@7.25.0': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.25.4 + '@babel/types': 7.25.4 - zod@3.23.8: - resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + '@babel/traverse@7.25.4': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.5 + '@babel/parser': 7.25.4 + '@babel/template': 7.25.0 + '@babel/types': 7.25.4 + debug: 4.3.6 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color -snapshots: + '@babel/types@7.25.4': + dependencies: + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 '@cloudflare/kv-asset-handler@0.3.4': dependencies: @@ -1468,10 +3313,23 @@ snapshots: dependencies: '@sinclair/typebox': 0.27.8 + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/resolve-uri@3.1.2': {} + '@jridgewell/set-array@1.2.1': {} + '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -1493,14 +3351,111 @@ snapshots: '@emnapi/runtime': 1.2.0 '@tybys/wasm-util': 0.9.0 - '@nrwl/tao@19.6.3(@swc-node/register@1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.7.18)': + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@nrwl/devkit@19.6.3(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': + dependencies: + '@nx/devkit': 19.6.3(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + transitivePeerDependencies: + - nx + + '@nrwl/js@19.6.3(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': + dependencies: + '@nx/js': 19.6.3(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + transitivePeerDependencies: + - '@babel/traverse' + - '@swc-node/register' + - '@swc/core' + - '@swc/wasm' + - '@types/node' + - debug + - nx + - supports-color + - typescript + - verdaccio + + '@nrwl/tao@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + dependencies: + nx: 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + tslib: 2.7.0 + transitivePeerDependencies: + - '@swc-node/register' + - '@swc/core' + - debug + + '@nrwl/workspace@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + dependencies: + '@nx/workspace': 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + transitivePeerDependencies: + - '@swc-node/register' + - '@swc/core' + - debug + + '@nx/devkit@19.6.3(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': dependencies: - nx: 19.6.3(@swc-node/register@1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.7.18) + '@nrwl/devkit': 19.6.3(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + ejs: 3.1.10 + enquirer: 2.3.6 + ignore: 5.3.2 + minimatch: 9.0.3 + nx: 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + semver: 7.6.3 + tmp: 0.2.3 + tslib: 2.7.0 + yargs-parser: 21.1.1 + + '@nx/js@19.6.3(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': + dependencies: + '@babel/core': 7.25.2 + '@babel/plugin-proposal-decorators': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-class-properties': 7.25.4(@babel/core@7.25.2) + '@babel/plugin-transform-runtime': 7.25.4(@babel/core@7.25.2) + '@babel/preset-env': 7.25.4(@babel/core@7.25.2) + '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) + '@babel/runtime': 7.25.4 + '@nrwl/js': 19.6.3(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + '@nx/devkit': 19.6.3(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nx/workspace': 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + babel-plugin-const-enum: 1.2.0(@babel/core@7.25.2) + babel-plugin-macros: 2.8.0 + babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.25.2)(@babel/traverse@7.25.4) + chalk: 4.1.2 + columnify: 1.6.0 + detect-port: 1.6.1 + fast-glob: 3.2.7 + fs-extra: 11.2.0 + ignore: 5.3.2 + js-tokens: 4.0.0 + jsonc-parser: 3.2.0 + minimatch: 9.0.3 + npm-package-arg: 11.0.1 + npm-run-path: 4.0.1 + ora: 5.3.0 + semver: 7.6.3 + source-map-support: 0.5.19 + ts-node: 10.9.1(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(typescript@5.5.4) + tsconfig-paths: 4.2.0 tslib: 2.7.0 transitivePeerDependencies: + - '@babel/traverse' - '@swc-node/register' - '@swc/core' + - '@swc/wasm' + - '@types/node' - debug + - nx + - supports-color + - typescript '@nx/nx-darwin-arm64@19.6.3': optional: true @@ -1532,6 +3487,20 @@ snapshots: '@nx/nx-win32-x64-msvc@19.6.3': optional: true + '@nx/workspace@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + dependencies: + '@nrwl/workspace': 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nx/devkit': 19.6.3(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + chalk: 4.1.2 + enquirer: 2.3.6 + nx: 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + tslib: 2.7.0 + yargs-parser: 21.1.1 + transitivePeerDependencies: + - '@swc-node/register' + - '@swc/core' + - debug + '@oxc-resolver/binding-darwin-arm64@1.11.0': optional: true @@ -1569,16 +3538,16 @@ snapshots: '@sinclair/typebox@0.27.8': {} - '@swc-node/core@1.13.3(@swc/core@1.7.18)(@swc/types@0.1.12)': + '@swc-node/core@1.13.3(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)': dependencies: - '@swc/core': 1.7.18 + '@swc/core': 1.5.29(@swc/helpers@0.5.12) '@swc/types': 0.1.12 - '@swc-node/register@1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4)': + '@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4)': dependencies: - '@swc-node/core': 1.13.3(@swc/core@1.7.18)(@swc/types@0.1.12) + '@swc-node/core': 1.13.3(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12) '@swc-node/sourcemap-support': 0.5.1 - '@swc/core': 1.7.18 + '@swc/core': 1.5.29(@swc/helpers@0.5.12) colorette: 2.0.20 debug: 4.3.6 oxc-resolver: 1.11.0 @@ -1594,58 +3563,71 @@ snapshots: source-map-support: 0.5.21 tslib: 2.7.0 - '@swc/core-darwin-arm64@1.7.18': + '@swc/core-darwin-arm64@1.5.29': optional: true - '@swc/core-darwin-x64@1.7.18': + '@swc/core-darwin-x64@1.5.29': optional: true - '@swc/core-linux-arm-gnueabihf@1.7.18': + '@swc/core-linux-arm-gnueabihf@1.5.29': optional: true - '@swc/core-linux-arm64-gnu@1.7.18': + '@swc/core-linux-arm64-gnu@1.5.29': optional: true - '@swc/core-linux-arm64-musl@1.7.18': + '@swc/core-linux-arm64-musl@1.5.29': optional: true - '@swc/core-linux-x64-gnu@1.7.18': + '@swc/core-linux-x64-gnu@1.5.29': optional: true - '@swc/core-linux-x64-musl@1.7.18': + '@swc/core-linux-x64-musl@1.5.29': optional: true - '@swc/core-win32-arm64-msvc@1.7.18': + '@swc/core-win32-arm64-msvc@1.5.29': optional: true - '@swc/core-win32-ia32-msvc@1.7.18': + '@swc/core-win32-ia32-msvc@1.5.29': optional: true - '@swc/core-win32-x64-msvc@1.7.18': + '@swc/core-win32-x64-msvc@1.5.29': optional: true - '@swc/core@1.7.18': + '@swc/core@1.5.29(@swc/helpers@0.5.12)': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.12 optionalDependencies: - '@swc/core-darwin-arm64': 1.7.18 - '@swc/core-darwin-x64': 1.7.18 - '@swc/core-linux-arm-gnueabihf': 1.7.18 - '@swc/core-linux-arm64-gnu': 1.7.18 - '@swc/core-linux-arm64-musl': 1.7.18 - '@swc/core-linux-x64-gnu': 1.7.18 - '@swc/core-linux-x64-musl': 1.7.18 - '@swc/core-win32-arm64-msvc': 1.7.18 - '@swc/core-win32-ia32-msvc': 1.7.18 - '@swc/core-win32-x64-msvc': 1.7.18 + '@swc/core-darwin-arm64': 1.5.29 + '@swc/core-darwin-x64': 1.5.29 + '@swc/core-linux-arm-gnueabihf': 1.5.29 + '@swc/core-linux-arm64-gnu': 1.5.29 + '@swc/core-linux-arm64-musl': 1.5.29 + '@swc/core-linux-x64-gnu': 1.5.29 + '@swc/core-linux-x64-musl': 1.5.29 + '@swc/core-win32-arm64-msvc': 1.5.29 + '@swc/core-win32-ia32-msvc': 1.5.29 + '@swc/core-win32-x64-msvc': 1.5.29 + '@swc/helpers': 0.5.12 '@swc/counter@0.1.3': {} + '@swc/helpers@0.5.12': + dependencies: + tslib: 2.7.0 + '@swc/types@0.1.12': dependencies: '@swc/counter': 0.1.3 + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + '@tybys/wasm-util@0.9.0': dependencies: tslib: 2.7.0 @@ -1674,6 +3656,8 @@ snapshots: dependencies: undici-types: 6.19.8 + '@types/parse-json@4.0.2': {} + '@types/tmp@0.2.6': {} '@types/ws@8.5.12': @@ -1697,10 +3681,16 @@ snapshots: acorn@8.12.1: {} + address@1.2.2: {} + ansi-colors@4.1.3: {} ansi-regex@5.0.1: {} + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 @@ -1712,6 +3702,8 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 + arg@4.1.3: {} + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 @@ -1722,6 +3714,8 @@ snapshots: dependencies: printable-characters: 1.0.42 + async@3.2.6: {} + asynckit@0.4.0: {} axios@1.7.5: @@ -1732,6 +3726,52 @@ snapshots: transitivePeerDependencies: - debug + babel-plugin-const-enum@1.2.0(@babel/core@7.25.2): + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-typescript': 7.25.4(@babel/core@7.25.2) + '@babel/traverse': 7.25.4 + transitivePeerDependencies: + - supports-color + + babel-plugin-macros@2.8.0: + dependencies: + '@babel/runtime': 7.25.4 + cosmiconfig: 6.0.0 + resolve: 1.22.8 + + babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.25.2): + dependencies: + '@babel/compat-data': 7.25.4 + '@babel/core': 7.25.2 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.10.6(@babel/core@7.25.2): + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) + core-js-compat: 3.38.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.25.2): + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-typescript-metadata@0.3.2(@babel/core@7.25.2)(@babel/traverse@7.25.4): + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + optionalDependencies: + '@babel/traverse': 7.25.4 + balanced-match@1.0.2: {} base64-js@1.5.1: {} @@ -1746,6 +3786,11 @@ snapshots: blake3-wasm@2.1.5: {} + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + brace-expansion@2.0.1: dependencies: balanced-match: 1.0.2 @@ -1754,6 +3799,13 @@ snapshots: dependencies: fill-range: 7.1.1 + browserslist@4.23.3: + dependencies: + caniuse-lite: 1.0.30001653 + electron-to-chromium: 1.5.13 + node-releases: 2.0.18 + update-browserslist-db: 1.1.0(browserslist@4.23.3) + buffer-from@1.1.2: {} buffer@5.7.1: @@ -1770,6 +3822,10 @@ snapshots: dependencies: streamsearch: 1.1.0 + callsites@3.1.0: {} + + caniuse-lite@1.0.30001653: {} + capnp-ts@0.7.0: dependencies: debug: 4.3.6 @@ -1777,6 +3833,12 @@ snapshots: transitivePeerDependencies: - supports-color + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -1808,22 +3870,51 @@ snapshots: clone@1.0.4: {} + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + color-convert@2.0.1: dependencies: color-name: 1.1.4 + color-name@1.1.3: {} + color-name@1.1.4: {} colorette@2.0.20: {} + columnify@1.6.0: + dependencies: + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 + concat-map@0.0.1: {} + consola@3.2.3: {} + convert-source-map@2.0.0: {} + cookie@0.5.0: {} + core-js-compat@3.38.1: + dependencies: + browserslist: 4.23.3 + + cosmiconfig@6.0.0: + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + + create-require@1.1.1: {} + data-uri-to-buffer@2.0.2: {} date-fns@3.6.0: {} @@ -1842,8 +3933,17 @@ snapshots: delayed-stream@1.0.0: {} + detect-port@1.6.1: + dependencies: + address: 1.2.2 + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + diff-sequences@29.6.3: {} + diff@4.0.2: {} + dotenv-expand@11.0.6: dependencies: dotenv: 16.4.5 @@ -1852,6 +3952,12 @@ snapshots: duplexer@0.1.2: {} + ejs@3.1.10: + dependencies: + jake: 10.9.2 + + electron-to-chromium@1.5.13: {} + emoji-regex@8.0.0: {} end-of-stream@1.4.4: @@ -1862,6 +3968,10 @@ snapshots: dependencies: ansi-colors: 4.1.3 + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + esbuild@0.17.19: optionalDependencies: '@esbuild/android-arm': 0.17.19 @@ -1897,12 +4007,30 @@ snapshots: estree-walker@0.6.1: {} + esutils@2.0.3: {} + exit-hook@2.2.1: {} + fast-glob@3.2.7: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + figures@3.2.0: dependencies: escape-string-regexp: 1.0.5 + filelist@1.0.4: + dependencies: + minimatch: 5.1.6 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -1934,6 +4062,8 @@ snapshots: function-bind@1.1.2: {} + gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} get-source@2.0.12: @@ -1947,20 +4077,35 @@ snapshots: glob-to-regexp@0.4.1: {} + globals@11.12.0: {} + graceful-fs@4.2.11: {} + has-flag@3.0.0: {} + has-flag@4.0.0: {} hasown@2.0.2: dependencies: function-bind: 1.1.2 + hosted-git-info@7.0.2: + dependencies: + lru-cache: 10.4.3 + ieee754@1.2.1: {} ignore@5.3.2: {} + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + inherits@2.0.4: {} + is-arrayish@0.2.1: {} + is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 @@ -1989,6 +4134,13 @@ snapshots: dependencies: is-docker: 2.2.1 + jake@10.9.2: + dependencies: + async: 3.2.6 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + jest-diff@29.7.0: dependencies: chalk: 4.1.2 @@ -1998,11 +4150,19 @@ snapshots: jest-get-type@29.6.3: {} + js-tokens@4.0.0: {} + js-yaml@3.14.1: dependencies: argparse: 1.0.10 esprima: 4.0.1 + jsesc@0.5.0: {} + + jsesc@2.5.2: {} + + json-parse-even-better-errors@2.3.1: {} + json5@2.2.3: {} jsonc-parser@3.2.0: {} @@ -2013,17 +4173,36 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + lines-and-columns@1.2.4: {} + lines-and-columns@2.0.4: {} + lodash.debounce@4.0.8: {} + log-symbols@4.1.0: dependencies: chalk: 4.1.2 is-unicode-supported: 0.1.0 + lru-cache@10.4.3: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + magic-string@0.25.9: dependencies: sourcemap-codec: 1.4.8 + make-error@1.3.6: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + mime-db@1.52.0: {} mime-types@2.1.35: @@ -2053,6 +4232,14 @@ snapshots: - supports-color - utf-8-validate + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + minimatch@9.0.3: dependencies: brace-expansion: 2.0.1 @@ -2075,16 +4262,25 @@ snapshots: node-machine-id@1.1.12: {} + node-releases@2.0.18: {} + normalize-path@3.0.0: {} + npm-package-arg@11.0.1: + dependencies: + hosted-git-info: 7.0.2 + proc-log: 3.0.0 + semver: 7.6.3 + validate-npm-package-name: 5.0.1 + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 - nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.7.18): + nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)): dependencies: '@napi-rs/wasm-runtime': 0.2.4 - '@nrwl/tao': 19.6.3(@swc-node/register@1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.7.18) + '@nrwl/tao': 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.0-rc.46 '@zkochan/js-yaml': 0.0.7 @@ -2129,8 +4325,8 @@ snapshots: '@nx/nx-linux-x64-musl': 19.6.3 '@nx/nx-win32-arm64-msvc': 19.6.3 '@nx/nx-win32-x64-msvc': 19.6.3 - '@swc-node/register': 1.10.9(@swc/core@1.7.18)(@swc/types@0.1.12)(typescript@5.5.4) - '@swc/core': 1.7.18 + '@swc-node/register': 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) + '@swc/core': 1.5.29(@swc/helpers@0.5.12) transitivePeerDependencies: - debug @@ -2173,14 +4369,29 @@ snapshots: '@oxc-resolver/binding-win32-arm64-msvc': 1.11.0 '@oxc-resolver/binding-win32-x64-msvc': 1.11.0 + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.24.7 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + path-key@3.1.1: {} path-parse@1.0.7: {} path-to-regexp@6.2.2: {} + path-type@4.0.0: {} + pathe@1.1.2: {} + picocolors@1.0.1: {} + picomatch@2.3.1: {} pirates@4.0.6: {} @@ -2195,8 +4406,12 @@ snapshots: printable-characters@1.0.42: {} + proc-log@3.0.0: {} + proxy-from-env@1.1.0: {} + queue-microtask@1.2.3: {} + react-is@18.3.1: {} readable-stream@3.6.2: @@ -2209,8 +4424,35 @@ snapshots: dependencies: picomatch: 2.3.1 + regenerate-unicode-properties@10.1.1: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regenerator-runtime@0.14.1: {} + + regenerator-transform@0.15.2: + dependencies: + '@babel/runtime': 7.25.4 + + regexpu-core@5.3.2: + dependencies: + '@babel/regjsgen': 0.8.0 + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.1 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 + + regjsparser@0.9.1: + dependencies: + jsesc: 0.5.0 + require-directory@2.1.1: {} + resolve-from@4.0.0: {} + resolve.exports@2.0.2: {} resolve@1.22.8: @@ -2224,6 +4466,8 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 + reusify@1.0.4: {} + rollup-plugin-inject@3.0.2: dependencies: estree-walker: 0.6.1 @@ -2238,6 +4482,10 @@ snapshots: dependencies: estree-walker: 0.6.1 + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + safe-buffer@5.2.1: {} selfsigned@2.4.1: @@ -2245,10 +4493,17 @@ snapshots: '@types/node-forge': 1.3.11 node-forge: 1.3.1 + semver@6.3.1: {} + semver@7.6.3: {} signal-exit@3.0.7: {} + source-map-support@0.5.19: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 @@ -2291,6 +4546,10 @@ snapshots: minimist: 1.2.8 through: 2.3.8 + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -2309,10 +4568,32 @@ snapshots: tmp@0.2.3: {} + to-fast-properties@2.0.0: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 + ts-node@10.9.1(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(typescript@5.5.4): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.5.0 + acorn: 8.12.1 + acorn-walk: 8.3.3 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.5.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optionalDependencies: + '@swc/core': 1.5.29(@swc/helpers@0.5.12) + tsconfig-paths@4.2.0: dependencies: json5: 2.2.3 @@ -2342,10 +4623,31 @@ snapshots: pathe: 1.1.2 ufo: 1.5.4 + unicode-canonical-property-names-ecmascript@2.0.0: {} + + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + + unicode-match-property-value-ecmascript@2.1.0: {} + + unicode-property-aliases-ecmascript@2.1.0: {} + universalify@2.0.1: {} + update-browserslist-db@1.1.0(browserslist@4.23.3): + dependencies: + browserslist: 4.23.3 + escalade: 3.1.2 + picocolors: 1.0.1 + util-deprecate@1.0.2: {} + v8-compile-cache-lib@3.0.1: {} + + validate-npm-package-name@5.0.1: {} + wcwidth@1.0.1: dependencies: defaults: 1.0.4 @@ -2400,6 +4702,10 @@ snapshots: y18n@5.0.8: {} + yallist@3.1.1: {} + + yaml@1.10.2: {} + yargs-parser@21.1.1: {} yargs@17.7.2: @@ -2412,6 +4718,8 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yn@3.1.1: {} + youch@3.3.3: dependencies: cookie: 0.5.0 From 38d8f46348b853785c33e6e3bc39ece6ba2171be Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 28 Aug 2024 09:54:37 -0700 Subject: [PATCH 374/730] Add custom release script --- nx.json | 9 +++++++++ package.json | 4 +++- scripts/release.js | 9 +++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 scripts/release.js diff --git a/nx.json b/nx.json index e79256232a1..1e3d7ae058a 100644 --- a/nx.json +++ b/nx.json @@ -9,5 +9,14 @@ "test": { "cache": true } + }, + "release": { + "projectsRelationship": "independent", + "versionPlans": true, + "version": { + "generatorOptions": { + "updateDependents": "auto" + } + } } } diff --git a/package.json b/package.json index 952556abe11..36e6d7e8f7e 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "remix-the-web", "private": true, "packageManager": "pnpm@9.9.0", + "type": "module", "devDependencies": { "@nx/js": "19.6.3", "@swc-node/register": "^1.10.9", @@ -12,6 +13,7 @@ "typescript": "^5.5.4" }, "scripts": { - "clean": "git clean -fdX ." + "clean": "git clean -fdX .", + "release": "node scripts/release.js" } } diff --git a/scripts/release.js b/scripts/release.js new file mode 100644 index 00000000000..b2334d21772 --- /dev/null +++ b/scripts/release.js @@ -0,0 +1,9 @@ +import { releaseVersion, releaseChangelog } from 'nx/release/index.js'; + +const dryRun = true; +const verbose = true; + +await releaseVersion({ dryRun, verbose }); + +// Force exit because it's connected to the Nx daemon +process.exit(0); From 329395b88359b4b10664aaece1a73a054d4d3a4f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 28 Aug 2024 12:15:35 -0700 Subject: [PATCH 375/730] Do not analyze source files for now --- nx.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nx.json b/nx.json index 1e3d7ae058a..0a3837ded24 100644 --- a/nx.json +++ b/nx.json @@ -11,6 +11,7 @@ } }, "release": { + "projects": ["packages/*"], "projectsRelationship": "independent", "versionPlans": true, "version": { @@ -18,5 +19,10 @@ "updateDependents": "auto" } } + }, + "pluginsConfig": { + "@nx/js": { + "analyzeSourceFiles": false + } } } From a976730eb16a3473f6c42b73e045089b2cc8d072 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 08:09:27 -0700 Subject: [PATCH 376/730] Update to nx 19.6.4 --- nx.json | 5 -- package.json | 4 +- pnpm-lock.yaml | 162 ++++++++++++++++++++++++------------------------- 3 files changed, 83 insertions(+), 88 deletions(-) diff --git a/nx.json b/nx.json index 0a3837ded24..45449fb32db 100644 --- a/nx.json +++ b/nx.json @@ -19,10 +19,5 @@ "updateDependents": "auto" } } - }, - "pluginsConfig": { - "@nx/js": { - "analyzeSourceFiles": false - } } } diff --git a/package.json b/package.json index 36e6d7e8f7e..c680ec08c26 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,11 @@ "packageManager": "pnpm@9.9.0", "type": "module", "devDependencies": { - "@nx/js": "19.6.3", + "@nx/js": "19.6.4", "@swc-node/register": "^1.10.9", "@swc/core": "~1.5.7", "@swc/helpers": "~0.5.11", - "nx": "19.6.3", + "nx": "19.6.4", "prettier": "^3.3.3", "typescript": "^5.5.4" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c55b0112157..0045cbab72c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: devDependencies: '@nx/js': - specifier: 19.6.3 - version: 19.6.3(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + specifier: 19.6.4 + version: 19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) '@swc-node/register': specifier: ^1.10.9 version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) @@ -21,8 +21,8 @@ importers: specifier: ~0.5.11 version: 0.5.12 nx: - specifier: 19.6.3 - version: 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + specifier: 19.6.4 + version: 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) prettier: specifier: ^3.3.3 version: 3.3.3 @@ -1031,94 +1031,94 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@nrwl/devkit@19.6.3': - resolution: {integrity: sha512-zrAboArNfrEMjimBl/0YeM08HfjqOEG/VHdCHKO+5QMDg65w7vDJ2flwyNhlmnMl8BMJSy9fNo6PNGhboOf3+w==} + '@nrwl/devkit@19.6.4': + resolution: {integrity: sha512-jpr+T5/+21W/fwAMB6zDLZKO+ReYAfOOMIeM8CpeBi/r9nWmjGXaXN9YKwEOYS1fath62Y5ldGK4yZUttv1tkw==} - '@nrwl/js@19.6.3': - resolution: {integrity: sha512-Z5tYcUQNfgmNFMJpGmZd6fB0D1pCKNiS3aci2gxHAUIP0Z5cznTyCuzcJSIRx3uMHENhxXwzLwv2l/cqOqnD8A==} + '@nrwl/js@19.6.4': + resolution: {integrity: sha512-yjxxSRST/lWylw4SO1qILg9oiKlBbcVst1nVFZzneTFo2oNuFVSEhluVh5tZ0bz3GZ1RPtHxjiBuWDwQ/QmmAA==} - '@nrwl/tao@19.6.3': - resolution: {integrity: sha512-j4vPU87yBhTrdyPFSNhlUkN29w4BQ+M14khT8PFGe+Y26gHMxNRNXNFUCwtVARYAc6IwxS8Uvlwy7AwXG2ETPA==} + '@nrwl/tao@19.6.4': + resolution: {integrity: sha512-1J8cD+MFzsmboiGe03VlQZ8gt64k/TaYYPZivnnhOJolPPs75nz1JyJX55uWcKKRy/b7FZNKWIu/6Wp9JDhJrQ==} hasBin: true - '@nrwl/workspace@19.6.3': - resolution: {integrity: sha512-NGJ6Mxpw8U6tZRT4ijGzqthr1NMgT/22uteu4otetLEdlqkh1VvLqJC9tjzLkYXmXF9QuoUrkwQib/HafsZmkg==} + '@nrwl/workspace@19.6.4': + resolution: {integrity: sha512-jjqtRjm5AP39s8oPUEehA6O0Zew6BeTi+Uhjb+ggqbFKH9R9hoSITnbJY670WlO4W8yWYxT8isPf1TNdSHkmBw==} - '@nx/devkit@19.6.3': - resolution: {integrity: sha512-/d8Z5/Cy/H/1rIHxW3VjeK5dlvHwRxRj8rCm8/sj5Pz3GmGX03uuEK+J/p+VlP3gP8dAYMgZu3ImeqTAu6rBtw==} + '@nx/devkit@19.6.4': + resolution: {integrity: sha512-mBitFwb/gcz8MR7STt7KQG0vf+QcsasDXiSYcf3OWpc6lGE5wn1q5jg6Iabp49Bd/mdHXVLQnP1aV5A+QqFIOQ==} peerDependencies: nx: '>= 17 <= 20' - '@nx/js@19.6.3': - resolution: {integrity: sha512-Ip7DseodvJSRM2sKhUjNMlNLegBtsB1u6TuQUiYOJa2FnIGzXETT2HuDMxBcL+u23xDTNyNvifNZ92mFywa00Q==} + '@nx/js@19.6.4': + resolution: {integrity: sha512-Z09whMis90on3/5V0RIG1On5bRlNI4q2SGZQmj530+BqRTNdKNqxuYdpGf3oNbw5cgLVGiHcWtHzZROaAzpc4g==} peerDependencies: verdaccio: ^5.0.4 peerDependenciesMeta: verdaccio: optional: true - '@nx/nx-darwin-arm64@19.6.3': - resolution: {integrity: sha512-P7WlX5YDZOABAlyfpR6eObigQTNuUuy3iJVUuGwp1Nuo3VPMPkpK1GMWKWLwOR9+2jGnF5MzuqWHk7CdF33uqQ==} + '@nx/nx-darwin-arm64@19.6.4': + resolution: {integrity: sha512-kRn2FLvhwJA/TJrNlsCSqqQTrguNZLmiRsiXhvjkfUMbUKwyQfVMgJlvkZ+KoqraUSG+Qyb0FmrGur1I/Mld0Q==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@nx/nx-darwin-x64@19.6.3': - resolution: {integrity: sha512-HF28dPc7h0EmEGYJWJUPA3cBvjXyHbSbGQP5oP885gos9zcyVBjQ2kdJEUZDNMHB9KlZraeXbmV1umFkikjn6A==} + '@nx/nx-darwin-x64@19.6.4': + resolution: {integrity: sha512-3uABBUhxVk+SdRwpUu30iuBlgRWm3tA/G9seG+wt7oN2R+fOu8zzRCYa+Blvoh1Ef+D9743Ir4rDc9Mhzl2B2g==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@nx/nx-freebsd-x64@19.6.3': - resolution: {integrity: sha512-y52dWxQ/x2ccyPqA4Vou4CnTqZX4gr/wV9myJX56G1CyEpWasmcqmPFeOKQd6dj7llGM/KJ/4Gz29RYxcWffcA==} + '@nx/nx-freebsd-x64@19.6.4': + resolution: {integrity: sha512-OG83MiEk5L54/vAldmwZJBKEvZaM+DEIDqn2yZLTToBRj5Z9jwKJX3jKP60xbHiaT/hzsb1xPlwhOHJnYd80EQ==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@nx/nx-linux-arm-gnueabihf@19.6.3': - resolution: {integrity: sha512-RneCg1tglLbP4cmGnGUs4FgZVT0aOA9wA53tO4IbyxLnlRXNY9OE452YLgqv3H7sLtNjsey2Lkq1seBHtr3p/Q==} + '@nx/nx-linux-arm-gnueabihf@19.6.4': + resolution: {integrity: sha512-hQ9x4qSKUh9mIVDuD270ULrBnmYfDTjXq7LnIwECw1AuP4LkKzKxULhsbqVnFQ/k3xxyFkwyGTIu2mfDcw16Gw==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@nx/nx-linux-arm64-gnu@19.6.3': - resolution: {integrity: sha512-Y+vgqaxrPQUEtCzxK25QY4ahO90l0eWgVrvCALexGmq0lW41JrVpfTTsbH/BAPLsx+u8A/GPAQAgrmg7d5lSxw==} + '@nx/nx-linux-arm64-gnu@19.6.4': + resolution: {integrity: sha512-OFKpAHiaVg3YGFIMBmi/JshciP9buwtOPiHDXcQdzQgE22jyYzKEiFxfcpG0nCT8PlMYAbHPAda15WfWkfVGVQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@nx/nx-linux-arm64-musl@19.6.3': - resolution: {integrity: sha512-o/99DBgafbjiJ4e9KFxaldvtlZta/FdzEiQQW+SQQ0JGSYlLCZZ8tIT6t3edV7cmG+gQLNMwolJzgpY53O9wjA==} + '@nx/nx-linux-arm64-musl@19.6.4': + resolution: {integrity: sha512-ZIR9u+mN0A7SmNd6vDxmPV1QVTgYPTdfBSM5TEnKl3q2fHw2Nkui81QBxA4d7VopJoJUz/pRHiUV+dlgEEZ6nA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@nx/nx-linux-x64-gnu@19.6.3': - resolution: {integrity: sha512-ppp0NBOhwJ39U1vR7h8jhFSfiur6CZPSUYjXsV44BlaNGc1wHZ+7FDXhzOTokgTNWHavYgYOJuVan5LtTLKJkA==} + '@nx/nx-linux-x64-gnu@19.6.4': + resolution: {integrity: sha512-AUMPvLs9KeCUuWD5DdlpbP3VfVsiD0IlptS2b3ul336rsQ7LwwdvE7jTVO5CixFOsiRZxP72fKJhaEargMn5Aw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@nx/nx-linux-x64-musl@19.6.3': - resolution: {integrity: sha512-H7xgsT5OTtVYCXjXBLZu28v+rIInhbUggrgVJ2iQJFGBT2A2qmvGmDJdcDz8+K90ku1f4VuWmm8i+TEyDEcBuQ==} + '@nx/nx-linux-x64-musl@19.6.4': + resolution: {integrity: sha512-PU7AaBlrgnJnDxTiV/PNCu0pHUCzaogm6uNcbzCyFJLGn7DoQK9rkqUMPJjb3CnJkAj9XrrhuZwmOdbrhvHAvA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@nx/nx-win32-arm64-msvc@19.6.3': - resolution: {integrity: sha512-o9O6lSmx67zUnqOtlDC4YpC++fiUkixgIsQEG8J/2jdNgAATqOtERcqCNra/uke/Q94Vht2tVXjXF3uj92APhw==} + '@nx/nx-win32-arm64-msvc@19.6.4': + resolution: {integrity: sha512-6CCmGWwH/J2k+Uxeci48w4QVhtcQ3hRZ5Z2jh26HI8YzH4wqZyA7QPgLBE6sNCPVLoGW5cBgTsfnyEdr+xarQA==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@nx/nx-win32-x64-msvc@19.6.3': - resolution: {integrity: sha512-6NQhc7jYQ/sqPt5fDy8C+br73kTd5jhb8ZkPtEy2Amr1aA1K9SAxZAYfyvxLHS2z1nBEelNFgXe6HBmDX92FkA==} + '@nx/nx-win32-x64-msvc@19.6.4': + resolution: {integrity: sha512-jTNrlaFaKtbL2mYOcfPAiljtpF5CI7vbHIqYqBFYLUQXOwW9lOHlO+SeQnft6JYZs0FIr1IdHaCfdOw/hpnCiQ==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@nx/workspace@19.6.3': - resolution: {integrity: sha512-DTvVJZuXHQd+F4M9JkTHGjLQADQZfUTs/h+v9/NC+YQHml8eixaNXSSvoHQcvBqO8HntbJz5LAJfQuiJ4IGBKw==} + '@nx/workspace@19.6.4': + resolution: {integrity: sha512-SMrI03OmjYm93XpDTlIWgAyIaEhToN4LNu4cxOXW9ygpzPe8HJlqR18aTaCqu1T+BY8XeaZ8BQ7qYS1kEjM9YA==} '@oxc-resolver/binding-darwin-arm64@1.11.0': resolution: {integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==} @@ -1961,8 +1961,8 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} - nx@19.6.3: - resolution: {integrity: sha512-JbgrEKaIBvTfhw3mG3GeyyzJHBAMfuQkMNrxxIto1fn94gxdjXdMfqUnAzrW6xRAt5OEEU+rf7v2OA3vEXYc3A==} + nx@19.6.4: + resolution: {integrity: sha512-yudYlBd3cMchRd8c0ZNan1SfT19AYK2zYOp77XVqVVwgqb6rJVxz6StFGFluUQ7Q7uSpkeT/8PsjwPVLt85EoQ==} hasBin: true peerDependencies: '@swc-node/register': ^1.8.0 @@ -3363,15 +3363,15 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 - '@nrwl/devkit@19.6.3(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': + '@nrwl/devkit@19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': dependencies: - '@nx/devkit': 19.6.3(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nx/devkit': 19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) transitivePeerDependencies: - nx - '@nrwl/js@19.6.3(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': + '@nrwl/js@19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': dependencies: - '@nx/js': 19.6.3(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + '@nx/js': 19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -3384,37 +3384,37 @@ snapshots: - typescript - verdaccio - '@nrwl/tao@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nrwl/tao@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - nx: 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) tslib: 2.7.0 transitivePeerDependencies: - '@swc-node/register' - '@swc/core' - debug - '@nrwl/workspace@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nrwl/workspace@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - '@nx/workspace': 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nx/workspace': 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) transitivePeerDependencies: - '@swc-node/register' - '@swc/core' - debug - '@nx/devkit@19.6.3(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': + '@nx/devkit@19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': dependencies: - '@nrwl/devkit': 19.6.3(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nrwl/devkit': 19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) ejs: 3.1.10 enquirer: 2.3.6 ignore: 5.3.2 minimatch: 9.0.3 - nx: 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) semver: 7.6.3 tmp: 0.2.3 tslib: 2.7.0 yargs-parser: 21.1.1 - '@nx/js@19.6.3(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': + '@nx/js@19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': dependencies: '@babel/core': 7.25.2 '@babel/plugin-proposal-decorators': 7.24.7(@babel/core@7.25.2) @@ -3423,9 +3423,9 @@ snapshots: '@babel/preset-env': 7.25.4(@babel/core@7.25.2) '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) '@babel/runtime': 7.25.4 - '@nrwl/js': 19.6.3(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) - '@nx/devkit': 19.6.3(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) - '@nx/workspace': 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nrwl/js': 19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + '@nx/devkit': 19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nx/workspace': 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) babel-plugin-const-enum: 1.2.0(@babel/core@7.25.2) babel-plugin-macros: 2.8.0 babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.25.2)(@babel/traverse@7.25.4) @@ -3457,43 +3457,43 @@ snapshots: - supports-color - typescript - '@nx/nx-darwin-arm64@19.6.3': + '@nx/nx-darwin-arm64@19.6.4': optional: true - '@nx/nx-darwin-x64@19.6.3': + '@nx/nx-darwin-x64@19.6.4': optional: true - '@nx/nx-freebsd-x64@19.6.3': + '@nx/nx-freebsd-x64@19.6.4': optional: true - '@nx/nx-linux-arm-gnueabihf@19.6.3': + '@nx/nx-linux-arm-gnueabihf@19.6.4': optional: true - '@nx/nx-linux-arm64-gnu@19.6.3': + '@nx/nx-linux-arm64-gnu@19.6.4': optional: true - '@nx/nx-linux-arm64-musl@19.6.3': + '@nx/nx-linux-arm64-musl@19.6.4': optional: true - '@nx/nx-linux-x64-gnu@19.6.3': + '@nx/nx-linux-x64-gnu@19.6.4': optional: true - '@nx/nx-linux-x64-musl@19.6.3': + '@nx/nx-linux-x64-musl@19.6.4': optional: true - '@nx/nx-win32-arm64-msvc@19.6.3': + '@nx/nx-win32-arm64-msvc@19.6.4': optional: true - '@nx/nx-win32-x64-msvc@19.6.3': + '@nx/nx-win32-x64-msvc@19.6.4': optional: true - '@nx/workspace@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nx/workspace@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - '@nrwl/workspace': 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) - '@nx/devkit': 19.6.3(nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nrwl/workspace': 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nx/devkit': 19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) chalk: 4.1.2 enquirer: 2.3.6 - nx: 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) tslib: 2.7.0 yargs-parser: 21.1.1 transitivePeerDependencies: @@ -4277,10 +4277,10 @@ snapshots: dependencies: path-key: 3.1.1 - nx@19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)): + nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)): dependencies: '@napi-rs/wasm-runtime': 0.2.4 - '@nrwl/tao': 19.6.3(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nrwl/tao': 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.0-rc.46 '@zkochan/js-yaml': 0.0.7 @@ -4315,16 +4315,16 @@ snapshots: yargs: 17.7.2 yargs-parser: 21.1.1 optionalDependencies: - '@nx/nx-darwin-arm64': 19.6.3 - '@nx/nx-darwin-x64': 19.6.3 - '@nx/nx-freebsd-x64': 19.6.3 - '@nx/nx-linux-arm-gnueabihf': 19.6.3 - '@nx/nx-linux-arm64-gnu': 19.6.3 - '@nx/nx-linux-arm64-musl': 19.6.3 - '@nx/nx-linux-x64-gnu': 19.6.3 - '@nx/nx-linux-x64-musl': 19.6.3 - '@nx/nx-win32-arm64-msvc': 19.6.3 - '@nx/nx-win32-x64-msvc': 19.6.3 + '@nx/nx-darwin-arm64': 19.6.4 + '@nx/nx-darwin-x64': 19.6.4 + '@nx/nx-freebsd-x64': 19.6.4 + '@nx/nx-linux-arm-gnueabihf': 19.6.4 + '@nx/nx-linux-arm64-gnu': 19.6.4 + '@nx/nx-linux-arm64-musl': 19.6.4 + '@nx/nx-linux-x64-gnu': 19.6.4 + '@nx/nx-linux-x64-musl': 19.6.4 + '@nx/nx-win32-arm64-msvc': 19.6.4 + '@nx/nx-win32-x64-msvc': 19.6.4 '@swc-node/register': 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) '@swc/core': 1.5.29(@swc/helpers@0.5.12) transitivePeerDependencies: From a69a90f6548c23b7c85bd0259bed05ab9c7791ab Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 08:17:54 -0700 Subject: [PATCH 377/730] Add nx key --- packages/headers/package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/headers/package.json b/packages/headers/package.json index 0028a7d0666..70794dff13a 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -32,5 +32,8 @@ "http", "header", "headers" - ] + ], + "nx": { + "name": "headers" + } } From b4de2aa312f38db1a7f6fac6b1c878875e435cde Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 08:20:20 -0700 Subject: [PATCH 378/730] Add version plan for headers release --- .nx/version-plans/version-plan-1724944493296.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .nx/version-plans/version-plan-1724944493296.md diff --git a/.nx/version-plans/version-plan-1724944493296.md b/.nx/version-plans/version-plan-1724944493296.md new file mode 100644 index 00000000000..6058809f171 --- /dev/null +++ b/.nx/version-plans/version-plan-1724944493296.md @@ -0,0 +1,5 @@ +--- +headers: patch +--- + +Treat `Headers` as iterable in the constructor From 51da6188b6e36f3e1efe725eb8baba1e99351b79 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 08:54:31 -0700 Subject: [PATCH 379/730] Add GH releases --- nx.json | 5 +++++ scripts/release.js | 10 +++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/nx.json b/nx.json index 45449fb32db..29af13c1886 100644 --- a/nx.json +++ b/nx.json @@ -18,6 +18,11 @@ "generatorOptions": { "updateDependents": "auto" } + }, + "changelog": { + "projectChangelogs": { + "createRelease": "github" + } } } } diff --git a/scripts/release.js b/scripts/release.js index b2334d21772..61ac79314cd 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -1,9 +1,13 @@ -import { releaseVersion, releaseChangelog } from 'nx/release/index.js'; +import { releaseVersion, releaseChangelog, releasePublish } from 'nx/release/index.js'; -const dryRun = true; +const dryRun = false; const verbose = true; -await releaseVersion({ dryRun, verbose }); +let { projectsVersionData } = await releaseVersion({ dryRun, verbose }); + +await releaseChangelog({ dryRun, verbose, versionData: projectsVersionData }); + +let statusCode = await releasePublish({ dryRun, verbose }); // Force exit because it's connected to the Nx daemon process.exit(0); From b7248d4901bd225be20772c77d4d46387d416938 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 08:55:31 -0700 Subject: [PATCH 380/730] chore(release): publish - project: headers 0.7.2 --- .nx/version-plans/version-plan-1724944493296.md | 5 ----- packages/headers/CHANGELOG.md | 7 +++++++ packages/headers/package.json | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) delete mode 100644 .nx/version-plans/version-plan-1724944493296.md diff --git a/.nx/version-plans/version-plan-1724944493296.md b/.nx/version-plans/version-plan-1724944493296.md deleted file mode 100644 index 6058809f171..00000000000 --- a/.nx/version-plans/version-plan-1724944493296.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -headers: patch ---- - -Treat `Headers` as iterable in the constructor diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 691c93f5f87..7779e98f1f1 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.7.2 (2024-08-29) + + +### 🩹 Fixes + +- **headers:** Treat `Headers` as iterable in the constructor + # headers CHANGELOG ## HEAD diff --git a/packages/headers/package.json b/packages/headers/package.json index 70794dff13a..8f36acd515d 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/headers", - "version": "0.7.1", + "version": "0.7.2", "description": "A toolkit for working with HTTP headers in JavaScript", "author": "Michael Jackson ", "license": "MIT", From 0ffc86aba4debf107640a96d5ce64c52b11eb1f9 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 10:44:06 -0700 Subject: [PATCH 381/730] Fixup changelogs --- packages/file-storage/CHANGELOG.md | 6 ++---- packages/form-data-parser/CHANGELOG.md | 6 ++---- packages/headers/CHANGELOG.md | 19 ++++++------------- packages/lazy-file/CHANGELOG.md | 14 ++++++-------- packages/multipart-parser/CHANGELOG.md | 16 +++++++--------- 5 files changed, 23 insertions(+), 38 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 364b64fa30a..704eb35196b 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -1,10 +1,8 @@ -# file-storage CHANGELOG - -## v0.2.0 (Aug 26, 2024) +## v0.2.0 (2024-08-26) - Moved `LocalFileStorage` to `file-storage/local` export - Moved `MemoryFileStorage` to `file-storage/memory` export -## v0.1.0 (Aug 24, 2024) +## v0.1.0 (2024-08-24) - Initial release diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index 77c9c1ed2b5..d0cd4c1db8b 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -1,9 +1,7 @@ -# form-data-parser CHANGELOG - -## v0.2.0 (Aug 28, 2024) +## v0.2.0 (2024-08-28) - Add missing `FileUpload` export 🤦‍♂️ -## v0.1.0 (Aug 24, 2024) +## v0.1.0 (2024-08-24) - Initial release diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 7779e98f1f1..25fb814d87d 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -1,37 +1,30 @@ ## 0.7.2 (2024-08-29) - ### 🩹 Fixes -- **headers:** Treat `Headers` as iterable in the constructor - -# headers CHANGELOG - -## HEAD - - Treat `Headers` as iterable in the constructor -## v0.7.1 (Aug 28, 2024) +## v0.7.1 (2024-08-28) - Added `string` init type to `new Headers({ acceptLanguage })` -## v0.7.0 (Aug 27, 2024) +## v0.7.0 (2024-08-27) - Added support for the `Accept-Language` header (https://github.com/mjackson/remix-the-web/pull/8, thanks [@ArnoSaine](https://github.com/ArnoSaine)) -## v0.6.1 (Aug 13, 2024) +## v0.6.1 (2024-08-13) - Associate `CacheControl` doc comments with the class instead of the constructor function -## v0.6.0 (Aug 13, 2024) +## v0.6.0 (2024-08-13) - Added support for `Cache-Control` header (https://github.com/mjackson/headers/pull/7, thanks [@alexanderson1993](https://github.com/alexanderson1993)) -## v0.5.1 (Aug 6, 2024) +## v0.5.1 (2024-08-6) - Added `CookieInit` support to `headers.cookie=` setter -## v0.5.0 (Aug 6, 2024) +## v0.5.0 (2024-08-6) - Added the ability to initialize a `SuperHeaders` instance with object config instead of just strings or header object instances. diff --git a/packages/lazy-file/CHANGELOG.md b/packages/lazy-file/CHANGELOG.md index bc862ae7709..4fab38f7dc4 100644 --- a/packages/lazy-file/CHANGELOG.md +++ b/packages/lazy-file/CHANGELOG.md @@ -1,6 +1,4 @@ -# lazy-file CHANGELOG - -## v3.0.0 (Aug 25, 2024) +## v3.0.0 (2024-08-25) - BREAKING: Do not accept regular string argument to `LazyFile`. This more closely matches `File` behavior - BREAKING: Move 4th `LazyFile()` argument `range` into `options.range` @@ -9,27 +7,27 @@ - Added `LazyBlobOptions` and `LazyFileOptions` interfaces (`endings` is not supported) - Return a `name`-less `Blob` from `file.slice()` to more closely match native `File` behavior -## v2.2.0 (Aug 24, 2024) +## v2.2.0 (2024-08-24) - Added support for `getFile(, { lastModified })` to override `file.lastModified` - Export `GetFileOptions` interface from `lazy-file/fs` -## v2.1.0 (Aug 24, 2024) +## v2.1.0 (2024-08-24) - Added `getFile` helper to `lazy-file/fs` export for reading files from the local filesystem -## v2.0.0 (Aug 23, 2024) +## v2.0.0 (2024-08-23) - BREAKING: Do not automatically propagate `name` and `lastModified` in `file.slice()`. This matches the behavior of `File` more closely - BREAKING: Remove `LazyFile[Symbol.asyncIterator]` to match the behavior of `File` more closely - In `slice(start, end)` make `end` default to `size` instead of `Infinity`. This more closely matches the `File` spec - Small perf improvement when streaming content arrays with Blobs in them and ending early -## v1.1.0 (Aug 22, 2024) +## v1.1.0 (2024-08-22) - Add ability to initialize a LazyFile with `BlobPart[]`, just like a normal `File` - Add async iterator support to LazyFile -## v1.0.0 (Aug 21, 2024) +## v1.0.0 (2024-08-21) - Initial release diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index fcceb1e7503..6990936f3d2 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -1,34 +1,32 @@ -# multipart-parser CHANGELOG - -## v0.6.2 (Aug 19, 2024) +## v0.6.2 (2024-08-19) - Provide correct type for `part.arrayBuffer()` - `part.isFile` now correctly detects `part.mediaType === 'application/octet-stream'` -## v0.6.1 (Aug 18, 2024) +## v0.6.1 (2024-08-18) - More small performance improvements -## v0.6.0 (Aug 17, 2024) +## v0.6.0 (2024-08-17) - BREAKING: Removed some low-level API (`parser.push()` and `parser.reset()`) that was duplicating higher-level API. Use `parser.parse()` instead. - Added `parser.maxHeaderSize` and `parser.maxFileSize` properties - Small performance improvements when parsing large files -## v0.5.0 (Aug 15, 2024) +## v0.5.0 (2024-08-15) - Change default `maxFileSize` from 10 MB to `Infinity` - Simplify internal buffer management and search, which leads to more consistent chunk flow when handling large file uploads -## v0.4.2 (Aug 13, 2024) +## v0.4.2 (2024-08-13) - Fix bug where max file size exceeded error would crash Node.js servers (https://github.com/mjackson/multipart-parser/issues/8) -## v0.4.1 (Aug 12, 2024) +## v0.4.1 (2024-08-12) - Add `type` keyword to `MultipartParserOptions` export for Deno (https://github.com/mjackson/multipart-parser/pull/11) -## v0.4.0 (Aug 12, 2024) +## v0.4.0 (2024-08-12) - Switch dependency from `fetch-super-headers` to `@mjackson/headers` - Use `for await...of` to iterate over `ReadableStream` internally. This will also cancel the stream when the loop exits from e.g. an error in a user-defined `part` handler. From 5d0d94bccd28e165079d54911ae3e9dcafcb992d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 28 Aug 2024 08:38:39 -0700 Subject: [PATCH 382/730] Initial commit of node-request-handler --- packages/node-request-handler/CHANGELOG.md | 5 + packages/node-request-handler/LICENSE | 21 ++ packages/node-request-handler/README.md | 1 + packages/node-request-handler/package.json | 42 ++++ packages/node-request-handler/src/global.d.ts | 6 + .../src/lib/node-request-listener.spec.ts | 101 ++++++++++ .../src/lib/node-request-listener.ts | 189 ++++++++++++++++++ .../src/lib/request-handler.ts | 20 ++ .../src/lib/request-url.spec.ts | 74 +++++++ .../src/lib/request-url.ts | 62 ++++++ .../src/lib/trust-proxy.spec.ts | 46 +++++ .../src/lib/trust-proxy.ts | 17 ++ .../src/node-request-handler.ts | 4 + packages/node-request-handler/tsconfig.json | 8 + .../node-request-handler/tsconfig.lib.json | 9 + .../node-request-handler/tsconfig.spec.json | 8 + 16 files changed, 613 insertions(+) create mode 100644 packages/node-request-handler/CHANGELOG.md create mode 100644 packages/node-request-handler/LICENSE create mode 100644 packages/node-request-handler/README.md create mode 100644 packages/node-request-handler/package.json create mode 100644 packages/node-request-handler/src/global.d.ts create mode 100644 packages/node-request-handler/src/lib/node-request-listener.spec.ts create mode 100644 packages/node-request-handler/src/lib/node-request-listener.ts create mode 100644 packages/node-request-handler/src/lib/request-handler.ts create mode 100644 packages/node-request-handler/src/lib/request-url.spec.ts create mode 100644 packages/node-request-handler/src/lib/request-url.ts create mode 100644 packages/node-request-handler/src/lib/trust-proxy.spec.ts create mode 100644 packages/node-request-handler/src/lib/trust-proxy.ts create mode 100644 packages/node-request-handler/src/node-request-handler.ts create mode 100644 packages/node-request-handler/tsconfig.json create mode 100644 packages/node-request-handler/tsconfig.lib.json create mode 100644 packages/node-request-handler/tsconfig.spec.json diff --git a/packages/node-request-handler/CHANGELOG.md b/packages/node-request-handler/CHANGELOG.md new file mode 100644 index 00000000000..84b69e114d9 --- /dev/null +++ b/packages/node-request-handler/CHANGELOG.md @@ -0,0 +1,5 @@ +# node-request-handler CHANGELOG + +## HEAD + +- Initial release diff --git a/packages/node-request-handler/LICENSE b/packages/node-request-handler/LICENSE new file mode 100644 index 00000000000..717984c0442 --- /dev/null +++ b/packages/node-request-handler/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Michael Jackson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/node-request-handler/README.md b/packages/node-request-handler/README.md new file mode 100644 index 00000000000..b63efa59abd --- /dev/null +++ b/packages/node-request-handler/README.md @@ -0,0 +1 @@ +# node-request-handler diff --git a/packages/node-request-handler/package.json b/packages/node-request-handler/package.json new file mode 100644 index 00000000000..e6421e8214e --- /dev/null +++ b/packages/node-request-handler/package.json @@ -0,0 +1,42 @@ +{ + "name": "@mjackson/node-request-handler", + "version": "0.1.0", + "description": "Build servers for Node.js using the web fetch API", + "author": "Michael Jackson ", + "repository": { + "type": "git", + "url": "git+https://github.com/mjackson/remix-the-web.git", + "directory": "packages/node-request-handler" + }, + "license": "MIT", + "files": [ + "dist", + "LICENSE", + "README.md" + ], + "type": "module", + "exports": { + ".": "./dist/node-request-handler.js", + "./package.json": "./package.json" + }, + "dependencies": { + "proxy-addr": "^2.0.7" + }, + "devDependencies": { + "@types/node": "^22.5.0", + "@types/proxy-addr": "^2.0.3" + }, + "scripts": { + "build": "tsc --outDir dist --project tsconfig.lib.json", + "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", + "prepare": "pnpm run build" + }, + "keywords": [ + "http", + "server", + "request", + "response", + "fetch", + "web" + ] +} diff --git a/packages/node-request-handler/src/global.d.ts b/packages/node-request-handler/src/global.d.ts new file mode 100644 index 00000000000..b8041179bc5 --- /dev/null +++ b/packages/node-request-handler/src/global.d.ts @@ -0,0 +1,6 @@ +// See https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62651 + +interface ReadableStream { + values(options?: { preventCancel?: boolean }): AsyncIterableIterator; + [Symbol.asyncIterator](): AsyncIterableIterator; +} diff --git a/packages/node-request-handler/src/lib/node-request-listener.spec.ts b/packages/node-request-handler/src/lib/node-request-listener.spec.ts new file mode 100644 index 00000000000..fa51510f0fc --- /dev/null +++ b/packages/node-request-handler/src/lib/node-request-listener.spec.ts @@ -0,0 +1,101 @@ +import * as assert from 'node:assert/strict'; +import { describe, it, mock } from 'node:test'; + +import * as http from 'node:http'; +import * as stream from 'node:stream'; + +import { RequestHandler } from './request-handler.js'; +import { createRequestListener } from './node-request-listener.js'; + +describe('createRequestListener', () => { + it('returns a request listener', async () => { + await new Promise((resolve) => { + let handler: RequestHandler = async () => { + return new Response('Hello, world!'); + }; + + let listener = createRequestListener(handler); + assert.ok(listener); + + let req = createIncomingMessage(); + let res = createServerResponse(); + + let chunks: Uint8Array[] = []; + mock.method(res, 'write', (chunk: Uint8Array) => { + chunks.push(chunk); + }); + + mock.method(res, 'end', () => { + let body = Buffer.concat(chunks).toString(); + assert.equal(body, 'Hello, world!'); + resolve(); + }); + + listener(req, res); + }); + }); + + it('calls onError when an error is thrown in the request handler', async () => { + await new Promise((resolve) => { + let handler: RequestHandler = async () => { + throw new Error('boom!'); + }; + let errorHandler = mock.fn(); + + let listener = createRequestListener(handler, { onError: errorHandler }); + assert.ok(listener); + + let req = createIncomingMessage(); + let res = createServerResponse(); + + mock.method(res, 'end', () => { + assert.equal(errorHandler.mock.calls.length, 1); + resolve(); + }); + + listener(req, res); + }); + }); +}); + +function createIncomingMessage({ + url = '/', + method = 'GET', + headers = {}, + socket = {}, + body, +}: { + method?: string; + url?: string; + headers?: Record; + socket?: { + encrypted?: boolean; + remoteAddress?: string; + }; + body?: string | Buffer; +} = {}): http.IncomingMessage { + return Object.assign( + new stream.Readable({ + read() { + if (body != null) this.push(Buffer.from(body)); + this.push(null); + }, + }), + { + url, + method, + headers, + socket, + }, + ) as unknown as http.IncomingMessage; +} + +function createServerResponse(): http.ServerResponse { + return Object.assign(new stream.Writable(), { + statusCode: 200, + statusMessage: 'OK', + setHeader() {}, + write() {}, + end() {}, + }) as unknown as http.ServerResponse; +} diff --git a/packages/node-request-handler/src/lib/node-request-listener.ts b/packages/node-request-handler/src/lib/node-request-listener.ts new file mode 100644 index 00000000000..9a37811aef4 --- /dev/null +++ b/packages/node-request-handler/src/lib/node-request-listener.ts @@ -0,0 +1,189 @@ +import * as http from 'node:http'; + +import { RequestHandler, ErrorHandler } from './request-handler.js'; +import { getRequestUrl } from './request-url.js'; +import { TrustArg, createTrustProxy } from './trust-proxy.js'; + +export interface RequestListenerOptions { + /** + * An error handler that determines the response when the request handler throws an error. By + * default a 500 Internal Server Error response will be sent. + */ + onError?: ErrorHandler; + /** + * Determines if/how the `X-Forwarded-Proto` and `X-Forwarded-Host` headers should be used to + * derive the request URL. By default these headers are not trusted because they can easily be + * spoofed. But if you're running behind a reverse proxy, you may use this option to allow them + * to be trusted. + * + * To trust a specific server, pass the IP address of the server as a string: + * + * ```ts + * createRequestListener(handler, { trustProxy: '127.0.0.1' }) + * ``` + * + * To trust a list of servers, pass their addresses in a comma-separated list or an array: + * + * ```ts + * createRequestListener(handler, { trustProxy: '127.0.0.1, 169.254.0.0' }) + * createRequestListener(handler, { trustProxy: ['127.0.0.1', '169.254.0.0'] }) + * ``` + * + * Use a subnet mask to trust a range of servers: + * + * ```ts + * // Trust any server on the 127.0.0.x subnet + * createRequestListener(handler, { trustProxy: '127.0.0.0/8' }) + * ``` + * + * To trust all proxy servers, pass `true`. + * + * ```ts + * createRequestListener(handler, { trustProxy: true }) + * ``` + */ + trustProxy?: boolean | TrustArg; +} + +/** + * Wraps a `RequestHandler` function in a Node.js `http.RequestListener` that can be used with + * `http.createServer()` or `https.createServer()`. + * + * ```ts + * import * as http from 'node:http'; + * import { RequestHandler, createRequestListener } from '@mjackson/node-request-handler'; + * + * let handler: RequestHandler = async (request) => { + * return new Response('Hello, world!'); + * }; + * + * let server = http.createServer( + * createRequestListener(handler) + * ); + * + * server.listen(3000); + * ``` + */ +export function createRequestListener( + handler: RequestHandler, + options?: RequestListenerOptions, +): http.RequestListener { + let onError = options?.onError ?? defaultErrorHandler; + let trustProxy = createTrustProxy(options?.trustProxy); + + return async (req, res) => { + let controller = new AbortController(); + res.on('close', () => { + controller.abort(); + }); + + let url = getRequestUrl(req, trustProxy); + let request = createRequest(req, url, controller.signal); + + try { + let response = await handler(request); + await sendResponse(res, response); + } catch (error) { + try { + let response = await onError(error); + await sendResponse(res, response ?? internalServerError()); + } catch (error) { + console.error(`There was an error in the error handler: ${error}`); + await sendResponse(res, internalServerError()); + } + } + }; +} + +function defaultErrorHandler(error: unknown): Response { + console.error(error); + return internalServerError(); +} + +function internalServerError(): Response { + return new Response('Internal Server Error', { + status: 500, + headers: { + 'Content-Type': 'text/plain', + }, + }); +} + +function createRequest(req: http.IncomingMessage, url: URL, signal: AbortSignal): Request { + let init: RequestInit = { + method: req.method, + headers: createHeaders(req.headers), + signal, + }; + + if (req.method !== 'GET' && req.method !== 'HEAD') { + init.body = createBody(req); + + // init.duplex = 'half' must be set when body is a ReadableStream, and Node follows the spec. + // However, this property is not defined in the TypeScript types for RequestInit, so we have + // to cast it here in order to set it without a type error. + // See https://fetch.spec.whatwg.org/#dom-requestinit-duplex + (init as { duplex: 'half' }).duplex = 'half'; + } + + return new Request(url, init); +} + +function createHeaders(incoming: http.IncomingHttpHeaders): Headers { + let headers = new Headers(); + + for (let key in incoming) { + let value = incoming[key]; + + if (Array.isArray(value)) { + for (let v of value) { + headers.append(key, v); + } + } else if (value != null) { + headers.set(key, value); + } + } + + return headers; +} + +function createBody(req: http.IncomingMessage): ReadableStream { + return new ReadableStream({ + start(controller) { + req.on('data', (chunk) => { + controller.enqueue(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength)); + }); + + req.on('end', () => { + controller.close(); + }); + }, + }); +} + +async function sendResponse(res: http.ServerResponse, response: Response): Promise { + res.statusCode = response.status; + res.statusMessage = response.statusText; + + // @ts-ignore - for some reason headers.entries() is not recognized + for (let [name, value] of response.headers.entries()) { + res.setHeader(name, value); + } + + if (isEventStreamResponse(response)) { + res.flushHeaders(); + } + + if (response.body) { + for await (let chunk of response.body) { + res.write(chunk); + } + } + + res.end(); +} + +function isEventStreamResponse(response: Response): boolean { + let contentType = response.headers.get('Content-Type'); + return contentType?.startsWith('text/event-stream') ?? false; +} diff --git a/packages/node-request-handler/src/lib/request-handler.ts b/packages/node-request-handler/src/lib/request-handler.ts new file mode 100644 index 00000000000..6cd04c4721e --- /dev/null +++ b/packages/node-request-handler/src/lib/request-handler.ts @@ -0,0 +1,20 @@ +/** + * A function that handles an error that occurred during request handling. May return a response to + * send to the client, or `undefined` to allow the server to send a default error response. + * + * [MDN `Response` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Response) + */ +export interface ErrorHandler { + (error: unknown): Response | void | Promise; +} + +/** + * A function that handles an incoming request and returns a response. + * + * [MDN `Request` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Request) + * + * [MDN `Response` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Response) + */ +export interface RequestHandler { + (request: Request): Response | Promise; +} diff --git a/packages/node-request-handler/src/lib/request-url.spec.ts b/packages/node-request-handler/src/lib/request-url.spec.ts new file mode 100644 index 00000000000..e9dd42cdd69 --- /dev/null +++ b/packages/node-request-handler/src/lib/request-url.spec.ts @@ -0,0 +1,74 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import * as http from 'node:http'; + +import { getRequestUrl } from './request-url.js'; +import { createTrustProxy } from './trust-proxy.js'; + +describe('getRequestUrl', () => { + it('returns the URL of an incoming request', () => { + let trustProxy = createTrustProxy(); + let req = { + socket: { + encrypted: false, + remoteAddress: '127.0.0.1', + }, + headers: { + host: 'example.com', + }, + url: '/path?query', + } as unknown as http.IncomingMessage; + + assert.equal(getRequestUrl(req, trustProxy).toString(), 'http://example.com/path?query'); + }); + + it('returns the URL of an incoming request on a secure connection', () => { + let trustProxy = createTrustProxy(); + let req = { + socket: { + encrypted: true, + remoteAddress: '127.0.0.1', + }, + headers: { + host: 'example.com', + }, + url: '/path?query', + } as unknown as http.IncomingMessage; + + assert.equal(getRequestUrl(req, trustProxy).toString(), 'https://example.com/path?query'); + }); + + it('returns the URL of an incoming request with a forwarded protocol', () => { + let trustProxy = createTrustProxy(true); + let req = { + socket: { + encrypted: false, + remoteAddress: '127.0.0.1', + }, + headers: { + 'x-forwarded-proto': 'https', + host: 'example.com', + }, + url: '/path?query', + } as unknown as http.IncomingMessage; + + assert.equal(getRequestUrl(req, trustProxy).toString(), 'https://example.com/path?query'); + }); + + it('returns the URL of an incoming request with a forwarded host', () => { + let trustProxy = createTrustProxy(true); + let req = { + socket: { + encrypted: false, + remoteAddress: '127.0.0.1', + }, + headers: { + 'x-forwarded-host': 'mjackson.me', + host: 'example.com', + }, + url: '/path?query', + } as unknown as http.IncomingMessage; + + assert.equal(getRequestUrl(req, trustProxy).toString(), 'http://mjackson.me/path?query'); + }); +}); diff --git a/packages/node-request-handler/src/lib/request-url.ts b/packages/node-request-handler/src/lib/request-url.ts new file mode 100644 index 00000000000..b955f7ba23a --- /dev/null +++ b/packages/node-request-handler/src/lib/request-url.ts @@ -0,0 +1,62 @@ +import * as http from 'node:http'; +import * as net from 'node:net'; +import * as tls from 'node:tls'; + +import { TrustProxy } from './trust-proxy.js'; + +/** + * Returns the URL of an incoming request. + */ +export function getRequestUrl(req: http.IncomingMessage, trustProxy: TrustProxy): URL { + let protocol = getProtocol(req, trustProxy); + let hostname = getHostname(req, trustProxy); + return new URL(`${protocol}//${hostname}${req.url}`); +} + +function getProtocol(req: http.IncomingMessage, trustProxy: TrustProxy): string { + let socket = req.socket as net.Socket | tls.TLSSocket; + let remoteAddress = socket.remoteAddress; + + let protocol = 'encrypted' in socket && socket.encrypted ? 'https:' : 'http:'; + + if (remoteAddress === undefined || !trustProxy(remoteAddress, 0)) { + return protocol; + } + + let header = req.headers['x-forwarded-proto']; + + if (header === undefined) { + return protocol; + } + + if (Array.isArray(header)) { + header = header[0]; + } + + let index = header.indexOf(','); + + return normalizeProtocol(index === -1 ? header.trim() : header.slice(0, index).trim()); +} + +function normalizeProtocol(protocol: string): string { + return (protocol.endsWith(':') ? protocol : protocol + ':').toLowerCase(); +} + +function getHostname(req: http.IncomingMessage, trustProxy: TrustProxy): string | undefined { + let socket = req.socket as net.Socket | tls.TLSSocket; + let remoteAddress = socket.remoteAddress; + + let header = req.headers['x-forwarded-host']; + + if (header === undefined || remoteAddress === undefined || !trustProxy(remoteAddress, 0)) { + header = req.headers.host; + } else if (Array.isArray(header)) { + header = header[0]; + } + + if (header === undefined) return undefined; + + let index = header.indexOf(','); + + return index === -1 ? header.trim() : header.slice(0, index).trim(); +} diff --git a/packages/node-request-handler/src/lib/trust-proxy.spec.ts b/packages/node-request-handler/src/lib/trust-proxy.spec.ts new file mode 100644 index 00000000000..3b5ca0df636 --- /dev/null +++ b/packages/node-request-handler/src/lib/trust-proxy.spec.ts @@ -0,0 +1,46 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { createTrustProxy } from './trust-proxy.js'; + +describe('createTrustProxy', () => { + it('does not trust by default', () => { + let trustProxy = createTrustProxy(); + assert.ok(!trustProxy('10.0.0.5', 0)); + }); + + it('trusts all proxies', () => { + let trustProxy = createTrustProxy(true); + assert.ok(trustProxy('10.0.0.5', 0)); + }); + + it('does not trust any proxies', () => { + let trustProxy = createTrustProxy(false); + assert.ok(!trustProxy('10.0.0.5', 0)); + }); + + it('trusts a function that returns true', () => { + let trustProxy = createTrustProxy(() => true); + assert.ok(trustProxy('10.0.0.5', 0)); + }); + + it('does not trust a function that returns false', () => { + let trustProxy = createTrustProxy(() => false); + assert.ok(!trustProxy('10.0.0.5', 0)); + }); + + it('trusts a single IP address', () => { + let trustProxy = createTrustProxy('127.0.0.1'); + assert.ok(trustProxy('127.0.0.1', 0)); + }); + + it('trusts a list of IP addresses', () => { + let trustProxy = createTrustProxy('127.0.0.1,10.0.0.5'); + assert.ok(trustProxy('10.0.0.5', 0)); + }); + + it('trusts a list of IP addresses as an array', () => { + let trustProxy = createTrustProxy(['127.0.0.1', '10.0.0.5']); + assert.ok(trustProxy('10.0.0.5', 0)); + }); +}); diff --git a/packages/node-request-handler/src/lib/trust-proxy.ts b/packages/node-request-handler/src/lib/trust-proxy.ts new file mode 100644 index 00000000000..fdcd045392a --- /dev/null +++ b/packages/node-request-handler/src/lib/trust-proxy.ts @@ -0,0 +1,17 @@ +import proxyAddr from 'proxy-addr'; + +export type TrustArg = Parameters[1]; + +export interface TrustProxy { + (addr: string, i: number): boolean; +} + +/** + * Creates a function that determines whether to trust a proxy server. + */ +export function createTrustProxy(trustArg?: boolean | TrustArg): TrustProxy { + if (typeof trustArg === 'boolean') return () => trustArg as boolean; + if (typeof trustArg === 'function') return trustArg; + if (typeof trustArg === 'string') trustArg = trustArg.split(',').map((s) => s.trim()); + return proxyAddr.compile(trustArg || []); +} diff --git a/packages/node-request-handler/src/node-request-handler.ts b/packages/node-request-handler/src/node-request-handler.ts new file mode 100644 index 00000000000..153084c24e6 --- /dev/null +++ b/packages/node-request-handler/src/node-request-handler.ts @@ -0,0 +1,4 @@ +export { type RequestListenerOptions, createRequestListener } from './lib/node-request-listener.js'; +export { type RequestHandler, type ErrorHandler } from './lib/request-handler.js'; +export { getRequestUrl } from './lib/request-url.js'; +export { createTrustProxy } from './lib/trust-proxy.js'; diff --git a/packages/node-request-handler/tsconfig.json b/packages/node-request-handler/tsconfig.json new file mode 100644 index 00000000000..d8aaef54f9d --- /dev/null +++ b/packages/node-request-handler/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "lib": ["DOM", "ES2020"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true + } +} diff --git a/packages/node-request-handler/tsconfig.lib.json b/packages/node-request-handler/tsconfig.lib.json new file mode 100644 index 00000000000..8e712f7d6c8 --- /dev/null +++ b/packages/node-request-handler/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.spec.ts"], + "compilerOptions": { + "composite": true, + "rootDir": "src" + } +} diff --git a/packages/node-request-handler/tsconfig.spec.json b/packages/node-request-handler/tsconfig.spec.json new file mode 100644 index 00000000000..ccfefc4d957 --- /dev/null +++ b/packages/node-request-handler/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.spec.ts"], + "compilerOptions": { + "composite": true, + "types": ["node"] + } +} From 5762cddad923dc1f7638a20be326e0cfac62debc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 28 Aug 2024 23:17:01 -0700 Subject: [PATCH 383/730] Add benchmarking for node-request-handler --- .../node-request-handler/bench/package.json | 12 + .../bench/servers/express.ts | 12 + .../bench/servers/node-http.ts | 10 + .../bench/servers/node-request-handler.ts | 14 + .../node-request-handler/bench/tsconfig.json | 8 + pnpm-lock.yaml | 592 ++++++++++++++++++ pnpm-workspace.yaml | 1 + 7 files changed, 649 insertions(+) create mode 100644 packages/node-request-handler/bench/package.json create mode 100644 packages/node-request-handler/bench/servers/express.ts create mode 100644 packages/node-request-handler/bench/servers/node-http.ts create mode 100644 packages/node-request-handler/bench/servers/node-request-handler.ts create mode 100644 packages/node-request-handler/bench/tsconfig.json diff --git a/packages/node-request-handler/bench/package.json b/packages/node-request-handler/bench/package.json new file mode 100644 index 00000000000..6ae763c547d --- /dev/null +++ b/packages/node-request-handler/bench/package.json @@ -0,0 +1,12 @@ +{ + "name": "node-request-handler-bench", + "private": true, + "type": "module", + "dependencies": { + "@mjackson/node-request-handler": "workspace:*", + "express": "^4.19.2" + }, + "devDependencies": { + "@types/express": "^4.17.21" + } +} diff --git a/packages/node-request-handler/bench/servers/express.ts b/packages/node-request-handler/bench/servers/express.ts new file mode 100644 index 00000000000..124aa0d3fa1 --- /dev/null +++ b/packages/node-request-handler/bench/servers/express.ts @@ -0,0 +1,12 @@ +import express from 'express'; + +let app = express(); + +app.get('/', (_req, res) => { + res.type('text/html'); + res.send('

Hello, world!

'); +}); + +app.listen(3000, () => { + console.log('Listening on http://localhost:3000 ...'); +}); diff --git a/packages/node-request-handler/bench/servers/node-http.ts b/packages/node-request-handler/bench/servers/node-http.ts new file mode 100644 index 00000000000..f35f3ab571b --- /dev/null +++ b/packages/node-request-handler/bench/servers/node-http.ts @@ -0,0 +1,10 @@ +import * as http from 'node:http'; + +let server = http.createServer((_req, res) => { + res.setHeader('Content-Type', 'text/html'); + res.end('

Hello, world!

'); +}); + +server.listen(3000, () => { + console.log('Listening on http://localhost:3000 ...'); +}); diff --git a/packages/node-request-handler/bench/servers/node-request-handler.ts b/packages/node-request-handler/bench/servers/node-request-handler.ts new file mode 100644 index 00000000000..d8d79972ad1 --- /dev/null +++ b/packages/node-request-handler/bench/servers/node-request-handler.ts @@ -0,0 +1,14 @@ +import * as http from 'node:http'; +import { createRequestListener } from '@mjackson/node-request-handler'; + +let server = http.createServer( + createRequestListener(() => { + return new Response('

Hello, world!

', { + headers: { 'Content-Type': 'text/html' }, + }); + }), +); + +server.listen(3000, () => { + console.log('Listening on http://localhost:3000 ...'); +}); diff --git a/packages/node-request-handler/bench/tsconfig.json b/packages/node-request-handler/bench/tsconfig.json new file mode 100644 index 00000000000..d8aaef54f9d --- /dev/null +++ b/packages/node-request-handler/bench/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "lib": ["DOM", "ES2020"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0045cbab72c..9b556d49bab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -159,6 +159,32 @@ importers: specifier: ^0.2.6 version: 0.2.6 + packages/node-request-handler: + dependencies: + proxy-addr: + specifier: ^2.0.7 + version: 2.0.7 + devDependencies: + '@types/node': + specifier: ^22.5.0 + version: 22.5.0 + '@types/proxy-addr': + specifier: ^2.0.3 + version: 2.0.3 + + packages/node-request-handler/bench: + dependencies: + '@mjackson/node-request-handler': + specifier: workspace:* + version: link:.. + express: + specifier: ^4.19.2 + version: 4.19.2 + devDependencies: + '@types/express': + specifier: ^4.17.21 + version: 4.17.21 + packages: '@ampproject/remapping@2.3.0': @@ -1287,12 +1313,30 @@ packages: '@tybys/wasm-util@0.9.0': resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + '@types/body-parser@1.19.5': + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + '@types/bun@1.1.8': resolution: {integrity: sha512-PIwVFQKPviksiibobyvcWtMvMFMTj91T8dQEh9l1P3Ypr3ZuVn9w7HSr+5mTNrPqD1xpdDLEErzZPU8gqHBu6g==} '@types/busboy@1.5.4': resolution: {integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==} + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/express-serve-static-core@4.19.5': + resolution: {integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==} + + '@types/express@4.17.21': + resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + + '@types/http-errors@2.0.4': + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + '@types/node-forge@1.3.11': resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} @@ -1308,6 +1352,21 @@ packages: '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + '@types/proxy-addr@2.0.3': + resolution: {integrity: sha512-TgAHHO4tNG3HgLTUhB+hM4iwW6JUNeQHCLnF1DjaDA9c69PN+IasoFu2MYDhubFc+ZIw5c5t9DMtjvrD6R3Egg==} + + '@types/qs@6.9.15': + resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/send@0.17.4': + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + + '@types/serve-static@1.15.7': + resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + '@types/tmp@0.2.6': resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} @@ -1325,6 +1384,10 @@ packages: resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} hasBin: true + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + acorn-walk@8.3.3: resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} engines: {node: '>=0.4.0'} @@ -1371,6 +1434,9 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + as-table@1.0.55: resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} @@ -1431,6 +1497,10 @@ packages: blake3-wasm@2.1.5: resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + body-parser@1.20.2: + resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -1459,6 +1529,14 @@ packages: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1528,13 +1606,28 @@ packages: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} engines: {node: ^14.18.0 || >=16.10.0} + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + cookie@0.5.0: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + core-js-compat@3.38.1: resolution: {integrity: sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==} @@ -1551,6 +1644,14 @@ packages: date-fns@3.6.0: resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.3.6: resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} engines: {node: '>=6.0'} @@ -1563,6 +1664,10 @@ packages: defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + define-lazy-prop@2.0.0: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} @@ -1574,6 +1679,14 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + detect-port@1.6.1: resolution: {integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==} engines: {node: '>= 4.0.0'} @@ -1598,6 +1711,9 @@ packages: duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + ejs@3.1.10: resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} engines: {node: '>=0.10.0'} @@ -1609,6 +1725,10 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} @@ -1619,6 +1739,14 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + esbuild@0.17.19: resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} engines: {node: '>=12'} @@ -1628,6 +1756,9 @@ packages: resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} engines: {node: '>=6'} + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -1648,10 +1779,18 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + exit-hook@2.2.1: resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} engines: {node: '>=6'} + express@4.19.2: + resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} + engines: {node: '>= 0.10.0'} + fast-glob@3.2.7: resolution: {integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==} engines: {node: '>=8'} @@ -1670,6 +1809,10 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true @@ -1687,6 +1830,14 @@ packages: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + front-matter@4.0.2: resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} @@ -1713,6 +1864,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + get-source@2.0.12: resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} @@ -1727,6 +1882,9 @@ packages: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -1738,6 +1896,17 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -1746,6 +1915,14 @@ packages: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} engines: {node: ^16.14.0 || >=18.0.0} + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -1760,6 +1937,10 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -1873,10 +2054,21 @@ packages: make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -1889,6 +2081,11 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + mime@3.0.0: resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} engines: {node: '>=10.0.0'} @@ -1921,9 +2118,15 @@ packages: resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} engines: {node: '>=10'} + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + multipasta@0.2.5: resolution: {integrity: sha512-c8eMDb1WwZcE02WVjHoOmUVk7fnKU/RmUcosHACglrWAuPQsEJv+E8430sXj6jNc1jHw0zrS16aCjQh4BcEb4A==} @@ -1936,6 +2139,10 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + node-fetch-native@1.6.4: resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} @@ -1973,6 +2180,14 @@ packages: '@swc/core': optional: true + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -1999,6 +2214,10 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -2006,6 +2225,9 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + path-to-regexp@6.2.2: resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} @@ -2043,12 +2265,28 @@ packages: resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} @@ -2121,6 +2359,9 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + selfsigned@2.4.1: resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} engines: {node: '>=10'} @@ -2134,6 +2375,25 @@ packages: engines: {node: '>=10'} hasBin: true + send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + + serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -2157,6 +2417,10 @@ packages: stacktracey@2.1.8: resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + stoppable@1.1.0: resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} engines: {node: '>=4', npm: '>=6'} @@ -2216,6 +2480,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + ts-node@10.9.1: resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true @@ -2237,6 +2505,10 @@ packages: tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + typescript@5.5.4: resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} engines: {node: '>=14.17'} @@ -2278,6 +2550,10 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + update-browserslist-db@1.1.0: resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} hasBin: true @@ -2287,6 +2563,10 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} @@ -2294,6 +2574,10 @@ packages: resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} @@ -3632,6 +3916,11 @@ snapshots: dependencies: tslib: 2.7.0 + '@types/body-parser@1.19.5': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 22.5.0 + '@types/bun@1.1.8': dependencies: bun-types: 1.1.26 @@ -3640,6 +3929,28 @@ snapshots: dependencies: '@types/node': 22.5.0 + '@types/connect@3.4.38': + dependencies: + '@types/node': 22.5.0 + + '@types/express-serve-static-core@4.19.5': + dependencies: + '@types/node': 22.5.0 + '@types/qs': 6.9.15 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + + '@types/express@4.17.21': + dependencies: + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 4.19.5 + '@types/qs': 6.9.15 + '@types/serve-static': 1.15.7 + + '@types/http-errors@2.0.4': {} + + '@types/mime@1.3.5': {} + '@types/node-forge@1.3.11': dependencies: '@types/node': 22.5.0 @@ -3658,6 +3969,25 @@ snapshots: '@types/parse-json@4.0.2': {} + '@types/proxy-addr@2.0.3': + dependencies: + '@types/node': 22.5.0 + + '@types/qs@6.9.15': {} + + '@types/range-parser@1.2.7': {} + + '@types/send@0.17.4': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 22.5.0 + + '@types/serve-static@1.15.7': + dependencies: + '@types/http-errors': 2.0.4 + '@types/node': 22.5.0 + '@types/send': 0.17.4 + '@types/tmp@0.2.6': {} '@types/ws@8.5.12': @@ -3675,6 +4005,11 @@ snapshots: dependencies: argparse: 2.0.1 + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + acorn-walk@8.3.3: dependencies: acorn: 8.12.1 @@ -3710,6 +4045,8 @@ snapshots: argparse@2.0.1: {} + array-flatten@1.1.1: {} + as-table@1.0.55: dependencies: printable-characters: 1.0.42 @@ -3786,6 +4123,23 @@ snapshots: blake3-wasm@2.1.5: {} + body-parser@1.20.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -3822,6 +4176,16 @@ snapshots: dependencies: streamsearch: 1.1.0 + bytes@3.1.2: {} + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + callsites@3.1.0: {} caniuse-lite@1.0.30001653: {} @@ -3897,10 +4261,20 @@ snapshots: consola@3.2.3: {} + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + convert-source-map@2.0.0: {} + cookie-signature@1.0.6: {} + cookie@0.5.0: {} + cookie@0.6.0: {} + core-js-compat@3.38.1: dependencies: browserslist: 4.23.3 @@ -3919,6 +4293,10 @@ snapshots: date-fns@3.6.0: {} + debug@2.6.9: + dependencies: + ms: 2.0.0 + debug@4.3.6: dependencies: ms: 2.1.2 @@ -3927,12 +4305,22 @@ snapshots: dependencies: clone: 1.0.4 + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + define-lazy-prop@2.0.0: {} defu@6.1.4: {} delayed-stream@1.0.0: {} + depd@2.0.0: {} + + destroy@1.2.0: {} + detect-port@1.6.1: dependencies: address: 1.2.2 @@ -3952,6 +4340,8 @@ snapshots: duplexer@0.1.2: {} + ee-first@1.1.1: {} + ejs@3.1.10: dependencies: jake: 10.9.2 @@ -3960,6 +4350,8 @@ snapshots: emoji-regex@8.0.0: {} + encodeurl@1.0.2: {} + end-of-stream@1.4.4: dependencies: once: 1.4.0 @@ -3972,6 +4364,12 @@ snapshots: dependencies: is-arrayish: 0.2.1 + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + esbuild@0.17.19: optionalDependencies: '@esbuild/android-arm': 0.17.19 @@ -3999,6 +4397,8 @@ snapshots: escalade@3.1.2: {} + escape-html@1.0.3: {} + escape-string-regexp@1.0.5: {} escape-string-regexp@4.0.0: {} @@ -4009,8 +4409,46 @@ snapshots: esutils@2.0.3: {} + etag@1.8.1: {} + exit-hook@2.2.1: {} + express@4.19.2: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.2 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.6.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + fast-glob@3.2.7: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4035,6 +4473,18 @@ snapshots: dependencies: to-regex-range: 5.0.1 + finalhandler@1.2.0: + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + flat@5.0.2: {} follow-redirects@1.15.6: {} @@ -4045,6 +4495,10 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 + forwarded@0.2.0: {} + + fresh@0.5.2: {} + front-matter@4.0.2: dependencies: js-yaml: 3.14.1 @@ -4066,6 +4520,14 @@ snapshots: get-caller-file@2.0.5: {} + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + get-source@2.0.12: dependencies: data-uri-to-buffer: 2.0.2 @@ -4079,12 +4541,24 @@ snapshots: globals@11.12.0: {} + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + graceful-fs@4.2.11: {} has-flag@3.0.0: {} has-flag@4.0.0: {} + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -4093,6 +4567,18 @@ snapshots: dependencies: lru-cache: 10.4.3 + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + ieee754@1.2.1: {} ignore@5.3.2: {} @@ -4104,6 +4590,8 @@ snapshots: inherits@2.0.4: {} + ipaddr.js@1.9.1: {} + is-arrayish@0.2.1: {} is-binary-path@2.1.0: @@ -4196,8 +4684,14 @@ snapshots: make-error@1.3.6: {} + media-typer@0.3.0: {} + + merge-descriptors@1.0.1: {} + merge2@1.4.1: {} + methods@1.1.2: {} + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -4209,6 +4703,8 @@ snapshots: dependencies: mime-db: 1.52.0 + mime@1.6.0: {} + mime@3.0.0: {} mimic-fn@2.1.0: {} @@ -4248,14 +4744,20 @@ snapshots: mrmime@2.0.0: {} + ms@2.0.0: {} + ms@2.1.2: {} + ms@2.1.3: {} + multipasta@0.2.5: {} mustache@4.2.0: {} nanoid@3.3.7: {} + negotiator@0.6.3: {} + node-fetch-native@1.6.4: {} node-forge@1.3.1: {} @@ -4330,6 +4832,12 @@ snapshots: transitivePeerDependencies: - debug + object-inspect@1.13.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -4380,10 +4888,14 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parseurl@1.3.3: {} + path-key@3.1.1: {} path-parse@1.0.7: {} + path-to-regexp@0.1.7: {} + path-to-regexp@6.2.2: {} path-type@4.0.0: {} @@ -4408,10 +4920,28 @@ snapshots: proc-log@3.0.0: {} + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + proxy-from-env@1.1.0: {} + qs@6.11.0: + dependencies: + side-channel: 1.0.6 + queue-microtask@1.2.3: {} + range-parser@1.2.1: {} + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + react-is@18.3.1: {} readable-stream@3.6.2: @@ -4488,6 +5018,8 @@ snapshots: safe-buffer@5.2.1: {} + safer-buffer@2.1.2: {} + selfsigned@2.4.1: dependencies: '@types/node-forge': 1.3.11 @@ -4497,6 +5029,51 @@ snapshots: semver@7.6.3: {} + send@0.18.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serve-static@1.15.0: + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + setprototypeof@1.2.0: {} + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + signal-exit@3.0.7: {} source-map-support@0.5.19: @@ -4520,6 +5097,8 @@ snapshots: as-table: 1.0.55 get-source: 2.0.12 + statuses@2.0.1: {} + stoppable@1.1.0: {} streamsearch@1.1.0: {} @@ -4574,6 +5153,8 @@ snapshots: dependencies: is-number: 7.0.0 + toidentifier@1.0.1: {} + ts-node@10.9.1(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(typescript@5.5.4): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -4602,6 +5183,11 @@ snapshots: tslib@2.7.0: {} + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + typescript@5.5.4: {} ufo@1.5.4: {} @@ -4636,6 +5222,8 @@ snapshots: universalify@2.0.1: {} + unpipe@1.0.0: {} + update-browserslist-db@1.1.0(browserslist@4.23.3): dependencies: browserslist: 4.23.3 @@ -4644,10 +5232,14 @@ snapshots: util-deprecate@1.0.2: {} + utils-merge@1.0.1: {} + v8-compile-cache-lib@3.0.1: {} validate-npm-package-name@5.0.1: {} + vary@1.1.2: {} + wcwidth@1.0.1: dependencies: defaults: 1.0.4 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c20da919268..4aeafabc7bc 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,3 +2,4 @@ packages: - packages/* - packages/multipart-parser/bench - packages/multipart-parser/examples/* + - packages/node-request-handler/bench From a28d486b101e46931c4fdeb593355a39f934c0b8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 08:04:16 -0700 Subject: [PATCH 384/730] wip --- packages/node-request-handler/src/lib/node-request-listener.ts | 1 - packages/node-request-handler/tsconfig.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/node-request-handler/src/lib/node-request-listener.ts b/packages/node-request-handler/src/lib/node-request-listener.ts index 9a37811aef4..cdfa7c31dd1 100644 --- a/packages/node-request-handler/src/lib/node-request-listener.ts +++ b/packages/node-request-handler/src/lib/node-request-listener.ts @@ -165,7 +165,6 @@ async function sendResponse(res: http.ServerResponse, response: Response): Promi res.statusCode = response.status; res.statusMessage = response.statusText; - // @ts-ignore - for some reason headers.entries() is not recognized for (let [name, value] of response.headers.entries()) { res.setHeader(name, value); } diff --git a/packages/node-request-handler/tsconfig.json b/packages/node-request-handler/tsconfig.json index d8aaef54f9d..4f02f2c73c9 100644 --- a/packages/node-request-handler/tsconfig.json +++ b/packages/node-request-handler/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "lib": ["DOM", "ES2020"], + "lib": ["DOM", "DOM.Iterable", "ES2020"], "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true From 0d894ad54b8fabdf180200c29e312d65efc03efa Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 10:50:34 -0700 Subject: [PATCH 385/730] Rename node-request-handler => node-fetch-server --- packages/node-fetch-server/CHANGELOG.md | 5 + .../LICENSE | 0 packages/node-fetch-server/README.md | 1 + .../bench/package.json | 4 +- .../bench/servers/express.ts | 0 .../bench/servers/node-fetch-server.ts} | 2 +- .../bench/servers/node-http.ts | 0 .../bench/tsconfig.json | 0 .../package.json | 6 +- .../src/global.d.ts | 0 .../src/lib/request-listener.spec.ts} | 8 +- .../src/lib/request-listener.ts} | 26 +- .../src/lib/request-url.spec.ts | 0 .../src/lib/request-url.ts | 0 .../src/lib/trust-proxy.spec.ts | 0 .../src/lib/trust-proxy.ts | 0 .../src/node-fetch-server.ts | 8 + .../tsconfig.json | 0 .../tsconfig.lib.json | 0 .../tsconfig.spec.json | 0 packages/node-request-handler/CHANGELOG.md | 5 - packages/node-request-handler/README.md | 1 - .../src/lib/request-handler.ts | 20 - .../src/node-request-handler.ts | 4 - pnpm-lock.yaml | 3542 ++++++++++++----- pnpm-workspace.yaml | 2 +- 26 files changed, 2665 insertions(+), 969 deletions(-) create mode 100644 packages/node-fetch-server/CHANGELOG.md rename packages/{node-request-handler => node-fetch-server}/LICENSE (100%) create mode 100644 packages/node-fetch-server/README.md rename packages/{node-request-handler => node-fetch-server}/bench/package.json (62%) rename packages/{node-request-handler => node-fetch-server}/bench/servers/express.ts (100%) rename packages/{node-request-handler/bench/servers/node-request-handler.ts => node-fetch-server/bench/servers/node-fetch-server.ts} (80%) rename packages/{node-request-handler => node-fetch-server}/bench/servers/node-http.ts (100%) rename packages/{node-request-handler => node-fetch-server}/bench/tsconfig.json (100%) rename packages/{node-request-handler => node-fetch-server}/package.json (86%) rename packages/{node-request-handler => node-fetch-server}/src/global.d.ts (100%) rename packages/{node-request-handler/src/lib/node-request-listener.spec.ts => node-fetch-server/src/lib/request-listener.spec.ts} (91%) rename packages/{node-request-handler/src/lib/node-request-listener.ts => node-fetch-server/src/lib/request-listener.ts} (86%) rename packages/{node-request-handler => node-fetch-server}/src/lib/request-url.spec.ts (100%) rename packages/{node-request-handler => node-fetch-server}/src/lib/request-url.ts (100%) rename packages/{node-request-handler => node-fetch-server}/src/lib/trust-proxy.spec.ts (100%) rename packages/{node-request-handler => node-fetch-server}/src/lib/trust-proxy.ts (100%) create mode 100644 packages/node-fetch-server/src/node-fetch-server.ts rename packages/{node-request-handler => node-fetch-server}/tsconfig.json (100%) rename packages/{node-request-handler => node-fetch-server}/tsconfig.lib.json (100%) rename packages/{node-request-handler => node-fetch-server}/tsconfig.spec.json (100%) delete mode 100644 packages/node-request-handler/CHANGELOG.md delete mode 100644 packages/node-request-handler/README.md delete mode 100644 packages/node-request-handler/src/lib/request-handler.ts delete mode 100644 packages/node-request-handler/src/node-request-handler.ts diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md new file mode 100644 index 00000000000..9301b86117e --- /dev/null +++ b/packages/node-fetch-server/CHANGELOG.md @@ -0,0 +1,5 @@ +# node-fetch-server CHANGELOG + +## HEAD + +- Initial release diff --git a/packages/node-request-handler/LICENSE b/packages/node-fetch-server/LICENSE similarity index 100% rename from packages/node-request-handler/LICENSE rename to packages/node-fetch-server/LICENSE diff --git a/packages/node-fetch-server/README.md b/packages/node-fetch-server/README.md new file mode 100644 index 00000000000..30cd3ee760e --- /dev/null +++ b/packages/node-fetch-server/README.md @@ -0,0 +1 @@ +# node-fetch-server diff --git a/packages/node-request-handler/bench/package.json b/packages/node-fetch-server/bench/package.json similarity index 62% rename from packages/node-request-handler/bench/package.json rename to packages/node-fetch-server/bench/package.json index 6ae763c547d..a7db4dfa509 100644 --- a/packages/node-request-handler/bench/package.json +++ b/packages/node-fetch-server/bench/package.json @@ -1,9 +1,9 @@ { - "name": "node-request-handler-bench", + "name": "node-fetch-server-bench", "private": true, "type": "module", "dependencies": { - "@mjackson/node-request-handler": "workspace:*", + "@mjackson/node-fetch-server": "workspace:*", "express": "^4.19.2" }, "devDependencies": { diff --git a/packages/node-request-handler/bench/servers/express.ts b/packages/node-fetch-server/bench/servers/express.ts similarity index 100% rename from packages/node-request-handler/bench/servers/express.ts rename to packages/node-fetch-server/bench/servers/express.ts diff --git a/packages/node-request-handler/bench/servers/node-request-handler.ts b/packages/node-fetch-server/bench/servers/node-fetch-server.ts similarity index 80% rename from packages/node-request-handler/bench/servers/node-request-handler.ts rename to packages/node-fetch-server/bench/servers/node-fetch-server.ts index d8d79972ad1..c3b16e2f428 100644 --- a/packages/node-request-handler/bench/servers/node-request-handler.ts +++ b/packages/node-fetch-server/bench/servers/node-fetch-server.ts @@ -1,5 +1,5 @@ import * as http from 'node:http'; -import { createRequestListener } from '@mjackson/node-request-handler'; +import { createRequestListener } from '@mjackson/node-fetch-server'; let server = http.createServer( createRequestListener(() => { diff --git a/packages/node-request-handler/bench/servers/node-http.ts b/packages/node-fetch-server/bench/servers/node-http.ts similarity index 100% rename from packages/node-request-handler/bench/servers/node-http.ts rename to packages/node-fetch-server/bench/servers/node-http.ts diff --git a/packages/node-request-handler/bench/tsconfig.json b/packages/node-fetch-server/bench/tsconfig.json similarity index 100% rename from packages/node-request-handler/bench/tsconfig.json rename to packages/node-fetch-server/bench/tsconfig.json diff --git a/packages/node-request-handler/package.json b/packages/node-fetch-server/package.json similarity index 86% rename from packages/node-request-handler/package.json rename to packages/node-fetch-server/package.json index e6421e8214e..111402f2c76 100644 --- a/packages/node-request-handler/package.json +++ b/packages/node-fetch-server/package.json @@ -1,12 +1,12 @@ { - "name": "@mjackson/node-request-handler", + "name": "@mjackson/node-fetch-server", "version": "0.1.0", "description": "Build servers for Node.js using the web fetch API", "author": "Michael Jackson ", "repository": { "type": "git", "url": "git+https://github.com/mjackson/remix-the-web.git", - "directory": "packages/node-request-handler" + "directory": "packages/node-fetch-server" }, "license": "MIT", "files": [ @@ -16,7 +16,7 @@ ], "type": "module", "exports": { - ".": "./dist/node-request-handler.js", + ".": "./dist/node-fetch-server.js", "./package.json": "./package.json" }, "dependencies": { diff --git a/packages/node-request-handler/src/global.d.ts b/packages/node-fetch-server/src/global.d.ts similarity index 100% rename from packages/node-request-handler/src/global.d.ts rename to packages/node-fetch-server/src/global.d.ts diff --git a/packages/node-request-handler/src/lib/node-request-listener.spec.ts b/packages/node-fetch-server/src/lib/request-listener.spec.ts similarity index 91% rename from packages/node-request-handler/src/lib/node-request-listener.spec.ts rename to packages/node-fetch-server/src/lib/request-listener.spec.ts index fa51510f0fc..bddd48e6196 100644 --- a/packages/node-request-handler/src/lib/node-request-listener.spec.ts +++ b/packages/node-fetch-server/src/lib/request-listener.spec.ts @@ -4,13 +4,13 @@ import { describe, it, mock } from 'node:test'; import * as http from 'node:http'; import * as stream from 'node:stream'; -import { RequestHandler } from './request-handler.js'; -import { createRequestListener } from './node-request-listener.js'; +import { FetchHandler } from './fetch-handler.js'; +import { createRequestListener } from './request-listener.js'; describe('createRequestListener', () => { it('returns a request listener', async () => { await new Promise((resolve) => { - let handler: RequestHandler = async () => { + let handler: FetchHandler = async () => { return new Response('Hello, world!'); }; @@ -37,7 +37,7 @@ describe('createRequestListener', () => { it('calls onError when an error is thrown in the request handler', async () => { await new Promise((resolve) => { - let handler: RequestHandler = async () => { + let handler: FetchHandler = async () => { throw new Error('boom!'); }; let errorHandler = mock.fn(); diff --git a/packages/node-request-handler/src/lib/node-request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts similarity index 86% rename from packages/node-request-handler/src/lib/node-request-listener.ts rename to packages/node-fetch-server/src/lib/request-listener.ts index cdfa7c31dd1..787b829d851 100644 --- a/packages/node-request-handler/src/lib/node-request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -1,9 +1,29 @@ import * as http from 'node:http'; -import { RequestHandler, ErrorHandler } from './request-handler.js'; import { getRequestUrl } from './request-url.js'; import { TrustArg, createTrustProxy } from './trust-proxy.js'; +/** + * A function that handles an incoming request and returns a response. + * + * [MDN `Request` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Request) + * + * [MDN `Response` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Response) + */ +export interface FetchHandler { + (request: Request): Response | Promise; +} + +/** + * A function that handles an error that occurred during request handling. May return a response to + * send to the client, or `undefined` to allow the server to send a default error response. + * + * [MDN `Response` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Response) + */ +export interface ErrorHandler { + (error: unknown): Response | void | Promise; +} + export interface RequestListenerOptions { /** * An error handler that determines the response when the request handler throws an error. By @@ -51,7 +71,7 @@ export interface RequestListenerOptions { * * ```ts * import * as http from 'node:http'; - * import { RequestHandler, createRequestListener } from '@mjackson/node-request-handler'; + * import { RequestHandler, createRequestListener } from '@mjackson/node-fetch-server'; * * let handler: RequestHandler = async (request) => { * return new Response('Hello, world!'); @@ -65,7 +85,7 @@ export interface RequestListenerOptions { * ``` */ export function createRequestListener( - handler: RequestHandler, + handler: FetchHandler, options?: RequestListenerOptions, ): http.RequestListener { let onError = options?.onError ?? defaultErrorHandler; diff --git a/packages/node-request-handler/src/lib/request-url.spec.ts b/packages/node-fetch-server/src/lib/request-url.spec.ts similarity index 100% rename from packages/node-request-handler/src/lib/request-url.spec.ts rename to packages/node-fetch-server/src/lib/request-url.spec.ts diff --git a/packages/node-request-handler/src/lib/request-url.ts b/packages/node-fetch-server/src/lib/request-url.ts similarity index 100% rename from packages/node-request-handler/src/lib/request-url.ts rename to packages/node-fetch-server/src/lib/request-url.ts diff --git a/packages/node-request-handler/src/lib/trust-proxy.spec.ts b/packages/node-fetch-server/src/lib/trust-proxy.spec.ts similarity index 100% rename from packages/node-request-handler/src/lib/trust-proxy.spec.ts rename to packages/node-fetch-server/src/lib/trust-proxy.spec.ts diff --git a/packages/node-request-handler/src/lib/trust-proxy.ts b/packages/node-fetch-server/src/lib/trust-proxy.ts similarity index 100% rename from packages/node-request-handler/src/lib/trust-proxy.ts rename to packages/node-fetch-server/src/lib/trust-proxy.ts diff --git a/packages/node-fetch-server/src/node-fetch-server.ts b/packages/node-fetch-server/src/node-fetch-server.ts new file mode 100644 index 00000000000..db6fda94b1c --- /dev/null +++ b/packages/node-fetch-server/src/node-fetch-server.ts @@ -0,0 +1,8 @@ +export { + type FetchHandler, + type ErrorHandler, + type RequestListenerOptions, + createRequestListener, +} from './lib/request-listener.js'; +export { getRequestUrl } from './lib/request-url.js'; +export { createTrustProxy } from './lib/trust-proxy.js'; diff --git a/packages/node-request-handler/tsconfig.json b/packages/node-fetch-server/tsconfig.json similarity index 100% rename from packages/node-request-handler/tsconfig.json rename to packages/node-fetch-server/tsconfig.json diff --git a/packages/node-request-handler/tsconfig.lib.json b/packages/node-fetch-server/tsconfig.lib.json similarity index 100% rename from packages/node-request-handler/tsconfig.lib.json rename to packages/node-fetch-server/tsconfig.lib.json diff --git a/packages/node-request-handler/tsconfig.spec.json b/packages/node-fetch-server/tsconfig.spec.json similarity index 100% rename from packages/node-request-handler/tsconfig.spec.json rename to packages/node-fetch-server/tsconfig.spec.json diff --git a/packages/node-request-handler/CHANGELOG.md b/packages/node-request-handler/CHANGELOG.md deleted file mode 100644 index 84b69e114d9..00000000000 --- a/packages/node-request-handler/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -# node-request-handler CHANGELOG - -## HEAD - -- Initial release diff --git a/packages/node-request-handler/README.md b/packages/node-request-handler/README.md deleted file mode 100644 index b63efa59abd..00000000000 --- a/packages/node-request-handler/README.md +++ /dev/null @@ -1 +0,0 @@ -# node-request-handler diff --git a/packages/node-request-handler/src/lib/request-handler.ts b/packages/node-request-handler/src/lib/request-handler.ts deleted file mode 100644 index 6cd04c4721e..00000000000 --- a/packages/node-request-handler/src/lib/request-handler.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * A function that handles an error that occurred during request handling. May return a response to - * send to the client, or `undefined` to allow the server to send a default error response. - * - * [MDN `Response` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Response) - */ -export interface ErrorHandler { - (error: unknown): Response | void | Promise; -} - -/** - * A function that handles an incoming request and returns a response. - * - * [MDN `Request` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Request) - * - * [MDN `Response` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Response) - */ -export interface RequestHandler { - (request: Request): Response | Promise; -} diff --git a/packages/node-request-handler/src/node-request-handler.ts b/packages/node-request-handler/src/node-request-handler.ts deleted file mode 100644 index 153084c24e6..00000000000 --- a/packages/node-request-handler/src/node-request-handler.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { type RequestListenerOptions, createRequestListener } from './lib/node-request-listener.js'; -export { type RequestHandler, type ErrorHandler } from './lib/request-handler.js'; -export { getRequestUrl } from './lib/request-url.js'; -export { createTrustProxy } from './lib/trust-proxy.js'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9b556d49bab..cfb2085c849 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,6 @@ settings: excludeLinksFromLockfile: false importers: - .: devDependencies: '@nx/js': @@ -159,7 +158,7 @@ importers: specifier: ^0.2.6 version: 0.2.6 - packages/node-request-handler: + packages/node-fetch-server: dependencies: proxy-addr: specifier: ^2.0.7 @@ -172,9 +171,9 @@ importers: specifier: ^2.0.3 version: 2.0.3 - packages/node-request-handler/bench: + packages/node-fetch-server/bench: dependencies: - '@mjackson/node-request-handler': + '@mjackson/node-fetch-server': specifier: workspace:* version: link:.. express: @@ -186,897 +185,1412 @@ importers: version: 4.17.21 packages: - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==, + } + engines: { node: '>=6.0.0' } '@babel/code-frame@7.24.7': - resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==, + } + engines: { node: '>=6.9.0' } '@babel/compat-data@7.25.4': - resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==, + } + engines: { node: '>=6.9.0' } '@babel/core@7.25.2': - resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==, + } + engines: { node: '>=6.9.0' } '@babel/generator@7.25.5': - resolution: {integrity: sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==, + } + engines: { node: '>=6.9.0' } '@babel/helper-annotate-as-pure@7.24.7': - resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==, + } + engines: { node: '>=6.9.0' } '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': - resolution: {integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==, + } + engines: { node: '>=6.9.0' } '@babel/helper-compilation-targets@7.25.2': - resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==, + } + engines: { node: '>=6.9.0' } '@babel/helper-create-class-features-plugin@7.25.4': - resolution: {integrity: sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 '@babel/helper-create-regexp-features-plugin@7.25.2': - resolution: {integrity: sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 '@babel/helper-define-polyfill-provider@0.6.2': - resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} + resolution: + { + integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==, + } peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 '@babel/helper-member-expression-to-functions@7.24.8': - resolution: {integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==, + } + engines: { node: '>=6.9.0' } '@babel/helper-module-imports@7.24.7': - resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==, + } + engines: { node: '>=6.9.0' } '@babel/helper-module-transforms@7.25.2': - resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 '@babel/helper-optimise-call-expression@7.24.7': - resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==, + } + engines: { node: '>=6.9.0' } '@babel/helper-plugin-utils@7.24.8': - resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==, + } + engines: { node: '>=6.9.0' } '@babel/helper-remap-async-to-generator@7.25.0': - resolution: {integrity: sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 '@babel/helper-replace-supers@7.25.0': - resolution: {integrity: sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 '@babel/helper-simple-access@7.24.7': - resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==, + } + engines: { node: '>=6.9.0' } '@babel/helper-skip-transparent-expression-wrappers@7.24.7': - resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==, + } + engines: { node: '>=6.9.0' } '@babel/helper-string-parser@7.24.8': - resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==, + } + engines: { node: '>=6.9.0' } '@babel/helper-validator-identifier@7.24.7': - resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==, + } + engines: { node: '>=6.9.0' } '@babel/helper-validator-option@7.24.8': - resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==, + } + engines: { node: '>=6.9.0' } '@babel/helper-wrap-function@7.25.0': - resolution: {integrity: sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==, + } + engines: { node: '>=6.9.0' } '@babel/helpers@7.25.0': - resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==, + } + engines: { node: '>=6.9.0' } '@babel/highlight@7.24.7': - resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==, + } + engines: { node: '>=6.9.0' } '@babel/parser@7.25.4': - resolution: {integrity: sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==, + } + engines: { node: '>=6.0.0' } hasBin: true '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.3': - resolution: {integrity: sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.0': - resolution: {integrity: sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.0': - resolution: {integrity: sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7': - resolution: {integrity: sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.13.0 '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.0': - resolution: {integrity: sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 '@babel/plugin-proposal-decorators@7.24.7': - resolution: {integrity: sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': - resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-async-generators@7.8.4': - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + resolution: + { + integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-class-properties@7.12.13': - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + resolution: + { + integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-class-static-block@7.14.5': - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-decorators@7.24.7': - resolution: {integrity: sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-dynamic-import@7.8.3': - resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + resolution: + { + integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-export-namespace-from@7.8.3': - resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + resolution: + { + integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-import-assertions@7.24.7': - resolution: {integrity: sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-import-attributes@7.24.7': - resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-import-meta@7.10.4': - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + resolution: + { + integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-json-strings@7.8.3': - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + resolution: + { + integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-jsx@7.24.7': - resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-logical-assignment-operators@7.10.4': - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + resolution: + { + integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + resolution: + { + integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-numeric-separator@7.10.4': - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + resolution: + { + integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-object-rest-spread@7.8.3': - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + resolution: + { + integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-optional-catch-binding@7.8.3': - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + resolution: + { + integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-optional-chaining@7.8.3': - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + resolution: + { + integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-private-property-in-object@7.14.5': - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-top-level-await@7.14.5': - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-typescript@7.25.4': - resolution: {integrity: sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-unicode-sets-regex@7.18.6': - resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 '@babel/plugin-transform-arrow-functions@7.24.7': - resolution: {integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-async-generator-functions@7.25.4': - resolution: {integrity: sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-async-to-generator@7.24.7': - resolution: {integrity: sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-block-scoped-functions@7.24.7': - resolution: {integrity: sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-block-scoping@7.25.0': - resolution: {integrity: sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-class-properties@7.25.4': - resolution: {integrity: sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-class-static-block@7.24.7': - resolution: {integrity: sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.12.0 '@babel/plugin-transform-classes@7.25.4': - resolution: {integrity: sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-computed-properties@7.24.7': - resolution: {integrity: sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-destructuring@7.24.8': - resolution: {integrity: sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-dotall-regex@7.24.7': - resolution: {integrity: sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-duplicate-keys@7.24.7': - resolution: {integrity: sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.0': - resolution: {integrity: sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 '@babel/plugin-transform-dynamic-import@7.24.7': - resolution: {integrity: sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-exponentiation-operator@7.24.7': - resolution: {integrity: sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-export-namespace-from@7.24.7': - resolution: {integrity: sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-for-of@7.24.7': - resolution: {integrity: sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-function-name@7.25.1': - resolution: {integrity: sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-json-strings@7.24.7': - resolution: {integrity: sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-literals@7.25.2': - resolution: {integrity: sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-logical-assignment-operators@7.24.7': - resolution: {integrity: sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-member-expression-literals@7.24.7': - resolution: {integrity: sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-modules-amd@7.24.7': - resolution: {integrity: sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-modules-commonjs@7.24.8': - resolution: {integrity: sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-modules-systemjs@7.25.0': - resolution: {integrity: sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-modules-umd@7.24.7': - resolution: {integrity: sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-named-capturing-groups-regex@7.24.7': - resolution: {integrity: sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 '@babel/plugin-transform-new-target@7.24.7': - resolution: {integrity: sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-nullish-coalescing-operator@7.24.7': - resolution: {integrity: sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-numeric-separator@7.24.7': - resolution: {integrity: sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-object-rest-spread@7.24.7': - resolution: {integrity: sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-object-super@7.24.7': - resolution: {integrity: sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-optional-catch-binding@7.24.7': - resolution: {integrity: sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-optional-chaining@7.24.8': - resolution: {integrity: sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-parameters@7.24.7': - resolution: {integrity: sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-private-methods@7.25.4': - resolution: {integrity: sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-private-property-in-object@7.24.7': - resolution: {integrity: sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-property-literals@7.24.7': - resolution: {integrity: sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-regenerator@7.24.7': - resolution: {integrity: sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-reserved-words@7.24.7': - resolution: {integrity: sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-runtime@7.25.4': - resolution: {integrity: sha512-8hsyG+KUYGY0coX6KUCDancA0Vw225KJ2HJO0yCNr1vq5r+lJTleDaJf0K7iOhjw4SWhu03TMBzYTJ9krmzULQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-8hsyG+KUYGY0coX6KUCDancA0Vw225KJ2HJO0yCNr1vq5r+lJTleDaJf0K7iOhjw4SWhu03TMBzYTJ9krmzULQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-shorthand-properties@7.24.7': - resolution: {integrity: sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-spread@7.24.7': - resolution: {integrity: sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-sticky-regex@7.24.7': - resolution: {integrity: sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-template-literals@7.24.7': - resolution: {integrity: sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-typeof-symbol@7.24.8': - resolution: {integrity: sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-typescript@7.25.2': - resolution: {integrity: sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-unicode-escapes@7.24.7': - resolution: {integrity: sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-unicode-property-regex@7.24.7': - resolution: {integrity: sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-unicode-regex@7.24.7': - resolution: {integrity: sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-unicode-sets-regex@7.25.4': - resolution: {integrity: sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 '@babel/preset-env@7.25.4': - resolution: {integrity: sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/preset-modules@0.1.6-no-external-plugins': - resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + resolution: + { + integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==, + } peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 '@babel/preset-typescript@7.24.7': - resolution: {integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/regjsgen@0.8.0': - resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} + resolution: + { + integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==, + } '@babel/runtime@7.25.4': - resolution: {integrity: sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==, + } + engines: { node: '>=6.9.0' } '@babel/template@7.25.0': - resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==, + } + engines: { node: '>=6.9.0' } '@babel/traverse@7.25.4': - resolution: {integrity: sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==, + } + engines: { node: '>=6.9.0' } '@babel/types@7.25.4': - resolution: {integrity: sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==, + } + engines: { node: '>=6.9.0' } '@cloudflare/kv-asset-handler@0.3.4': - resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} - engines: {node: '>=16.13'} + resolution: + { + integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==, + } + engines: { node: '>=16.13' } '@cloudflare/workerd-darwin-64@1.20240821.1': - resolution: {integrity: sha512-CDBpfZKrSy4YrIdqS84z67r3Tzal2pOhjCsIb63IuCnvVes59/ft1qhczBzk9EffeOE2iTCrA4YBT7Sbn7USew==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-CDBpfZKrSy4YrIdqS84z67r3Tzal2pOhjCsIb63IuCnvVes59/ft1qhczBzk9EffeOE2iTCrA4YBT7Sbn7USew==, + } + engines: { node: '>=16' } cpu: [x64] os: [darwin] '@cloudflare/workerd-darwin-arm64@1.20240821.1': - resolution: {integrity: sha512-Q+9RedvNbPcEt/dKni1oN94OxbvuNAeJkgHmrLFTGF8zu21wzOhVkQeRNxcYxrMa9mfStc457NAg13OVCj2kHQ==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-Q+9RedvNbPcEt/dKni1oN94OxbvuNAeJkgHmrLFTGF8zu21wzOhVkQeRNxcYxrMa9mfStc457NAg13OVCj2kHQ==, + } + engines: { node: '>=16' } cpu: [arm64] os: [darwin] '@cloudflare/workerd-linux-64@1.20240821.1': - resolution: {integrity: sha512-j6z3KsPtawrscoLuP985LbqFrmsJL6q1mvSXOXTqXGODAHIzGBipHARdOjms3UQqovzvqB2lQaQsZtLBwCZxtA==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-j6z3KsPtawrscoLuP985LbqFrmsJL6q1mvSXOXTqXGODAHIzGBipHARdOjms3UQqovzvqB2lQaQsZtLBwCZxtA==, + } + engines: { node: '>=16' } cpu: [x64] os: [linux] '@cloudflare/workerd-linux-arm64@1.20240821.1': - resolution: {integrity: sha512-I9bHgZOxJQW0CV5gTdilyxzTG7ILzbTirehQWgfPx9X77E/7eIbR9sboOMgyeC69W4he0SKtpx0sYZuTJu4ERw==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-I9bHgZOxJQW0CV5gTdilyxzTG7ILzbTirehQWgfPx9X77E/7eIbR9sboOMgyeC69W4he0SKtpx0sYZuTJu4ERw==, + } + engines: { node: '>=16' } cpu: [arm64] os: [linux] '@cloudflare/workerd-windows-64@1.20240821.1': - resolution: {integrity: sha512-keC97QPArs6LWbPejQM7/Y8Jy8QqyaZow4/ZdsGo+QjlOLiZRDpAenfZx3CBUoWwEeFwQTl2FLO+8hV1SWFFYw==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-keC97QPArs6LWbPejQM7/Y8Jy8QqyaZow4/ZdsGo+QjlOLiZRDpAenfZx3CBUoWwEeFwQTl2FLO+8hV1SWFFYw==, + } + engines: { node: '>=16' } cpu: [x64] os: [win32] '@cloudflare/workers-shared@0.4.0': - resolution: {integrity: sha512-XAFOldVQsbxQ7mjbqX2q1dNIgcLbKSytk41pwuZTn9e0p7OeTpFTosJef8uwosL6CcOAHqcW1f1HJxyjwmtGxw==} - engines: {node: '>=16.7.0'} + resolution: + { + integrity: sha512-XAFOldVQsbxQ7mjbqX2q1dNIgcLbKSytk41pwuZTn9e0p7OeTpFTosJef8uwosL6CcOAHqcW1f1HJxyjwmtGxw==, + } + engines: { node: '>=16.7.0' } '@cloudflare/workers-types@4.20240821.1': - resolution: {integrity: sha512-icAkbnAqgVl6ef9lgLTom8na+kj2RBw2ViPAQ586hbdj0xZcnrjK7P46Eu08OU9D/lNDgN2sKU/sxhe2iK/gIg==} + resolution: + { + integrity: sha512-icAkbnAqgVl6ef9lgLTom8na+kj2RBw2ViPAQ586hbdj0xZcnrjK7P46Eu08OU9D/lNDgN2sKU/sxhe2iK/gIg==, + } '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, + } + engines: { node: '>=12' } '@emnapi/core@1.2.0': - resolution: {integrity: sha512-E7Vgw78I93we4ZWdYCb4DGAwRROGkMIXk7/y87UmANR+J6qsWusmC3gLt0H+O0KOt5e6O38U8oJamgbudrES/w==} + resolution: + { + integrity: sha512-E7Vgw78I93we4ZWdYCb4DGAwRROGkMIXk7/y87UmANR+J6qsWusmC3gLt0H+O0KOt5e6O38U8oJamgbudrES/w==, + } '@emnapi/runtime@1.2.0': - resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==} + resolution: + { + integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==, + } '@emnapi/wasi-threads@1.0.1': - resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} + resolution: + { + integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==, + } '@esbuild-plugins/node-globals-polyfill@0.2.3': - resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} + resolution: + { + integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==, + } peerDependencies: esbuild: '*' '@esbuild-plugins/node-modules-polyfill@0.2.2': - resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} + resolution: + { + integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==, + } peerDependencies: esbuild: '*' '@esbuild/android-arm64@0.17.19': - resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==, + } + engines: { node: '>=12' } cpu: [arm64] os: [android] '@esbuild/android-arm@0.17.19': - resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==, + } + engines: { node: '>=12' } cpu: [arm] os: [android] '@esbuild/android-x64@0.17.19': - resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==, + } + engines: { node: '>=12' } cpu: [x64] os: [android] '@esbuild/darwin-arm64@0.17.19': - resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==, + } + engines: { node: '>=12' } cpu: [arm64] os: [darwin] '@esbuild/darwin-x64@0.17.19': - resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==, + } + engines: { node: '>=12' } cpu: [x64] os: [darwin] '@esbuild/freebsd-arm64@0.17.19': - resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==, + } + engines: { node: '>=12' } cpu: [arm64] os: [freebsd] '@esbuild/freebsd-x64@0.17.19': - resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==, + } + engines: { node: '>=12' } cpu: [x64] os: [freebsd] '@esbuild/linux-arm64@0.17.19': - resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==, + } + engines: { node: '>=12' } cpu: [arm64] os: [linux] '@esbuild/linux-arm@0.17.19': - resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==, + } + engines: { node: '>=12' } cpu: [arm] os: [linux] '@esbuild/linux-ia32@0.17.19': - resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==, + } + engines: { node: '>=12' } cpu: [ia32] os: [linux] '@esbuild/linux-loong64@0.17.19': - resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==, + } + engines: { node: '>=12' } cpu: [loong64] os: [linux] '@esbuild/linux-mips64el@0.17.19': - resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==, + } + engines: { node: '>=12' } cpu: [mips64el] os: [linux] '@esbuild/linux-ppc64@0.17.19': - resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==, + } + engines: { node: '>=12' } cpu: [ppc64] os: [linux] '@esbuild/linux-riscv64@0.17.19': - resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==, + } + engines: { node: '>=12' } cpu: [riscv64] os: [linux] '@esbuild/linux-s390x@0.17.19': - resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==, + } + engines: { node: '>=12' } cpu: [s390x] os: [linux] '@esbuild/linux-x64@0.17.19': - resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==, + } + engines: { node: '>=12' } cpu: [x64] os: [linux] '@esbuild/netbsd-x64@0.17.19': - resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==, + } + engines: { node: '>=12' } cpu: [x64] os: [netbsd] '@esbuild/openbsd-x64@0.17.19': - resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==, + } + engines: { node: '>=12' } cpu: [x64] os: [openbsd] '@esbuild/sunos-x64@0.17.19': - resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==, + } + engines: { node: '>=12' } cpu: [x64] os: [sunos] '@esbuild/win32-arm64@0.17.19': - resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==, + } + engines: { node: '>=12' } cpu: [arm64] os: [win32] '@esbuild/win32-ia32@0.17.19': - resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==, + } + engines: { node: '>=12' } cpu: [ia32] os: [win32] '@esbuild/win32-x64@0.17.19': - resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==, + } + engines: { node: '>=12' } cpu: [x64] os: [win32] '@fastify/busboy@2.1.1': - resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==, + } + engines: { node: '>=14' } '@fastify/busboy@3.0.0': - resolution: {integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==} + resolution: + { + integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==, + } '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==, + } + engines: { node: '>=6.0.0' } '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, + } + engines: { node: '>=6.0.0' } '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==, + } + engines: { node: '>=6.0.0' } '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + resolution: + { + integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==, + } '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + resolution: + { + integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==, + } '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + resolution: + { + integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==, + } '@mjackson/headers@0.5.1': - resolution: {integrity: sha512-sJpFgecPT/zJvwk3GRNVWNs8EkwaJoUNU2D0VMlp+gDJs6cuSTm1q/aCZi3ZtuV6CgDEQ4l2ZjUG3A9JrQlbNA==} + resolution: + { + integrity: sha512-sJpFgecPT/zJvwk3GRNVWNs8EkwaJoUNU2D0VMlp+gDJs6cuSTm1q/aCZi3ZtuV6CgDEQ4l2ZjUG3A9JrQlbNA==, + } '@mjackson/lazy-file@2.2.0': - resolution: {integrity: sha512-51M2TAL5eMZj5mh1e22/qBl4C5udViZqSBEqwiHSi1lTAixCp4YiAOV62VaTSqVp771OkmgNCPsh8/LpJ/A/Yw==} + resolution: + { + integrity: sha512-51M2TAL5eMZj5mh1e22/qBl4C5udViZqSBEqwiHSi1lTAixCp4YiAOV62VaTSqVp771OkmgNCPsh8/LpJ/A/Yw==, + } '@mjackson/multipart-parser@0.6.2': - resolution: {integrity: sha512-xG3mINK6gFVposxu83x3n4ueJfjWoxOl3UaBADXNjh/NL84L+Zc/kmz2mTQA9GHvHFPAMlXqPSLTocIDkmhemQ==} + resolution: + { + integrity: sha512-xG3mINK6gFVposxu83x3n4ueJfjWoxOl3UaBADXNjh/NL84L+Zc/kmz2mTQA9GHvHFPAMlXqPSLTocIDkmhemQ==, + } '@napi-rs/wasm-runtime@0.2.4': - resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} + resolution: + { + integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==, + } '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, + } + engines: { node: '>= 8' } '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, + } + engines: { node: '>= 8' } '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, + } + engines: { node: '>= 8' } '@nrwl/devkit@19.6.4': - resolution: {integrity: sha512-jpr+T5/+21W/fwAMB6zDLZKO+ReYAfOOMIeM8CpeBi/r9nWmjGXaXN9YKwEOYS1fath62Y5ldGK4yZUttv1tkw==} + resolution: + { + integrity: sha512-jpr+T5/+21W/fwAMB6zDLZKO+ReYAfOOMIeM8CpeBi/r9nWmjGXaXN9YKwEOYS1fath62Y5ldGK4yZUttv1tkw==, + } '@nrwl/js@19.6.4': - resolution: {integrity: sha512-yjxxSRST/lWylw4SO1qILg9oiKlBbcVst1nVFZzneTFo2oNuFVSEhluVh5tZ0bz3GZ1RPtHxjiBuWDwQ/QmmAA==} + resolution: + { + integrity: sha512-yjxxSRST/lWylw4SO1qILg9oiKlBbcVst1nVFZzneTFo2oNuFVSEhluVh5tZ0bz3GZ1RPtHxjiBuWDwQ/QmmAA==, + } '@nrwl/tao@19.6.4': - resolution: {integrity: sha512-1J8cD+MFzsmboiGe03VlQZ8gt64k/TaYYPZivnnhOJolPPs75nz1JyJX55uWcKKRy/b7FZNKWIu/6Wp9JDhJrQ==} + resolution: + { + integrity: sha512-1J8cD+MFzsmboiGe03VlQZ8gt64k/TaYYPZivnnhOJolPPs75nz1JyJX55uWcKKRy/b7FZNKWIu/6Wp9JDhJrQ==, + } hasBin: true '@nrwl/workspace@19.6.4': - resolution: {integrity: sha512-jjqtRjm5AP39s8oPUEehA6O0Zew6BeTi+Uhjb+ggqbFKH9R9hoSITnbJY670WlO4W8yWYxT8isPf1TNdSHkmBw==} + resolution: + { + integrity: sha512-jjqtRjm5AP39s8oPUEehA6O0Zew6BeTi+Uhjb+ggqbFKH9R9hoSITnbJY670WlO4W8yWYxT8isPf1TNdSHkmBw==, + } '@nx/devkit@19.6.4': - resolution: {integrity: sha512-mBitFwb/gcz8MR7STt7KQG0vf+QcsasDXiSYcf3OWpc6lGE5wn1q5jg6Iabp49Bd/mdHXVLQnP1aV5A+QqFIOQ==} + resolution: + { + integrity: sha512-mBitFwb/gcz8MR7STt7KQG0vf+QcsasDXiSYcf3OWpc6lGE5wn1q5jg6Iabp49Bd/mdHXVLQnP1aV5A+QqFIOQ==, + } peerDependencies: nx: '>= 17 <= 20' '@nx/js@19.6.4': - resolution: {integrity: sha512-Z09whMis90on3/5V0RIG1On5bRlNI4q2SGZQmj530+BqRTNdKNqxuYdpGf3oNbw5cgLVGiHcWtHzZROaAzpc4g==} + resolution: + { + integrity: sha512-Z09whMis90on3/5V0RIG1On5bRlNI4q2SGZQmj530+BqRTNdKNqxuYdpGf3oNbw5cgLVGiHcWtHzZROaAzpc4g==, + } peerDependencies: verdaccio: ^5.0.4 peerDependenciesMeta: @@ -1084,205 +1598,316 @@ packages: optional: true '@nx/nx-darwin-arm64@19.6.4': - resolution: {integrity: sha512-kRn2FLvhwJA/TJrNlsCSqqQTrguNZLmiRsiXhvjkfUMbUKwyQfVMgJlvkZ+KoqraUSG+Qyb0FmrGur1I/Mld0Q==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-kRn2FLvhwJA/TJrNlsCSqqQTrguNZLmiRsiXhvjkfUMbUKwyQfVMgJlvkZ+KoqraUSG+Qyb0FmrGur1I/Mld0Q==, + } + engines: { node: '>= 10' } cpu: [arm64] os: [darwin] '@nx/nx-darwin-x64@19.6.4': - resolution: {integrity: sha512-3uABBUhxVk+SdRwpUu30iuBlgRWm3tA/G9seG+wt7oN2R+fOu8zzRCYa+Blvoh1Ef+D9743Ir4rDc9Mhzl2B2g==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-3uABBUhxVk+SdRwpUu30iuBlgRWm3tA/G9seG+wt7oN2R+fOu8zzRCYa+Blvoh1Ef+D9743Ir4rDc9Mhzl2B2g==, + } + engines: { node: '>= 10' } cpu: [x64] os: [darwin] '@nx/nx-freebsd-x64@19.6.4': - resolution: {integrity: sha512-OG83MiEk5L54/vAldmwZJBKEvZaM+DEIDqn2yZLTToBRj5Z9jwKJX3jKP60xbHiaT/hzsb1xPlwhOHJnYd80EQ==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-OG83MiEk5L54/vAldmwZJBKEvZaM+DEIDqn2yZLTToBRj5Z9jwKJX3jKP60xbHiaT/hzsb1xPlwhOHJnYd80EQ==, + } + engines: { node: '>= 10' } cpu: [x64] os: [freebsd] '@nx/nx-linux-arm-gnueabihf@19.6.4': - resolution: {integrity: sha512-hQ9x4qSKUh9mIVDuD270ULrBnmYfDTjXq7LnIwECw1AuP4LkKzKxULhsbqVnFQ/k3xxyFkwyGTIu2mfDcw16Gw==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-hQ9x4qSKUh9mIVDuD270ULrBnmYfDTjXq7LnIwECw1AuP4LkKzKxULhsbqVnFQ/k3xxyFkwyGTIu2mfDcw16Gw==, + } + engines: { node: '>= 10' } cpu: [arm] os: [linux] '@nx/nx-linux-arm64-gnu@19.6.4': - resolution: {integrity: sha512-OFKpAHiaVg3YGFIMBmi/JshciP9buwtOPiHDXcQdzQgE22jyYzKEiFxfcpG0nCT8PlMYAbHPAda15WfWkfVGVQ==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-OFKpAHiaVg3YGFIMBmi/JshciP9buwtOPiHDXcQdzQgE22jyYzKEiFxfcpG0nCT8PlMYAbHPAda15WfWkfVGVQ==, + } + engines: { node: '>= 10' } cpu: [arm64] os: [linux] '@nx/nx-linux-arm64-musl@19.6.4': - resolution: {integrity: sha512-ZIR9u+mN0A7SmNd6vDxmPV1QVTgYPTdfBSM5TEnKl3q2fHw2Nkui81QBxA4d7VopJoJUz/pRHiUV+dlgEEZ6nA==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-ZIR9u+mN0A7SmNd6vDxmPV1QVTgYPTdfBSM5TEnKl3q2fHw2Nkui81QBxA4d7VopJoJUz/pRHiUV+dlgEEZ6nA==, + } + engines: { node: '>= 10' } cpu: [arm64] os: [linux] '@nx/nx-linux-x64-gnu@19.6.4': - resolution: {integrity: sha512-AUMPvLs9KeCUuWD5DdlpbP3VfVsiD0IlptS2b3ul336rsQ7LwwdvE7jTVO5CixFOsiRZxP72fKJhaEargMn5Aw==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-AUMPvLs9KeCUuWD5DdlpbP3VfVsiD0IlptS2b3ul336rsQ7LwwdvE7jTVO5CixFOsiRZxP72fKJhaEargMn5Aw==, + } + engines: { node: '>= 10' } cpu: [x64] os: [linux] '@nx/nx-linux-x64-musl@19.6.4': - resolution: {integrity: sha512-PU7AaBlrgnJnDxTiV/PNCu0pHUCzaogm6uNcbzCyFJLGn7DoQK9rkqUMPJjb3CnJkAj9XrrhuZwmOdbrhvHAvA==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-PU7AaBlrgnJnDxTiV/PNCu0pHUCzaogm6uNcbzCyFJLGn7DoQK9rkqUMPJjb3CnJkAj9XrrhuZwmOdbrhvHAvA==, + } + engines: { node: '>= 10' } cpu: [x64] os: [linux] '@nx/nx-win32-arm64-msvc@19.6.4': - resolution: {integrity: sha512-6CCmGWwH/J2k+Uxeci48w4QVhtcQ3hRZ5Z2jh26HI8YzH4wqZyA7QPgLBE6sNCPVLoGW5cBgTsfnyEdr+xarQA==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-6CCmGWwH/J2k+Uxeci48w4QVhtcQ3hRZ5Z2jh26HI8YzH4wqZyA7QPgLBE6sNCPVLoGW5cBgTsfnyEdr+xarQA==, + } + engines: { node: '>= 10' } cpu: [arm64] os: [win32] '@nx/nx-win32-x64-msvc@19.6.4': - resolution: {integrity: sha512-jTNrlaFaKtbL2mYOcfPAiljtpF5CI7vbHIqYqBFYLUQXOwW9lOHlO+SeQnft6JYZs0FIr1IdHaCfdOw/hpnCiQ==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-jTNrlaFaKtbL2mYOcfPAiljtpF5CI7vbHIqYqBFYLUQXOwW9lOHlO+SeQnft6JYZs0FIr1IdHaCfdOw/hpnCiQ==, + } + engines: { node: '>= 10' } cpu: [x64] os: [win32] '@nx/workspace@19.6.4': - resolution: {integrity: sha512-SMrI03OmjYm93XpDTlIWgAyIaEhToN4LNu4cxOXW9ygpzPe8HJlqR18aTaCqu1T+BY8XeaZ8BQ7qYS1kEjM9YA==} + resolution: + { + integrity: sha512-SMrI03OmjYm93XpDTlIWgAyIaEhToN4LNu4cxOXW9ygpzPe8HJlqR18aTaCqu1T+BY8XeaZ8BQ7qYS1kEjM9YA==, + } '@oxc-resolver/binding-darwin-arm64@1.11.0': - resolution: {integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==} + resolution: + { + integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==, + } cpu: [arm64] os: [darwin] '@oxc-resolver/binding-darwin-x64@1.11.0': - resolution: {integrity: sha512-w/svTRKnuRinojYAVsWRozVoPar7XUPlJhpfnsYlReRjls6A53/ziTzHfpmcKjdBrP/AXPcDVJDnM4pOSsvWvA==} + resolution: + { + integrity: sha512-w/svTRKnuRinojYAVsWRozVoPar7XUPlJhpfnsYlReRjls6A53/ziTzHfpmcKjdBrP/AXPcDVJDnM4pOSsvWvA==, + } cpu: [x64] os: [darwin] '@oxc-resolver/binding-freebsd-x64@1.11.0': - resolution: {integrity: sha512-thGp8g8maYUx7vYJqD0vSsuUO95vWNJwKS2AXchq212J5dQ0Dybq4gjt2O2N9iU+lxj1QzmIDXGw7q5HCagOiw==} + resolution: + { + integrity: sha512-thGp8g8maYUx7vYJqD0vSsuUO95vWNJwKS2AXchq212J5dQ0Dybq4gjt2O2N9iU+lxj1QzmIDXGw7q5HCagOiw==, + } cpu: [x64] os: [freebsd] '@oxc-resolver/binding-linux-arm-gnueabihf@1.11.0': - resolution: {integrity: sha512-8G99bs4cnwpJRjRK2cEJXiJVyLogzPJq4JgLlcMEKSGhdkoMV1Ia0dghLk9lAFog33U4lWIwKmPgqQzTO6JM8g==} + resolution: + { + integrity: sha512-8G99bs4cnwpJRjRK2cEJXiJVyLogzPJq4JgLlcMEKSGhdkoMV1Ia0dghLk9lAFog33U4lWIwKmPgqQzTO6JM8g==, + } cpu: [arm] os: [linux] '@oxc-resolver/binding-linux-arm64-gnu@1.11.0': - resolution: {integrity: sha512-hNcB/wbuCFbsspg4h9+Nz5gSL8PbRW7zG/eVvmEpzGhmVubzDFuNmlYtmaUaZ6b9jzOrrqTkYCt9t7Q2TDHnBA==} + resolution: + { + integrity: sha512-hNcB/wbuCFbsspg4h9+Nz5gSL8PbRW7zG/eVvmEpzGhmVubzDFuNmlYtmaUaZ6b9jzOrrqTkYCt9t7Q2TDHnBA==, + } cpu: [arm64] os: [linux] '@oxc-resolver/binding-linux-arm64-musl@1.11.0': - resolution: {integrity: sha512-H9rjqCcNQT9aip1VLrtsiyj9So0DEKUoutMNu1oL9UuD3H5lWIaxhDlHTAFsobWeUHCnuaCbizhGb9wyLRHSuA==} + resolution: + { + integrity: sha512-H9rjqCcNQT9aip1VLrtsiyj9So0DEKUoutMNu1oL9UuD3H5lWIaxhDlHTAFsobWeUHCnuaCbizhGb9wyLRHSuA==, + } cpu: [arm64] os: [linux] '@oxc-resolver/binding-linux-x64-gnu@1.11.0': - resolution: {integrity: sha512-6hdv/kmaGysK3/hUaGTYG07yX+nvk6hGoWombmOuc0vBnGLRtSjqvvgDBdAs9/iIcOSQI2YNUEiJvTyy6eb5GA==} + resolution: + { + integrity: sha512-6hdv/kmaGysK3/hUaGTYG07yX+nvk6hGoWombmOuc0vBnGLRtSjqvvgDBdAs9/iIcOSQI2YNUEiJvTyy6eb5GA==, + } cpu: [x64] os: [linux] '@oxc-resolver/binding-linux-x64-musl@1.11.0': - resolution: {integrity: sha512-AYUvI4VwQkBq0rcYI3Z7a9+BpllbllbxQCD30ZRgHghvqXvDECWfP8r98iynz7u0oKGO8ZPf15d/l9VrkRtiuQ==} + resolution: + { + integrity: sha512-AYUvI4VwQkBq0rcYI3Z7a9+BpllbllbxQCD30ZRgHghvqXvDECWfP8r98iynz7u0oKGO8ZPf15d/l9VrkRtiuQ==, + } cpu: [x64] os: [linux] '@oxc-resolver/binding-wasm32-wasi@1.11.0': - resolution: {integrity: sha512-vhXnOs34q8p7QhqQ04bIGy7ZzLEHBaBTsqh2wpAzSBCmjL7MmTpM8KWwXFPFB+Wj0P7/parjGDHzbZG20pEePg==} - engines: {node: '>=14.0.0'} + resolution: + { + integrity: sha512-vhXnOs34q8p7QhqQ04bIGy7ZzLEHBaBTsqh2wpAzSBCmjL7MmTpM8KWwXFPFB+Wj0P7/parjGDHzbZG20pEePg==, + } + engines: { node: '>=14.0.0' } cpu: [wasm32] '@oxc-resolver/binding-win32-arm64-msvc@1.11.0': - resolution: {integrity: sha512-5XMm8EELDkAVQoMGv4QKqi+SjWnhcU1aq5B9q59iqiXIBNAs72f0d3LAldLrqE2XomP2QweorpsoxuGuIk2Cnw==} + resolution: + { + integrity: sha512-5XMm8EELDkAVQoMGv4QKqi+SjWnhcU1aq5B9q59iqiXIBNAs72f0d3LAldLrqE2XomP2QweorpsoxuGuIk2Cnw==, + } cpu: [arm64] os: [win32] '@oxc-resolver/binding-win32-x64-msvc@1.11.0': - resolution: {integrity: sha512-rVKiZSTgao4SBWyqWvStxDhKmwbKEN/E8+H3CJzIP4FcsL7MQtWH2HT86bmoefkyRe1yO+m2/mG7j3TfADh/Fg==} + resolution: + { + integrity: sha512-rVKiZSTgao4SBWyqWvStxDhKmwbKEN/E8+H3CJzIP4FcsL7MQtWH2HT86bmoefkyRe1yO+m2/mG7j3TfADh/Fg==, + } cpu: [x64] os: [win32] '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + resolution: + { + integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==, + } '@swc-node/core@1.13.3': - resolution: {integrity: sha512-OGsvXIid2Go21kiNqeTIn79jcaX4l0G93X2rAnas4LFoDyA9wAwVK7xZdm+QsKoMn5Mus2yFLCc4OtX2dD/PWA==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-OGsvXIid2Go21kiNqeTIn79jcaX4l0G93X2rAnas4LFoDyA9wAwVK7xZdm+QsKoMn5Mus2yFLCc4OtX2dD/PWA==, + } + engines: { node: '>= 10' } peerDependencies: '@swc/core': '>= 1.4.13' '@swc/types': '>= 0.1' '@swc-node/register@1.10.9': - resolution: {integrity: sha512-iXy2sjP0phPEpK2yivjRC3PAgoLaT4sjSk0LDWCTdcTBJmR4waEog0E6eJbvoOkLkOtWw37SB8vCkl/bbh4+8A==} + resolution: + { + integrity: sha512-iXy2sjP0phPEpK2yivjRC3PAgoLaT4sjSk0LDWCTdcTBJmR4waEog0E6eJbvoOkLkOtWw37SB8vCkl/bbh4+8A==, + } peerDependencies: '@swc/core': '>= 1.4.13' typescript: '>= 4.3' '@swc-node/sourcemap-support@0.5.1': - resolution: {integrity: sha512-JxIvIo/Hrpv0JCHSyRpetAdQ6lB27oFYhv0PKCNf1g2gUXOjpeR1exrXccRxLMuAV5WAmGFBwRnNOJqN38+qtg==} + resolution: + { + integrity: sha512-JxIvIo/Hrpv0JCHSyRpetAdQ6lB27oFYhv0PKCNf1g2gUXOjpeR1exrXccRxLMuAV5WAmGFBwRnNOJqN38+qtg==, + } '@swc/core-darwin-arm64@1.5.29': - resolution: {integrity: sha512-6F/sSxpHaq3nzg2ADv9FHLi4Fu2A8w8vP8Ich8gIl16D2htStlwnaPmCLjRswO+cFkzgVqy/l01gzNGWd4DFqA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-6F/sSxpHaq3nzg2ADv9FHLi4Fu2A8w8vP8Ich8gIl16D2htStlwnaPmCLjRswO+cFkzgVqy/l01gzNGWd4DFqA==, + } + engines: { node: '>=10' } cpu: [arm64] os: [darwin] '@swc/core-darwin-x64@1.5.29': - resolution: {integrity: sha512-rF/rXkvUOTdTIfoYbmszbSUGsCyvqACqy1VeP3nXONS+LxFl4bRmRcUTRrblL7IE5RTMCKUuPbqbQSE2hK7bqg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-rF/rXkvUOTdTIfoYbmszbSUGsCyvqACqy1VeP3nXONS+LxFl4bRmRcUTRrblL7IE5RTMCKUuPbqbQSE2hK7bqg==, + } + engines: { node: '>=10' } cpu: [x64] os: [darwin] '@swc/core-linux-arm-gnueabihf@1.5.29': - resolution: {integrity: sha512-2OAPL8iWBsmmwkjGXqvuUhbmmoLxS1xNXiMq87EsnCNMAKohGc7wJkdAOUL6J/YFpean/vwMWg64rJD4pycBeg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-2OAPL8iWBsmmwkjGXqvuUhbmmoLxS1xNXiMq87EsnCNMAKohGc7wJkdAOUL6J/YFpean/vwMWg64rJD4pycBeg==, + } + engines: { node: '>=10' } cpu: [arm] os: [linux] '@swc/core-linux-arm64-gnu@1.5.29': - resolution: {integrity: sha512-eH/Q9+8O5qhSxMestZnhuS1xqQMr6M7SolZYxiXJqxArXYILLCF+nq2R9SxuMl0CfjHSpb6+hHPk/HXy54eIRA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-eH/Q9+8O5qhSxMestZnhuS1xqQMr6M7SolZYxiXJqxArXYILLCF+nq2R9SxuMl0CfjHSpb6+hHPk/HXy54eIRA==, + } + engines: { node: '>=10' } cpu: [arm64] os: [linux] '@swc/core-linux-arm64-musl@1.5.29': - resolution: {integrity: sha512-TERh2OICAJz+SdDIK9+0GyTUwF6r4xDlFmpoiHKHrrD/Hh3u+6Zue0d7jQ/he/i80GDn4tJQkHlZys+RZL5UZg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-TERh2OICAJz+SdDIK9+0GyTUwF6r4xDlFmpoiHKHrrD/Hh3u+6Zue0d7jQ/he/i80GDn4tJQkHlZys+RZL5UZg==, + } + engines: { node: '>=10' } cpu: [arm64] os: [linux] '@swc/core-linux-x64-gnu@1.5.29': - resolution: {integrity: sha512-WMDPqU7Ji9dJpA+Llek2p9t7pcy7Bob8ggPUvgsIlv3R/eesF9DIzSbrgl6j3EAEPB9LFdSafsgf6kT/qnvqFg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-WMDPqU7Ji9dJpA+Llek2p9t7pcy7Bob8ggPUvgsIlv3R/eesF9DIzSbrgl6j3EAEPB9LFdSafsgf6kT/qnvqFg==, + } + engines: { node: '>=10' } cpu: [x64] os: [linux] '@swc/core-linux-x64-musl@1.5.29': - resolution: {integrity: sha512-DO14glwpdKY4POSN0201OnGg1+ziaSVr6/RFzuSLggshwXeeyVORiHv3baj7NENhJhWhUy3NZlDsXLnRFkmhHQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-DO14glwpdKY4POSN0201OnGg1+ziaSVr6/RFzuSLggshwXeeyVORiHv3baj7NENhJhWhUy3NZlDsXLnRFkmhHQ==, + } + engines: { node: '>=10' } cpu: [x64] os: [linux] '@swc/core-win32-arm64-msvc@1.5.29': - resolution: {integrity: sha512-V3Y1+a1zG1zpYXUMqPIHEMEOd+rHoVnIpO/KTyFwAmKVu8v+/xPEVx/AGoYE67x4vDAAvPQrKI3Aokilqa5yVg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-V3Y1+a1zG1zpYXUMqPIHEMEOd+rHoVnIpO/KTyFwAmKVu8v+/xPEVx/AGoYE67x4vDAAvPQrKI3Aokilqa5yVg==, + } + engines: { node: '>=10' } cpu: [arm64] os: [win32] '@swc/core-win32-ia32-msvc@1.5.29': - resolution: {integrity: sha512-OrM6yfXw4wXhnVFosOJzarw0Fdz5Y0okgHfn9oFbTPJhoqxV5Rdmd6kXxWu2RiVKs6kGSJFZXHDeUq2w5rTIMg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-OrM6yfXw4wXhnVFosOJzarw0Fdz5Y0okgHfn9oFbTPJhoqxV5Rdmd6kXxWu2RiVKs6kGSJFZXHDeUq2w5rTIMg==, + } + engines: { node: '>=10' } cpu: [ia32] os: [win32] '@swc/core-win32-x64-msvc@1.5.29': - resolution: {integrity: sha512-eD/gnxqKyZQQR0hR7TMkIlJ+nCF9dzYmVVNbYZWuA1Xy94aBPUsEk3Uw3oG7q6R3ErrEUPP0FNf2ztEnv+I+dw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-eD/gnxqKyZQQR0hR7TMkIlJ+nCF9dzYmVVNbYZWuA1Xy94aBPUsEk3Uw3oG7q6R3ErrEUPP0FNf2ztEnv+I+dw==, + } + engines: { node: '>=10' } cpu: [x64] os: [win32] '@swc/core@1.5.29': - resolution: {integrity: sha512-nvTtHJI43DUSOAf3h9XsqYg8YXKc0/N4il9y4j0xAkO0ekgDNo+3+jbw6MInawjKJF9uulyr+f5bAutTsOKVlw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-nvTtHJI43DUSOAf3h9XsqYg8YXKc0/N4il9y4j0xAkO0ekgDNo+3+jbw6MInawjKJF9uulyr+f5bAutTsOKVlw==, + } + engines: { node: '>=10' } peerDependencies: '@swc/helpers': '*' peerDependenciesMeta: @@ -1290,190 +1915,355 @@ packages: optional: true '@swc/counter@0.1.3': - resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + resolution: + { + integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==, + } '@swc/helpers@0.5.12': - resolution: {integrity: sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==} + resolution: + { + integrity: sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==, + } '@swc/types@0.1.12': - resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==} + resolution: + { + integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==, + } '@tsconfig/node10@1.0.11': - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + resolution: + { + integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==, + } '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + resolution: + { + integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==, + } '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + resolution: + { + integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==, + } '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + resolution: + { + integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==, + } '@tybys/wasm-util@0.9.0': - resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + resolution: + { + integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==, + } '@types/body-parser@1.19.5': - resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + resolution: + { + integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==, + } '@types/bun@1.1.8': - resolution: {integrity: sha512-PIwVFQKPviksiibobyvcWtMvMFMTj91T8dQEh9l1P3Ypr3ZuVn9w7HSr+5mTNrPqD1xpdDLEErzZPU8gqHBu6g==} + resolution: + { + integrity: sha512-PIwVFQKPviksiibobyvcWtMvMFMTj91T8dQEh9l1P3Ypr3ZuVn9w7HSr+5mTNrPqD1xpdDLEErzZPU8gqHBu6g==, + } '@types/busboy@1.5.4': - resolution: {integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==} + resolution: + { + integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==, + } '@types/connect@3.4.38': - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + resolution: + { + integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==, + } '@types/express-serve-static-core@4.19.5': - resolution: {integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==} + resolution: + { + integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==, + } '@types/express@4.17.21': - resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + resolution: + { + integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==, + } '@types/http-errors@2.0.4': - resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + resolution: + { + integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==, + } '@types/mime@1.3.5': - resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + resolution: + { + integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==, + } '@types/node-forge@1.3.11': - resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} + resolution: + { + integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==, + } '@types/node@20.12.14': - resolution: {integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==} + resolution: + { + integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==, + } '@types/node@20.16.1': - resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==} + resolution: + { + integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==, + } '@types/node@22.5.0': - resolution: {integrity: sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==} + resolution: + { + integrity: sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==, + } '@types/parse-json@4.0.2': - resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + resolution: + { + integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==, + } '@types/proxy-addr@2.0.3': - resolution: {integrity: sha512-TgAHHO4tNG3HgLTUhB+hM4iwW6JUNeQHCLnF1DjaDA9c69PN+IasoFu2MYDhubFc+ZIw5c5t9DMtjvrD6R3Egg==} + resolution: + { + integrity: sha512-TgAHHO4tNG3HgLTUhB+hM4iwW6JUNeQHCLnF1DjaDA9c69PN+IasoFu2MYDhubFc+ZIw5c5t9DMtjvrD6R3Egg==, + } '@types/qs@6.9.15': - resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} + resolution: + { + integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==, + } '@types/range-parser@1.2.7': - resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + resolution: + { + integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==, + } '@types/send@0.17.4': - resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + resolution: + { + integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==, + } '@types/serve-static@1.15.7': - resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + resolution: + { + integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==, + } '@types/tmp@0.2.6': - resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} + resolution: + { + integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==, + } '@types/ws@8.5.12': - resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} + resolution: + { + integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==, + } '@yarnpkg/lockfile@1.1.0': - resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} + resolution: + { + integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==, + } '@yarnpkg/parsers@3.0.0-rc.46': - resolution: {integrity: sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==} - engines: {node: '>=14.15.0'} + resolution: + { + integrity: sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==, + } + engines: { node: '>=14.15.0' } '@zkochan/js-yaml@0.0.7': - resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} + resolution: + { + integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==, + } hasBin: true accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==, + } + engines: { node: '>= 0.6' } acorn-walk@8.3.3: - resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==, + } + engines: { node: '>=0.4.0' } acorn@8.12.1: - resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==, + } + engines: { node: '>=0.4.0' } hasBin: true address@1.2.2: - resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} - engines: {node: '>= 10.0.0'} + resolution: + { + integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==, + } + engines: { node: '>= 10.0.0' } ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==, + } + engines: { node: '>=6' } ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: '>=8' } ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==, + } + engines: { node: '>=4' } ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: '>=8' } ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==, + } + engines: { node: '>=10' } anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, + } + engines: { node: '>= 8' } arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + resolution: + { + integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==, + } argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + resolution: + { + integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, + } argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + resolution: + { + integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, + } array-flatten@1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + resolution: + { + integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==, + } as-table@1.0.55: - resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + resolution: + { + integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==, + } async@3.2.6: - resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + resolution: + { + integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==, + } asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + resolution: + { + integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, + } axios@1.7.5: - resolution: {integrity: sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==} + resolution: + { + integrity: sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==, + } babel-plugin-const-enum@1.2.0: - resolution: {integrity: sha512-o1m/6iyyFnp9MRsK1dHF3bneqyf3AlM2q3A/YbgQr2pCat6B6XJVDv2TXqzfY2RYUi4mak6WAksSBPlyYGx9dg==} + resolution: + { + integrity: sha512-o1m/6iyyFnp9MRsK1dHF3bneqyf3AlM2q3A/YbgQr2pCat6B6XJVDv2TXqzfY2RYUi4mak6WAksSBPlyYGx9dg==, + } peerDependencies: '@babel/core': ^7.0.0-0 babel-plugin-macros@2.8.0: - resolution: {integrity: sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==} + resolution: + { + integrity: sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==, + } babel-plugin-polyfill-corejs2@0.4.11: - resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} + resolution: + { + integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==, + } peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 babel-plugin-polyfill-corejs3@0.10.6: - resolution: {integrity: sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==} + resolution: + { + integrity: sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==, + } peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 babel-plugin-polyfill-regenerator@0.6.2: - resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} + resolution: + { + integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==, + } peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 babel-plugin-transform-typescript-metadata@0.3.2: - resolution: {integrity: sha512-mWEvCQTgXQf48yDqgN7CH50waTyYBeP2Lpqx4nNWab9sxEpdXVeKgfj1qYI2/TgUPQtNFZ85i3PemRtnXVYYJg==} + resolution: + { + integrity: sha512-mWEvCQTgXQf48yDqgN7CH50waTyYBeP2Lpqx4nNWab9sxEpdXVeKgfj1qYI2/TgUPQtNFZ85i3PemRtnXVYYJg==, + } peerDependencies: '@babel/core': ^7 '@babel/traverse': ^7 @@ -1482,170 +2272,311 @@ packages: optional: true balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + resolution: + { + integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, + } base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + resolution: + { + integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==, + } binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==, + } + engines: { node: '>=8' } bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + resolution: + { + integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==, + } blake3-wasm@2.1.5: - resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + resolution: + { + integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==, + } body-parser@1.20.2: - resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + resolution: + { + integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==, + } + engines: { node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16 } brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + resolution: + { + integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, + } brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + resolution: + { + integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==, + } braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, + } + engines: { node: '>=8' } browserslist@4.23.3: - resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + resolution: + { + integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==, + } + engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } hasBin: true buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + resolution: + { + integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, + } buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + resolution: + { + integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==, + } bun-types@1.1.26: - resolution: {integrity: sha512-n7jDe62LsB2+WE8Q8/mT3azkPaatKlj/2MyP6hi3mKvPz9oPpB6JW/Ll6JHtNLudasFFuvfgklYSE+rreGvBjw==} + resolution: + { + integrity: sha512-n7jDe62LsB2+WE8Q8/mT3azkPaatKlj/2MyP6hi3mKvPz9oPpB6JW/Ll6JHtNLudasFFuvfgklYSE+rreGvBjw==, + } busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} + resolution: + { + integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==, + } + engines: { node: '>=10.16.0' } bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==, + } + engines: { node: '>= 0.8' } call-bind@1.0.7: - resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==, + } + engines: { node: '>= 0.4' } callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, + } + engines: { node: '>=6' } caniuse-lite@1.0.30001653: - resolution: {integrity: sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==} + resolution: + { + integrity: sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==, + } capnp-ts@0.7.0: - resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} + resolution: + { + integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==, + } chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==, + } + engines: { node: '>=4' } chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, + } + engines: { node: '>=10' } chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} + resolution: + { + integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==, + } + engines: { node: '>= 8.10.0' } cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==, + } + engines: { node: '>=8' } cli-spinners@2.6.1: - resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==, + } + engines: { node: '>=6' } cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, + } + engines: { node: '>=12' } clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} + resolution: + { + integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==, + } + engines: { node: '>=0.8' } color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + resolution: + { + integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, + } color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: '>=7.0.0' } color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + resolution: + { + integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, + } color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } colorette@2.0.20: - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + resolution: + { + integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==, + } columnify@1.6.0: - resolution: {integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==} - engines: {node: '>=8.0.0'} + resolution: + { + integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==, + } + engines: { node: '>=8.0.0' } combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, + } + engines: { node: '>= 0.8' } concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + resolution: + { + integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, + } consola@3.2.3: - resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} - engines: {node: ^14.18.0 || >=16.10.0} + resolution: + { + integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==, + } + engines: { node: ^14.18.0 || >=16.10.0 } content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==, + } + engines: { node: '>= 0.6' } content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==, + } + engines: { node: '>= 0.6' } convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + resolution: + { + integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, + } cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + resolution: + { + integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==, + } cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==, + } + engines: { node: '>= 0.6' } cookie@0.6.0: - resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==, + } + engines: { node: '>= 0.6' } core-js-compat@3.38.1: - resolution: {integrity: sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==} + resolution: + { + integrity: sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==, + } cosmiconfig@6.0.0: - resolution: {integrity: sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==, + } + engines: { node: '>=8' } create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + resolution: + { + integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==, + } data-uri-to-buffer@2.0.2: - resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} + resolution: + { + integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==, + } date-fns@3.6.0: - resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + resolution: + { + integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==, + } debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + resolution: + { + integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==, + } peerDependencies: supports-color: '*' peerDependenciesMeta: @@ -1653,8 +2584,11 @@ packages: optional: true debug@4.3.6: - resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} - engines: {node: '>=6.0'} + resolution: + { + integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==, + } + engines: { node: '>=6.0' } peerDependencies: supports-color: '*' peerDependenciesMeta: @@ -1662,164 +2596,290 @@ packages: optional: true defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + resolution: + { + integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==, + } define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==, + } + engines: { node: '>= 0.4' } define-lazy-prop@2.0.0: - resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==, + } + engines: { node: '>=8' } defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + resolution: + { + integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==, + } delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, + } + engines: { node: '>=0.4.0' } depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==, + } + engines: { node: '>= 0.8' } destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + resolution: + { + integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==, + } + engines: { node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16 } detect-port@1.6.1: - resolution: {integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==} - engines: {node: '>= 4.0.0'} + resolution: + { + integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==, + } + engines: { node: '>= 4.0.0' } hasBin: true diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} + resolution: + { + integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==, + } + engines: { node: '>=0.3.1' } dotenv-expand@11.0.6: - resolution: {integrity: sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==, + } + engines: { node: '>=12' } dotenv@16.4.5: - resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==, + } + engines: { node: '>=12' } duplexer@0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + resolution: + { + integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==, + } ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + resolution: + { + integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==, + } ejs@3.1.10: - resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==, + } + engines: { node: '>=0.10.0' } hasBin: true electron-to-chromium@1.5.13: - resolution: {integrity: sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==} + resolution: + { + integrity: sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==, + } emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==, + } + engines: { node: '>= 0.8' } end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + resolution: + { + integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==, + } enquirer@2.3.6: - resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} - engines: {node: '>=8.6'} + resolution: + { + integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==, + } + engines: { node: '>=8.6' } error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + resolution: + { + integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==, + } es-define-property@1.0.0: - resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==, + } + engines: { node: '>= 0.4' } es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==, + } + engines: { node: '>= 0.4' } esbuild@0.17.19: - resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==, + } + engines: { node: '>=12' } hasBin: true escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==, + } + engines: { node: '>=6' } escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + resolution: + { + integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==, + } escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} + resolution: + { + integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==, + } + engines: { node: '>=0.8.0' } escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, + } + engines: { node: '>=10' } esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, + } + engines: { node: '>=4' } hasBin: true estree-walker@0.6.1: - resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + resolution: + { + integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==, + } esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, + } + engines: { node: '>=0.10.0' } etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==, + } + engines: { node: '>= 0.6' } exit-hook@2.2.1: - resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==, + } + engines: { node: '>=6' } express@4.19.2: - resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} - engines: {node: '>= 0.10.0'} + resolution: + { + integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==, + } + engines: { node: '>= 0.10.0' } fast-glob@3.2.7: - resolution: {integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==, + } + engines: { node: '>=8' } fastq@1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + resolution: + { + integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==, + } figures@3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==, + } + engines: { node: '>=8' } filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + resolution: + { + integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==, + } fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, + } + engines: { node: '>=8' } finalhandler@1.2.0: - resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==, + } + engines: { node: '>= 0.8' } flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + resolution: + { + integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==, + } hasBin: true follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} - engines: {node: '>=4.0'} + resolution: + { + integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==, + } + engines: { node: '>=4.0' } peerDependencies: debug: '*' peerDependenciesMeta: @@ -1827,349 +2887,625 @@ packages: optional: true form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==, + } + engines: { node: '>= 6' } forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==, + } + engines: { node: '>= 0.6' } fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==, + } + engines: { node: '>= 0.6' } front-matter@4.0.2: - resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} + resolution: + { + integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==, + } fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + resolution: + { + integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==, + } fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} - engines: {node: '>=14.14'} + resolution: + { + integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==, + } + engines: { node: '>=14.14' } fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } os: [darwin] function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + resolution: + { + integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, + } gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, + } + engines: { node: '>=6.9.0' } get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} + resolution: + { + integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, + } + engines: { node: 6.* || 8.* || >= 10.* } get-intrinsic@1.2.4: - resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==, + } + engines: { node: '>= 0.4' } get-source@2.0.12: - resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} + resolution: + { + integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==, + } glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, + } + engines: { node: '>= 6' } glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + resolution: + { + integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==, + } globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==, + } + engines: { node: '>=4' } gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + resolution: + { + integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==, + } graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + resolution: + { + integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, + } has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, + } + engines: { node: '>=4' } has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, + } + engines: { node: '>=8' } has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + resolution: + { + integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==, + } has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==, + } + engines: { node: '>= 0.4' } has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==, + } + engines: { node: '>= 0.4' } hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==, + } + engines: { node: '>= 0.4' } hosted-git-info@7.0.2: - resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} - engines: {node: ^16.14.0 || >=18.0.0} + resolution: + { + integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==, + } + engines: { node: ^16.14.0 || >=18.0.0 } http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==, + } + engines: { node: '>= 0.8' } iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==, + } + engines: { node: '>=0.10.0' } ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + resolution: + { + integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==, + } ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} + resolution: + { + integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==, + } + engines: { node: '>= 4' } import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==, + } + engines: { node: '>=6' } inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + resolution: + { + integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, + } ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==, + } + engines: { node: '>= 0.10' } is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + resolution: + { + integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==, + } is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==, + } + engines: { node: '>=8' } is-core-module@2.15.1: - resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==, + } + engines: { node: '>= 0.4' } is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==, + } + engines: { node: '>=8' } hasBin: true is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, + } + engines: { node: '>=0.10.0' } is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: '>=8' } is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, + } + engines: { node: '>=0.10.0' } is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==, + } + engines: { node: '>=8' } is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} + resolution: + { + integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, + } + engines: { node: '>=0.12.0' } is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==, + } + engines: { node: '>=10' } is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==, + } + engines: { node: '>=8' } jake@10.9.2: - resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==, + } + engines: { node: '>=10' } hasBin: true jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + resolution: + { + integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, + } js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + resolution: + { + integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==, + } hasBin: true jsesc@0.5.0: - resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + resolution: + { + integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==, + } hasBin: true jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==, + } + engines: { node: '>=4' } hasBin: true json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + resolution: + { + integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, + } json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, + } + engines: { node: '>=6' } hasBin: true jsonc-parser@3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + resolution: + { + integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==, + } jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + resolution: + { + integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==, + } lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + resolution: + { + integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, + } lines-and-columns@2.0.4: - resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } lodash.debounce@4.0.8: - resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + resolution: + { + integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==, + } log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==, + } + engines: { node: '>=10' } lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + resolution: + { + integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==, + } lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + resolution: + { + integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, + } magic-string@0.25.9: - resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + resolution: + { + integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==, + } make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + resolution: + { + integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==, + } media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==, + } + engines: { node: '>= 0.6' } merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + resolution: + { + integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==, + } merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, + } + engines: { node: '>= 8' } methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==, + } + engines: { node: '>= 0.6' } micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} + resolution: + { + integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, + } + engines: { node: '>=8.6' } mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, + } + engines: { node: '>= 0.6' } mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, + } + engines: { node: '>= 0.6' } mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==, + } + engines: { node: '>=4' } hasBin: true mime@3.0.0: - resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} - engines: {node: '>=10.0.0'} + resolution: + { + integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==, + } + engines: { node: '>=10.0.0' } hasBin: true mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, + } + engines: { node: '>=6' } miniflare@3.20240821.0: - resolution: {integrity: sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==} - engines: {node: '>=16.13'} + resolution: + { + integrity: sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==, + } + engines: { node: '>=16.13' } hasBin: true minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + resolution: + { + integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, + } minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==, + } + engines: { node: '>=10' } minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { + integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==, + } + engines: { node: '>=16 || 14 >=14.17' } minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + resolution: + { + integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==, + } mrmime@2.0.0: - resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==, + } + engines: { node: '>=10' } ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + resolution: + { + integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==, + } ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + resolution: + { + integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, + } ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + resolution: + { + integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, + } multipasta@0.2.5: - resolution: {integrity: sha512-c8eMDb1WwZcE02WVjHoOmUVk7fnKU/RmUcosHACglrWAuPQsEJv+E8430sXj6jNc1jHw0zrS16aCjQh4BcEb4A==} + resolution: + { + integrity: sha512-c8eMDb1WwZcE02WVjHoOmUVk7fnKU/RmUcosHACglrWAuPQsEJv+E8430sXj6jNc1jHw0zrS16aCjQh4BcEb4A==, + } mustache@4.2.0: - resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} + resolution: + { + integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==, + } hasBin: true nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + resolution: + { + integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==, + } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } hasBin: true negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==, + } + engines: { node: '>= 0.6' } node-fetch-native@1.6.4: - resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + resolution: + { + integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==, + } node-forge@1.3.1: - resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} - engines: {node: '>= 6.13.0'} + resolution: + { + integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==, + } + engines: { node: '>= 6.13.0' } node-machine-id@1.1.12: - resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} + resolution: + { + integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==, + } node-releases@2.0.18: - resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + resolution: + { + integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==, + } normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, + } + engines: { node: '>=0.10.0' } npm-package-arg@11.0.1: - resolution: {integrity: sha512-M7s1BD4NxdAvBKUPqqRW957Xwcl/4Zvo8Aj+ANrzvIPzGJZElrH7Z//rSaec2ORcND6FHHLnZeY8qgTpXDMFQQ==} - engines: {node: ^16.14.0 || >=18.0.0} + resolution: + { + integrity: sha512-M7s1BD4NxdAvBKUPqqRW957Xwcl/4Zvo8Aj+ANrzvIPzGJZElrH7Z//rSaec2ORcND6FHHLnZeY8qgTpXDMFQQ==, + } + engines: { node: ^16.14.0 || >=18.0.0 } npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==, + } + engines: { node: '>=8' } nx@19.6.4: - resolution: {integrity: sha512-yudYlBd3cMchRd8c0ZNan1SfT19AYK2zYOp77XVqVVwgqb6rJVxz6StFGFluUQ7Q7uSpkeT/8PsjwPVLt85EoQ==} + resolution: + { + integrity: sha512-yudYlBd3cMchRd8c0ZNan1SfT19AYK2zYOp77XVqVVwgqb6rJVxz6StFGFluUQ7Q7uSpkeT/8PsjwPVLt85EoQ==, + } hasBin: true peerDependencies: '@swc-node/register': ^1.8.0 @@ -2181,311 +3517,560 @@ packages: optional: true object-inspect@1.13.2: - resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==, + } + engines: { node: '>= 0.4' } on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==, + } + engines: { node: '>= 0.8' } once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + resolution: + { + integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, + } onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, + } + engines: { node: '>=6' } open@8.4.2: - resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==, + } + engines: { node: '>=12' } ora@5.3.0: - resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==, + } + engines: { node: '>=10' } oxc-resolver@1.11.0: - resolution: {integrity: sha512-N3qMse2AM7uST8PaiUMXZkcACyGAMN073tomyvzHTICSzaOqKHvVS0IZ3vj/OqoE140QP4CyOiWmgC1Hw5Urmg==} + resolution: + { + integrity: sha512-N3qMse2AM7uST8PaiUMXZkcACyGAMN073tomyvzHTICSzaOqKHvVS0IZ3vj/OqoE140QP4CyOiWmgC1Hw5Urmg==, + } parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, + } + engines: { node: '>=6' } parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==, + } + engines: { node: '>=8' } parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==, + } + engines: { node: '>= 0.8' } path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, + } + engines: { node: '>=8' } path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + resolution: + { + integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, + } path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + resolution: + { + integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==, + } path-to-regexp@6.2.2: - resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} + resolution: + { + integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==, + } path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, + } + engines: { node: '>=8' } pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + resolution: + { + integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==, + } picocolors@1.0.1: - resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + resolution: + { + integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==, + } picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} + resolution: + { + integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, + } + engines: { node: '>=8.6' } pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==, + } + engines: { node: '>= 6' } prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==, + } + engines: { node: '>=14' } hasBin: true pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } printable-characters@1.0.42: - resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + resolution: + { + integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==, + } proc-log@3.0.0: - resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==, + } + engines: { node: '>= 0.10' } proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + resolution: + { + integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==, + } qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} + resolution: + { + integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==, + } + engines: { node: '>=0.6' } queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + resolution: + { + integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, + } range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==, + } + engines: { node: '>= 0.6' } raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==, + } + engines: { node: '>= 0.8' } react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + resolution: + { + integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==, + } readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==, + } + engines: { node: '>= 6' } readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} + resolution: + { + integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==, + } + engines: { node: '>=8.10.0' } regenerate-unicode-properties@10.1.1: - resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==, + } + engines: { node: '>=4' } regenerate@1.4.2: - resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + resolution: + { + integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==, + } regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + resolution: + { + integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==, + } regenerator-transform@0.15.2: - resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + resolution: + { + integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==, + } regexpu-core@5.3.2: - resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==, + } + engines: { node: '>=4' } regjsparser@0.9.1: - resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + resolution: + { + integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==, + } hasBin: true require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, + } + engines: { node: '>=0.10.0' } resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, + } + engines: { node: '>=4' } resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==, + } + engines: { node: '>=10' } resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + resolution: + { + integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==, + } hasBin: true restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==, + } + engines: { node: '>=8' } reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + resolution: + { + integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==, + } + engines: { iojs: '>=1.0.0', node: '>=0.10.0' } rollup-plugin-inject@3.0.2: - resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} + resolution: + { + integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==, + } deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. rollup-plugin-node-polyfills@0.2.1: - resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} + resolution: + { + integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==, + } rollup-pluginutils@2.8.2: - resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + resolution: + { + integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==, + } run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + resolution: + { + integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, + } safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + resolution: + { + integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, + } safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + resolution: + { + integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, + } selfsigned@2.4.1: - resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==, + } + engines: { node: '>=10' } semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + resolution: + { + integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, + } hasBin: true semver@7.6.3: - resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==, + } + engines: { node: '>=10' } hasBin: true send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==, + } + engines: { node: '>= 0.8.0' } serve-static@1.15.0: - resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==, + } + engines: { node: '>= 0.8.0' } set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==, + } + engines: { node: '>= 0.4' } setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + resolution: + { + integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==, + } side-channel@1.0.6: - resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==, + } + engines: { node: '>= 0.4' } signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + resolution: + { + integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, + } source-map-support@0.5.19: - resolution: {integrity: sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==} + resolution: + { + integrity: sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==, + } source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + resolution: + { + integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==, + } source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, + } + engines: { node: '>=0.10.0' } sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + resolution: + { + integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==, + } deprecated: Please use @jridgewell/sourcemap-codec instead sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + resolution: + { + integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, + } stacktracey@2.1.8: - resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} + resolution: + { + integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==, + } statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==, + } + engines: { node: '>= 0.8' } stoppable@1.1.0: - resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} - engines: {node: '>=4', npm: '>=6'} + resolution: + { + integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==, + } + engines: { node: '>=4', npm: '>=6' } streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} + resolution: + { + integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==, + } + engines: { node: '>=10.0.0' } string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: '>=8' } string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + resolution: + { + integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==, + } strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: '>=8' } strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==, + } + engines: { node: '>=4' } strong-log-transformer@2.1.0: - resolution: {integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==, + } + engines: { node: '>=4' } hasBin: true supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==, + } + engines: { node: '>=4' } supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, + } + engines: { node: '>=8' } supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, + } + engines: { node: '>= 0.4' } tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==, + } + engines: { node: '>=6' } through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + resolution: + { + integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==, + } tmp@0.2.3: - resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} - engines: {node: '>=14.14'} + resolution: + { + integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==, + } + engines: { node: '>=14.14' } to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, + } + engines: { node: '>=4' } to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + resolution: + { + integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, + } + engines: { node: '>=8.0' } toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} + resolution: + { + integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==, + } + engines: { node: '>=0.6' } ts-node@10.9.1: - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + resolution: + { + integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==, + } hasBin: true peerDependencies: '@swc/core': '>=1.2.50' @@ -2499,96 +4084,168 @@ packages: optional: true tsconfig-paths@4.2.0: - resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==, + } + engines: { node: '>=6' } tslib@2.7.0: - resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + resolution: + { + integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==, + } type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==, + } + engines: { node: '>= 0.6' } typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} - engines: {node: '>=14.17'} + resolution: + { + integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==, + } + engines: { node: '>=14.17' } hasBin: true ufo@1.5.4: - resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + resolution: + { + integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==, + } undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + resolution: + { + integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==, + } undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + resolution: + { + integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==, + } undici@5.28.4: - resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} - engines: {node: '>=14.0'} + resolution: + { + integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==, + } + engines: { node: '>=14.0' } unenv-nightly@1.10.0-1717606461.a117952: - resolution: {integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==} + resolution: + { + integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==, + } unicode-canonical-property-names-ecmascript@2.0.0: - resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==, + } + engines: { node: '>=4' } unicode-match-property-ecmascript@2.0.0: - resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==, + } + engines: { node: '>=4' } unicode-match-property-value-ecmascript@2.1.0: - resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==, + } + engines: { node: '>=4' } unicode-property-aliases-ecmascript@2.1.0: - resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==, + } + engines: { node: '>=4' } universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} + resolution: + { + integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==, + } + engines: { node: '>= 10.0.0' } unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==, + } + engines: { node: '>= 0.8' } update-browserslist-db@1.1.0: - resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} + resolution: + { + integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==, + } hasBin: true peerDependencies: browserslist: '>= 4.21.0' util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + resolution: + { + integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==, + } utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} + resolution: + { + integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==, + } + engines: { node: '>= 0.4.0' } v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + resolution: + { + integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==, + } validate-npm-package-name@5.0.1: - resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==, + } + engines: { node: '>= 0.8' } wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + resolution: + { + integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==, + } workerd@1.20240821.1: - resolution: {integrity: sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==, + } + engines: { node: '>=16' } hasBin: true wrangler@3.72.3: - resolution: {integrity: sha512-EBlJGOcwanbzFkiJkRB47WKhvevh1AZK0ty0MyD0gptsgWnAxBfmFGiBuzOuRXbvH45ZrFrTqgi8c67EwcV1nA==} - engines: {node: '>=16.17.0'} + resolution: + { + integrity: sha512-EBlJGOcwanbzFkiJkRB47WKhvevh1AZK0ty0MyD0gptsgWnAxBfmFGiBuzOuRXbvH45ZrFrTqgi8c67EwcV1nA==, + } + engines: { node: '>=16.17.0' } hasBin: true peerDependencies: '@cloudflare/workers-types': ^4.20240821.1 @@ -2597,15 +4254,24 @@ packages: optional: true wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, + } + engines: { node: '>=10' } wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + resolution: + { + integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, + } ws@8.18.0: - resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} - engines: {node: '>=10.0.0'} + resolution: + { + integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==, + } + engines: { node: '>=10.0.0' } peerDependencies: bufferutil: ^4.0.1 utf-8-validate: '>=5.0.2' @@ -2616,39 +4282,65 @@ packages: optional: true xxhash-wasm@1.0.2: - resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} + resolution: + { + integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==, + } y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, + } + engines: { node: '>=10' } yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + resolution: + { + integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, + } yaml@1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==, + } + engines: { node: '>= 6' } yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, + } + engines: { node: '>=12' } yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, + } + engines: { node: '>=12' } yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==, + } + engines: { node: '>=6' } youch@3.3.3: - resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} + resolution: + { + integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==, + } zod@3.23.8: - resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + resolution: + { + integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==, + } snapshots: - '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.5 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 4aeafabc7bc..5845e2430d5 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,4 +2,4 @@ packages: - packages/* - packages/multipart-parser/bench - packages/multipart-parser/examples/* - - packages/node-request-handler/bench + - packages/node-fetch-server/bench From 81f213e9dff2a78e78712a437ddd0d31b3992a4b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 11:01:06 -0700 Subject: [PATCH 386/730] Small internal refactor --- .../src/lib/request-listener.ts | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 787b829d851..1564cd8667a 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -1,7 +1,7 @@ import * as http from 'node:http'; import { getRequestUrl } from './request-url.js'; -import { TrustArg, createTrustProxy } from './trust-proxy.js'; +import { TrustArg, TrustProxy, createTrustProxy } from './trust-proxy.js'; /** * A function that handles an incoming request and returns a response. @@ -92,13 +92,7 @@ export function createRequestListener( let trustProxy = createTrustProxy(options?.trustProxy); return async (req, res) => { - let controller = new AbortController(); - res.on('close', () => { - controller.abort(); - }); - - let url = getRequestUrl(req, trustProxy); - let request = createRequest(req, url, controller.signal); + let request = createRequest(req, res, trustProxy); try { let response = await handler(request); @@ -129,11 +123,21 @@ function internalServerError(): Response { }); } -function createRequest(req: http.IncomingMessage, url: URL, signal: AbortSignal): Request { +function createRequest( + req: http.IncomingMessage, + res: http.ServerResponse, + trustProxy: TrustProxy, +): Request { + let controller = new AbortController(); + res.on('close', () => { + controller.abort(); + }); + + let url = getRequestUrl(req, trustProxy); let init: RequestInit = { method: req.method, headers: createHeaders(req.headers), - signal, + signal: controller.signal, }; if (req.method !== 'GET' && req.method !== 'HEAD') { From f7ab66b18afe32efae7239f4f9048f086e066e7b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 11:50:57 -0700 Subject: [PATCH 387/730] Update README --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5bab1dc1135..d64e96f09ab 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ This repository is a collection of packages for use with [Remix](https://remix.r ## Philosophy -The packages in this repository are designed around the [single responsibility principle](https://en.wikipedia.org/wiki/Single-responsibility_principle); they each do one thing really well. Where existing web standards and APIs exist, we build on them in creative ways to expand and extend their functionality. Where new APIs are needed, we design theme to interoperate seamlessly with existing standards. +Each package in this repository has a [single responsibility](https://en.wikipedia.org/wiki/Single-responsibility_principle); it does one thing well. -The goal is that these libraries should be really useful for anyone who is building for the web. If you're using [Remix](https://remix.run), we've designed it from the start to work with web standards. If you're using some other framework, you should easily be able to integrate these tools into your workflow as well without going full-blown Remix. If you're building your own framework, we hope you'll be able to use these tools as well. +To maximize interoperability between packages, we build on web standards. Where standards are missing or incomplete, we augment them in unobtrusive ways to minimize the chance of incompatibility. What exactly does it mean when we say "web standards"? It means we use: @@ -13,7 +13,9 @@ What exactly does it mean when we say "web standards"? It means we use: - [The Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) instead of the Node.js crypto library - [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) and [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) instead of some bespoke runtime-specific API -You get the idea. The benefit of writing JavaScript like this is that it's incredibly portable between various runtimes. All of the packages in this repository work on any JavaScript runtime you might be using: Node.js, Bun, Deno, Cloudflare Workers, etc. +You get the idea. The benefit of writing JavaScript like this is that it's portable between various runtimes. Unless explicitly noted, all packages in this repository work on any JavaScript runtime you might be using: [Node.js](https://nodejs.org/), [Bun](https://bun.sh/), [Deno](https://deno.com/), [Cloudflare Workers](https://workers.cloudflare.com/), etc. + +The goal is that these packages should be useful for anyone who is building for the web. If you're using [Remix](https://remix.run), we've designed it from the start to work with web standards. If you're using some other framework, you should easily be able to integrate these tools into your workflow as well without going full-blown Remix. If you're building your own framework, we hope you'll be able to build on this foundation as well. ## Packages From 2378bd9ac00785fc39aee1270c7d65fe9119934e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 11:51:15 -0700 Subject: [PATCH 388/730] Add test script --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index c680ec08c26..5947108b51f 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ }, "scripts": { "clean": "git clean -fdX .", - "release": "node scripts/release.js" + "release": "node scripts/release.js", + "test": "nx run-many --projects='packages/*' --target=test" } } From 20fa7f17b548059fedc40ab6c8bf11469b03f4bf Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 11:51:33 -0700 Subject: [PATCH 389/730] Update CHANGELOG --- packages/node-fetch-server/CHANGELOG.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 9301b86117e..e69de29bb2d 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -1,5 +0,0 @@ -# node-fetch-server CHANGELOG - -## HEAD - -- Initial release From 488e8ea379b8b8d02bd0aa47b7f04db06b6e61fc Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 11:51:46 -0700 Subject: [PATCH 390/730] Add CONTRIBUTING.md --- CONTRIBUTING.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000000..fe9eb7eca9e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,3 @@ +## Making Changes + +## Releases From 95b53762b6fc3d1960ec3885ee7a754f1fc89850 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 11:52:52 -0700 Subject: [PATCH 391/730] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d64e96f09ab..231e027624b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Each package in this repository has a [single responsibility](https://en.wikiped To maximize interoperability between packages, we build on web standards. Where standards are missing or incomplete, we augment them in unobtrusive ways to minimize the chance of incompatibility. -What exactly does it mean when we say "web standards"? It means we use: +What exactly we mean by "web standards"? It means we use: - [The Web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) instead of Node.js streams - [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) instead of Node.js `Buffer`s From 90c047cde7d8ccf5ab0df418ede266b1b486ef59 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 12:09:51 -0700 Subject: [PATCH 392/730] Add { origin } option to createRequestListener --- .../src/lib/request-listener.ts | 26 ++++++++++++------- ...est-url.spec.ts => request-origin.spec.ts} | 14 ++++------ .../lib/{request-url.ts => request-origin.ts} | 6 ++--- .../src/node-fetch-server.ts | 2 +- 4 files changed, 26 insertions(+), 22 deletions(-) rename packages/node-fetch-server/src/lib/{request-url.spec.ts => request-origin.spec.ts} (74%) rename packages/node-fetch-server/src/lib/{request-url.ts => request-origin.ts} (89%) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 1564cd8667a..6cec4320dc0 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -1,7 +1,7 @@ import * as http from 'node:http'; -import { getRequestUrl } from './request-url.js'; -import { TrustArg, TrustProxy, createTrustProxy } from './trust-proxy.js'; +import { getRequestOrigin } from './request-origin.js'; +import { TrustArg, createTrustProxy } from './trust-proxy.js'; /** * A function that handles an incoming request and returns a response. @@ -30,6 +30,17 @@ export interface RequestListenerOptions { * default a 500 Internal Server Error response will be sent. */ onError?: ErrorHandler; + /** + * Overrides the origin of the incoming request. + * + * Normally the request origin is derived from the `Host` header and the connection protocol. + * Additionally, the `X-Forwarded-Proto` and `X-Forwarded-Host` headers can be used via the + * `trustProxy` option to derive the origin from HTTP reverse proxy headers. + * + * If `origin` is provided, it will be used as the origin of the request and the `Host` header + * (along with any reverse proxy headers) will be ignored. + */ + origin?: string; /** * Determines if/how the `X-Forwarded-Proto` and `X-Forwarded-Host` headers should be used to * derive the request URL. By default these headers are not trusted because they can easily be @@ -92,7 +103,9 @@ export function createRequestListener( let trustProxy = createTrustProxy(options?.trustProxy); return async (req, res) => { - let request = createRequest(req, res, trustProxy); + let origin = options?.origin ?? getRequestOrigin(req, trustProxy); + let url = new URL(req.url!, origin); + let request = createRequest(req, res, url); try { let response = await handler(request); @@ -123,17 +136,12 @@ function internalServerError(): Response { }); } -function createRequest( - req: http.IncomingMessage, - res: http.ServerResponse, - trustProxy: TrustProxy, -): Request { +function createRequest(req: http.IncomingMessage, res: http.ServerResponse, url: URL): Request { let controller = new AbortController(); res.on('close', () => { controller.abort(); }); - let url = getRequestUrl(req, trustProxy); let init: RequestInit = { method: req.method, headers: createHeaders(req.headers), diff --git a/packages/node-fetch-server/src/lib/request-url.spec.ts b/packages/node-fetch-server/src/lib/request-origin.spec.ts similarity index 74% rename from packages/node-fetch-server/src/lib/request-url.spec.ts rename to packages/node-fetch-server/src/lib/request-origin.spec.ts index e9dd42cdd69..a2e7510278a 100644 --- a/packages/node-fetch-server/src/lib/request-url.spec.ts +++ b/packages/node-fetch-server/src/lib/request-origin.spec.ts @@ -2,7 +2,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; import * as http from 'node:http'; -import { getRequestUrl } from './request-url.js'; +import { getRequestOrigin } from './request-origin.js'; import { createTrustProxy } from './trust-proxy.js'; describe('getRequestUrl', () => { @@ -16,10 +16,9 @@ describe('getRequestUrl', () => { headers: { host: 'example.com', }, - url: '/path?query', } as unknown as http.IncomingMessage; - assert.equal(getRequestUrl(req, trustProxy).toString(), 'http://example.com/path?query'); + assert.equal(getRequestOrigin(req, trustProxy).toString(), 'http://example.com'); }); it('returns the URL of an incoming request on a secure connection', () => { @@ -32,10 +31,9 @@ describe('getRequestUrl', () => { headers: { host: 'example.com', }, - url: '/path?query', } as unknown as http.IncomingMessage; - assert.equal(getRequestUrl(req, trustProxy).toString(), 'https://example.com/path?query'); + assert.equal(getRequestOrigin(req, trustProxy).toString(), 'https://example.com'); }); it('returns the URL of an incoming request with a forwarded protocol', () => { @@ -49,10 +47,9 @@ describe('getRequestUrl', () => { 'x-forwarded-proto': 'https', host: 'example.com', }, - url: '/path?query', } as unknown as http.IncomingMessage; - assert.equal(getRequestUrl(req, trustProxy).toString(), 'https://example.com/path?query'); + assert.equal(getRequestOrigin(req, trustProxy).toString(), 'https://example.com'); }); it('returns the URL of an incoming request with a forwarded host', () => { @@ -66,9 +63,8 @@ describe('getRequestUrl', () => { 'x-forwarded-host': 'mjackson.me', host: 'example.com', }, - url: '/path?query', } as unknown as http.IncomingMessage; - assert.equal(getRequestUrl(req, trustProxy).toString(), 'http://mjackson.me/path?query'); + assert.equal(getRequestOrigin(req, trustProxy).toString(), 'http://mjackson.me'); }); }); diff --git a/packages/node-fetch-server/src/lib/request-url.ts b/packages/node-fetch-server/src/lib/request-origin.ts similarity index 89% rename from packages/node-fetch-server/src/lib/request-url.ts rename to packages/node-fetch-server/src/lib/request-origin.ts index b955f7ba23a..0cd0728cb5a 100644 --- a/packages/node-fetch-server/src/lib/request-url.ts +++ b/packages/node-fetch-server/src/lib/request-origin.ts @@ -5,12 +5,12 @@ import * as tls from 'node:tls'; import { TrustProxy } from './trust-proxy.js'; /** - * Returns the URL of an incoming request. + * Returns the origin of an incoming request. */ -export function getRequestUrl(req: http.IncomingMessage, trustProxy: TrustProxy): URL { +export function getRequestOrigin(req: http.IncomingMessage, trustProxy: TrustProxy): string { let protocol = getProtocol(req, trustProxy); let hostname = getHostname(req, trustProxy); - return new URL(`${protocol}//${hostname}${req.url}`); + return `${protocol}//${hostname}`; } function getProtocol(req: http.IncomingMessage, trustProxy: TrustProxy): string { diff --git a/packages/node-fetch-server/src/node-fetch-server.ts b/packages/node-fetch-server/src/node-fetch-server.ts index db6fda94b1c..01609e47854 100644 --- a/packages/node-fetch-server/src/node-fetch-server.ts +++ b/packages/node-fetch-server/src/node-fetch-server.ts @@ -4,5 +4,5 @@ export { type RequestListenerOptions, createRequestListener, } from './lib/request-listener.js'; -export { getRequestUrl } from './lib/request-url.js'; +export { getRequestOrigin } from './lib/request-origin.js'; export { createTrustProxy } from './lib/trust-proxy.js'; From 6c4ad2ff0b8086425867dbf715d15793e5878a81 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 29 Aug 2024 13:55:39 -0700 Subject: [PATCH 393/730] Always flushHeaders() --- .../src/lib/request-listener.ts | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 6cec4320dc0..de0337e411b 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -31,14 +31,13 @@ export interface RequestListenerOptions { */ onError?: ErrorHandler; /** - * Overrides the origin of the incoming request. + * Overrides the origin of the incoming request URL. By default the request URL origin is derived + * from the `Host` header and the connection protocol. Additionally, the `X-Forwarded-Proto` and + * `X-Forwarded-Host` headers can be used via the `trustProxy` option to derive the origin from + * HTTP reverse proxy headers. * - * Normally the request origin is derived from the `Host` header and the connection protocol. - * Additionally, the `X-Forwarded-Proto` and `X-Forwarded-Host` headers can be used via the - * `trustProxy` option to derive the origin from HTTP reverse proxy headers. - * - * If `origin` is provided, it will be used as the origin of the request and the `Host` header - * (along with any reverse proxy headers) will be ignored. + * If `origin` is provided, it will be used as the origin of the request URL and the `Host` + * header, along with any HTTP reverse proxy headers will be ignored. */ origin?: string; /** @@ -201,11 +200,9 @@ async function sendResponse(res: http.ServerResponse, response: Response): Promi res.setHeader(name, value); } - if (isEventStreamResponse(response)) { - res.flushHeaders(); - } + res.flushHeaders(); - if (response.body) { + if (response.body != null) { for await (let chunk of response.body) { res.write(chunk); } @@ -213,8 +210,3 @@ async function sendResponse(res: http.ServerResponse, response: Response): Promi res.end(); } - -function isEventStreamResponse(response: Response): boolean { - let contentType = response.headers.get('Content-Type'); - return contentType?.startsWith('text/event-stream') ?? false; -} From 55f2289b62cd7ba562ca30df64ff36604859a7b3 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 12:05:58 -0700 Subject: [PATCH 394/730] Add basic hello world benchmark --- packages/node-fetch-server/bench/runner.sh | 44 +++++++++++++++++++ .../bench/servers/express.ts | 17 +++++-- .../bench/servers/node-fetch-server.ts | 15 +++++-- .../bench/servers/node-http.ts | 18 ++++++-- packages/node-fetch-server/package.json | 1 + 5 files changed, 83 insertions(+), 12 deletions(-) create mode 100755 packages/node-fetch-server/bench/runner.sh diff --git a/packages/node-fetch-server/bench/runner.sh b/packages/node-fetch-server/bench/runner.sh new file mode 100755 index 00000000000..a86b26d2629 --- /dev/null +++ b/packages/node-fetch-server/bench/runner.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +pushd "$SCRIPT_DIR" > /dev/null + +run_benchmark() { + local server_name=$1 + local start_command=$2 + + export PORT=3000 + + echo -e "\nRunning benchmark for $server_name ...\n" + + # Start the server in the background + $start_command & + local server_pid=$! + + # Wait for the server to start + sleep 2 + + wrk -t12 -c400 -d30s http://127.0.0.1:3000/ + + kill -SIGINT $server_pid + + wait $server_pid +} + +echo $(node -e 'console.log(`Platform: ${os.type()} (${os.release()})`)') +echo $(node -e 'console.log(`CPU: ${os.cpus()[0].model}`)') +echo $(node -e 'console.log(`Date: ${new Date().toLocaleString()}`)') + +NODE_VERSION=$(node -e 'console.log(process.version.slice(1))') +run_benchmark "node:http@$NODE_VERSION" \ + "node --import @swc-node/register/esm-register ./servers/node-http.ts" + +NODE_FETCH_SERVER_VERSION=$(node -e 'console.log(require("../package.json").version)') +run_benchmark "node-fetch-server@$NODE_FETCH_SERVER_VERSION" \ + "node --import @swc-node/register/esm-register ./servers/node-fetch-server.ts" + +EXPRESS_VERSION=$(node -e 'console.log(require("express/package.json").version)') +run_benchmark "express@$EXPRESS_VERSION" \ + "node --import @swc-node/register/esm-register ./servers/express.ts" + +popd > /dev/null diff --git a/packages/node-fetch-server/bench/servers/express.ts b/packages/node-fetch-server/bench/servers/express.ts index 124aa0d3fa1..ada071cc49c 100644 --- a/packages/node-fetch-server/bench/servers/express.ts +++ b/packages/node-fetch-server/bench/servers/express.ts @@ -1,12 +1,21 @@ +import * as stream from 'node:stream'; import express from 'express'; +const PORT = process.env.PORT || 3000; + let app = express(); app.get('/', (_req, res) => { res.type('text/html'); - res.send('

Hello, world!

'); -}); -app.listen(3000, () => { - console.log('Listening on http://localhost:3000 ...'); + let body = new stream.Readable({ + read() { + this.push('

Hello, world!

'); + this.push(null); + }, + }); + + body.pipe(res); }); + +app.listen(PORT); diff --git a/packages/node-fetch-server/bench/servers/node-fetch-server.ts b/packages/node-fetch-server/bench/servers/node-fetch-server.ts index c3b16e2f428..077c47a1f24 100644 --- a/packages/node-fetch-server/bench/servers/node-fetch-server.ts +++ b/packages/node-fetch-server/bench/servers/node-fetch-server.ts @@ -1,14 +1,21 @@ import * as http from 'node:http'; import { createRequestListener } from '@mjackson/node-fetch-server'; +const PORT = process.env.PORT || 3000; + let server = http.createServer( createRequestListener(() => { - return new Response('

Hello, world!

', { + let stream = new ReadableStream({ + start(controller) { + controller.enqueue('

Hello, world!

'); + controller.close(); + }, + }); + + return new Response(stream, { headers: { 'Content-Type': 'text/html' }, }); }), ); -server.listen(3000, () => { - console.log('Listening on http://localhost:3000 ...'); -}); +server.listen(PORT); diff --git a/packages/node-fetch-server/bench/servers/node-http.ts b/packages/node-fetch-server/bench/servers/node-http.ts index f35f3ab571b..8da1c473428 100644 --- a/packages/node-fetch-server/bench/servers/node-http.ts +++ b/packages/node-fetch-server/bench/servers/node-http.ts @@ -1,10 +1,20 @@ import * as http from 'node:http'; +import * as stream from 'node:stream'; + +const PORT = process.env.PORT || 3000; let server = http.createServer((_req, res) => { res.setHeader('Content-Type', 'text/html'); - res.end('

Hello, world!

'); -}); + res.flushHeaders(); -server.listen(3000, () => { - console.log('Listening on http://localhost:3000 ...'); + let body = new stream.Readable({ + read() { + this.push('

Hello, world!

'); + this.push(null); + }, + }); + + body.pipe(res); }); + +server.listen(PORT); diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 111402f2c76..48c41eb90c7 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -27,6 +27,7 @@ "@types/proxy-addr": "^2.0.3" }, "scripts": { + "bench": "bash ./bench/runner.sh", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", "prepare": "pnpm run build" From e7d05698a31513431a4d30840a48c92ff4b7304e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 12:06:12 -0700 Subject: [PATCH 395/730] Update doc comment --- packages/node-fetch-server/src/lib/request-listener.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index de0337e411b..1021c63fe6d 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -81,7 +81,7 @@ export interface RequestListenerOptions { * * ```ts * import * as http from 'node:http'; - * import { RequestHandler, createRequestListener } from '@mjackson/node-fetch-server'; + * import { type RequestHandler, createRequestListener } from '@mjackson/node-fetch-server'; * * let handler: RequestHandler = async (request) => { * return new Response('Hello, world!'); From c9ada66a0572147720d80ba439b439747f1930f3 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 12:06:23 -0700 Subject: [PATCH 396/730] Small formatting tweak --- packages/multipart-parser/bench/runner.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/multipart-parser/bench/runner.ts b/packages/multipart-parser/bench/runner.ts index 538b81087f0..14f4739784c 100644 --- a/packages/multipart-parser/bench/runner.ts +++ b/packages/multipart-parser/bench/runner.ts @@ -21,8 +21,8 @@ interface Parser { async function runParserBenchmarks( parser: Parser, times = 1000, -): Promise<{ [testName: string]: string }> { - let results: { [testName: string]: string } = {}; +): Promise { + let results: BenchmarkResults[string] = {}; for (let benchmark of benchmarks) { let measurements: number[] = []; @@ -45,7 +45,7 @@ function getMeanAndStdDev(measurements: number[]): string { interface BenchmarkResults { [parserName: string]: { - [testName: string]: string; + [benchmarkName: string]: string; }; } From e28ae20ca78662e682b1c5cada1a849209bebc17 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 12:18:08 -0700 Subject: [PATCH 397/730] Update README --- packages/node-fetch-server/README.md | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/node-fetch-server/README.md b/packages/node-fetch-server/README.md index 30cd3ee760e..04b3324b512 100644 --- a/packages/node-fetch-server/README.md +++ b/packages/node-fetch-server/README.md @@ -1 +1,56 @@ # node-fetch-server + +## Benchmark + +A basic benchmark shows `node-fetch-server` is able to serve more requests per second (and has higher overall throughput) than Express v4. The vanilla `node:http` module is also shown as a baseline for comparison. + +``` +> @mjackson/node-fetch-server@0.1.0 bench /Users/michael/Projects/remix-the-web/packages/node-fetch-server +> bash ./bench/runner.sh + +Platform: Darwin (23.5.0) +CPU: Apple M1 Pro +Date: 8/31/2024, 12:14:41 PM + +Running benchmark for node:http@22.1.0 ... + +Running 30s test @ http://127.0.0.1:3000/ + 12 threads and 400 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 31.70ms 109.12ms 2.00s 98.22% + Req/Sec 1.69k 342.98 2.99k 87.16% + 606083 requests in 30.10s, 124.27MB read + Socket errors: connect 0, read 633, write 117, timeout 20 +Requests/sec: 20135.72 +Transfer/sec: 4.13MB + +Running benchmark for node-fetch-server@0.1.0 ... + +Running 30s test @ http://127.0.0.1:3000/ + 12 threads and 400 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 42.37ms 96.58ms 2.00s 98.66% + Req/Sec 0.94k 255.57 3.01k 81.37% + 333862 requests in 30.10s, 68.46MB read + Socket errors: connect 0, read 419, write 10, timeout 168 +Requests/sec: 11091.24 +Transfer/sec: 2.27MB + +Running benchmark for express@4.19.2 ... + +Running 30s test @ http://127.0.0.1:3000/ + 12 threads and 400 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 48.42ms 95.22ms 2.00s 98.83% + Req/Sec 761.93 191.11 3.98k 79.46% + 272003 requests in 30.10s, 65.63MB read + Socket errors: connect 0, read 835, write 3, timeout 189 +Requests/sec: 9037.72 +Transfer/sec: 2.18MB +``` + +I encourage you to run the benchmark yourself. To do so, you'll need to have [`wrk`](https://github.com/wg/wrk) installed. Then run: + +```sh +pnpm run bench +``` From dc92430e0e1d9fc3bfbc44c276895c4dc06efb2a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 13:55:00 -0700 Subject: [PATCH 398/730] Remove trust proxy logic --- packages/node-fetch-server/package.json | 6 +- .../src/lib/request-listener.ts | 97 +- .../src/lib/request-origin.spec.ts | 70 - .../src/lib/request-origin.ts | 62 - .../src/lib/trust-proxy.spec.ts | 46 - .../node-fetch-server/src/lib/trust-proxy.ts | 17 - .../src/node-fetch-server.ts | 6 +- pnpm-lock.yaml | 3548 +++++------------ 8 files changed, 970 insertions(+), 2882 deletions(-) delete mode 100644 packages/node-fetch-server/src/lib/request-origin.spec.ts delete mode 100644 packages/node-fetch-server/src/lib/request-origin.ts delete mode 100644 packages/node-fetch-server/src/lib/trust-proxy.spec.ts delete mode 100644 packages/node-fetch-server/src/lib/trust-proxy.ts diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 48c41eb90c7..1d23e91f0b0 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -19,12 +19,8 @@ ".": "./dist/node-fetch-server.js", "./package.json": "./package.json" }, - "dependencies": { - "proxy-addr": "^2.0.7" - }, "devDependencies": { - "@types/node": "^22.5.0", - "@types/proxy-addr": "^2.0.3" + "@types/node": "^22.5.0" }, "scripts": { "bench": "bash ./bench/runner.sh", diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 1021c63fe6d..ed8c1448772 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -1,17 +1,33 @@ import * as http from 'node:http'; -import { getRequestOrigin } from './request-origin.js'; -import { TrustArg, createTrustProxy } from './trust-proxy.js'; - /** - * A function that handles an incoming request and returns a response. - * - * [MDN `Request` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Request) - * - * [MDN `Response` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Response) + * Returns the origin of an incoming request URL. */ -export interface FetchHandler { - (request: Request): Response | Promise; +export function getRequestOrigin(req: http.IncomingMessage): string { + let protocol = 'encrypted' in req.socket && req.socket.encrypted ? 'https:' : 'http:'; + let host = req.headers.host ?? 'localhost'; + return `${protocol}//${host}`; +} + +export interface ClientAddr { + /** + * The IP address of the client that sent the request. + * + * [Node.js Reference](https://nodejs.org/api/net.html#socketremoteaddress) + */ + address?: string; + /** + * The family of the IP address of the client that sent the request. Either `'IPv4'` or `'IPv6'`. + * + * [Node.js Reference](https://nodejs.org/api/net.html#socketremotefamily) + */ + family?: string; + /** + * The numeric representation of the remote port of the client that sent the request. + * + * [Node.js Reference](https://nodejs.org/api/net.html#socketremoteport) + */ + port?: number; } /** @@ -24,6 +40,17 @@ export interface ErrorHandler { (error: unknown): Response | void | Promise; } +/** + * A function that handles an incoming request and returns a response. + * + * [MDN `Request` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Request) + * + * [MDN `Response` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Response) + */ +export interface FetchHandler { + (request: Request, client: ClientAddr): Response | Promise; +} + export interface RequestListenerOptions { /** * An error handler that determines the response when the request handler throws an error. By @@ -32,47 +59,9 @@ export interface RequestListenerOptions { onError?: ErrorHandler; /** * Overrides the origin of the incoming request URL. By default the request URL origin is derived - * from the `Host` header and the connection protocol. Additionally, the `X-Forwarded-Proto` and - * `X-Forwarded-Host` headers can be used via the `trustProxy` option to derive the origin from - * HTTP reverse proxy headers. - * - * If `origin` is provided, it will be used as the origin of the request URL and the `Host` - * header, along with any HTTP reverse proxy headers will be ignored. + * from the `Host` header and the connection protocol. */ origin?: string; - /** - * Determines if/how the `X-Forwarded-Proto` and `X-Forwarded-Host` headers should be used to - * derive the request URL. By default these headers are not trusted because they can easily be - * spoofed. But if you're running behind a reverse proxy, you may use this option to allow them - * to be trusted. - * - * To trust a specific server, pass the IP address of the server as a string: - * - * ```ts - * createRequestListener(handler, { trustProxy: '127.0.0.1' }) - * ``` - * - * To trust a list of servers, pass their addresses in a comma-separated list or an array: - * - * ```ts - * createRequestListener(handler, { trustProxy: '127.0.0.1, 169.254.0.0' }) - * createRequestListener(handler, { trustProxy: ['127.0.0.1', '169.254.0.0'] }) - * ``` - * - * Use a subnet mask to trust a range of servers: - * - * ```ts - * // Trust any server on the 127.0.0.x subnet - * createRequestListener(handler, { trustProxy: '127.0.0.0/8' }) - * ``` - * - * To trust all proxy servers, pass `true`. - * - * ```ts - * createRequestListener(handler, { trustProxy: true }) - * ``` - */ - trustProxy?: boolean | TrustArg; } /** @@ -99,15 +88,19 @@ export function createRequestListener( options?: RequestListenerOptions, ): http.RequestListener { let onError = options?.onError ?? defaultErrorHandler; - let trustProxy = createTrustProxy(options?.trustProxy); return async (req, res) => { - let origin = options?.origin ?? getRequestOrigin(req, trustProxy); + let origin = options?.origin ?? getRequestOrigin(req); let url = new URL(req.url!, origin); let request = createRequest(req, res, url); + let client: ClientAddr = { + address: req.socket.remoteAddress, + family: req.socket.remoteFamily, + port: req.socket.remotePort, + }; try { - let response = await handler(request); + let response = await handler(request, client); await sendResponse(res, response); } catch (error) { try { diff --git a/packages/node-fetch-server/src/lib/request-origin.spec.ts b/packages/node-fetch-server/src/lib/request-origin.spec.ts deleted file mode 100644 index a2e7510278a..00000000000 --- a/packages/node-fetch-server/src/lib/request-origin.spec.ts +++ /dev/null @@ -1,70 +0,0 @@ -import * as assert from 'node:assert/strict'; -import { describe, it } from 'node:test'; -import * as http from 'node:http'; - -import { getRequestOrigin } from './request-origin.js'; -import { createTrustProxy } from './trust-proxy.js'; - -describe('getRequestUrl', () => { - it('returns the URL of an incoming request', () => { - let trustProxy = createTrustProxy(); - let req = { - socket: { - encrypted: false, - remoteAddress: '127.0.0.1', - }, - headers: { - host: 'example.com', - }, - } as unknown as http.IncomingMessage; - - assert.equal(getRequestOrigin(req, trustProxy).toString(), 'http://example.com'); - }); - - it('returns the URL of an incoming request on a secure connection', () => { - let trustProxy = createTrustProxy(); - let req = { - socket: { - encrypted: true, - remoteAddress: '127.0.0.1', - }, - headers: { - host: 'example.com', - }, - } as unknown as http.IncomingMessage; - - assert.equal(getRequestOrigin(req, trustProxy).toString(), 'https://example.com'); - }); - - it('returns the URL of an incoming request with a forwarded protocol', () => { - let trustProxy = createTrustProxy(true); - let req = { - socket: { - encrypted: false, - remoteAddress: '127.0.0.1', - }, - headers: { - 'x-forwarded-proto': 'https', - host: 'example.com', - }, - } as unknown as http.IncomingMessage; - - assert.equal(getRequestOrigin(req, trustProxy).toString(), 'https://example.com'); - }); - - it('returns the URL of an incoming request with a forwarded host', () => { - let trustProxy = createTrustProxy(true); - let req = { - socket: { - encrypted: false, - remoteAddress: '127.0.0.1', - }, - headers: { - 'x-forwarded-host': 'mjackson.me', - host: 'example.com', - }, - } as unknown as http.IncomingMessage; - - assert.equal(getRequestOrigin(req, trustProxy).toString(), 'http://mjackson.me'); - }); -}); diff --git a/packages/node-fetch-server/src/lib/request-origin.ts b/packages/node-fetch-server/src/lib/request-origin.ts deleted file mode 100644 index 0cd0728cb5a..00000000000 --- a/packages/node-fetch-server/src/lib/request-origin.ts +++ /dev/null @@ -1,62 +0,0 @@ -import * as http from 'node:http'; -import * as net from 'node:net'; -import * as tls from 'node:tls'; - -import { TrustProxy } from './trust-proxy.js'; - -/** - * Returns the origin of an incoming request. - */ -export function getRequestOrigin(req: http.IncomingMessage, trustProxy: TrustProxy): string { - let protocol = getProtocol(req, trustProxy); - let hostname = getHostname(req, trustProxy); - return `${protocol}//${hostname}`; -} - -function getProtocol(req: http.IncomingMessage, trustProxy: TrustProxy): string { - let socket = req.socket as net.Socket | tls.TLSSocket; - let remoteAddress = socket.remoteAddress; - - let protocol = 'encrypted' in socket && socket.encrypted ? 'https:' : 'http:'; - - if (remoteAddress === undefined || !trustProxy(remoteAddress, 0)) { - return protocol; - } - - let header = req.headers['x-forwarded-proto']; - - if (header === undefined) { - return protocol; - } - - if (Array.isArray(header)) { - header = header[0]; - } - - let index = header.indexOf(','); - - return normalizeProtocol(index === -1 ? header.trim() : header.slice(0, index).trim()); -} - -function normalizeProtocol(protocol: string): string { - return (protocol.endsWith(':') ? protocol : protocol + ':').toLowerCase(); -} - -function getHostname(req: http.IncomingMessage, trustProxy: TrustProxy): string | undefined { - let socket = req.socket as net.Socket | tls.TLSSocket; - let remoteAddress = socket.remoteAddress; - - let header = req.headers['x-forwarded-host']; - - if (header === undefined || remoteAddress === undefined || !trustProxy(remoteAddress, 0)) { - header = req.headers.host; - } else if (Array.isArray(header)) { - header = header[0]; - } - - if (header === undefined) return undefined; - - let index = header.indexOf(','); - - return index === -1 ? header.trim() : header.slice(0, index).trim(); -} diff --git a/packages/node-fetch-server/src/lib/trust-proxy.spec.ts b/packages/node-fetch-server/src/lib/trust-proxy.spec.ts deleted file mode 100644 index 3b5ca0df636..00000000000 --- a/packages/node-fetch-server/src/lib/trust-proxy.spec.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as assert from 'node:assert/strict'; -import { describe, it } from 'node:test'; - -import { createTrustProxy } from './trust-proxy.js'; - -describe('createTrustProxy', () => { - it('does not trust by default', () => { - let trustProxy = createTrustProxy(); - assert.ok(!trustProxy('10.0.0.5', 0)); - }); - - it('trusts all proxies', () => { - let trustProxy = createTrustProxy(true); - assert.ok(trustProxy('10.0.0.5', 0)); - }); - - it('does not trust any proxies', () => { - let trustProxy = createTrustProxy(false); - assert.ok(!trustProxy('10.0.0.5', 0)); - }); - - it('trusts a function that returns true', () => { - let trustProxy = createTrustProxy(() => true); - assert.ok(trustProxy('10.0.0.5', 0)); - }); - - it('does not trust a function that returns false', () => { - let trustProxy = createTrustProxy(() => false); - assert.ok(!trustProxy('10.0.0.5', 0)); - }); - - it('trusts a single IP address', () => { - let trustProxy = createTrustProxy('127.0.0.1'); - assert.ok(trustProxy('127.0.0.1', 0)); - }); - - it('trusts a list of IP addresses', () => { - let trustProxy = createTrustProxy('127.0.0.1,10.0.0.5'); - assert.ok(trustProxy('10.0.0.5', 0)); - }); - - it('trusts a list of IP addresses as an array', () => { - let trustProxy = createTrustProxy(['127.0.0.1', '10.0.0.5']); - assert.ok(trustProxy('10.0.0.5', 0)); - }); -}); diff --git a/packages/node-fetch-server/src/lib/trust-proxy.ts b/packages/node-fetch-server/src/lib/trust-proxy.ts deleted file mode 100644 index fdcd045392a..00000000000 --- a/packages/node-fetch-server/src/lib/trust-proxy.ts +++ /dev/null @@ -1,17 +0,0 @@ -import proxyAddr from 'proxy-addr'; - -export type TrustArg = Parameters[1]; - -export interface TrustProxy { - (addr: string, i: number): boolean; -} - -/** - * Creates a function that determines whether to trust a proxy server. - */ -export function createTrustProxy(trustArg?: boolean | TrustArg): TrustProxy { - if (typeof trustArg === 'boolean') return () => trustArg as boolean; - if (typeof trustArg === 'function') return trustArg; - if (typeof trustArg === 'string') trustArg = trustArg.split(',').map((s) => s.trim()); - return proxyAddr.compile(trustArg || []); -} diff --git a/packages/node-fetch-server/src/node-fetch-server.ts b/packages/node-fetch-server/src/node-fetch-server.ts index 01609e47854..48961a2588a 100644 --- a/packages/node-fetch-server/src/node-fetch-server.ts +++ b/packages/node-fetch-server/src/node-fetch-server.ts @@ -1,8 +1,8 @@ export { - type FetchHandler, + type ClientAddr, type ErrorHandler, + type FetchHandler, type RequestListenerOptions, + getRequestOrigin, createRequestListener, } from './lib/request-listener.js'; -export { getRequestOrigin } from './lib/request-origin.js'; -export { createTrustProxy } from './lib/trust-proxy.js'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cfb2085c849..e34d758fc36 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,7 @@ settings: excludeLinksFromLockfile: false importers: + .: devDependencies: '@nx/js': @@ -159,17 +160,10 @@ importers: version: 0.2.6 packages/node-fetch-server: - dependencies: - proxy-addr: - specifier: ^2.0.7 - version: 2.0.7 devDependencies: '@types/node': specifier: ^22.5.0 version: 22.5.0 - '@types/proxy-addr': - specifier: ^2.0.3 - version: 2.0.3 packages/node-fetch-server/bench: dependencies: @@ -185,1412 +179,897 @@ importers: version: 4.17.21 packages: + '@ampproject/remapping@2.3.0': - resolution: - { - integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==, - } - engines: { node: '>=6.0.0' } + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} '@babel/code-frame@7.24.7': - resolution: - { - integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} '@babel/compat-data@7.25.4': - resolution: - { - integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==} + engines: {node: '>=6.9.0'} '@babel/core@7.25.2': - resolution: - { - integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} + engines: {node: '>=6.9.0'} '@babel/generator@7.25.5': - resolution: - { - integrity: sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==} + engines: {node: '>=6.9.0'} '@babel/helper-annotate-as-pure@7.24.7': - resolution: - { - integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} + engines: {node: '>=6.9.0'} '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': - resolution: - { - integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==} + engines: {node: '>=6.9.0'} '@babel/helper-compilation-targets@7.25.2': - resolution: - { - integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} + engines: {node: '>=6.9.0'} '@babel/helper-create-class-features-plugin@7.25.4': - resolution: - { - integrity: sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/helper-create-regexp-features-plugin@7.25.2': - resolution: - { - integrity: sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/helper-define-polyfill-provider@0.6.2': - resolution: - { - integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==, - } + resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 '@babel/helper-member-expression-to-functions@7.24.8': - resolution: - { - integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==} + engines: {node: '>=6.9.0'} '@babel/helper-module-imports@7.24.7': - resolution: - { - integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} '@babel/helper-module-transforms@7.25.2': - resolution: - { - integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/helper-optimise-call-expression@7.24.7': - resolution: - { - integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} + engines: {node: '>=6.9.0'} '@babel/helper-plugin-utils@7.24.8': - resolution: - { - integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} + engines: {node: '>=6.9.0'} '@babel/helper-remap-async-to-generator@7.25.0': - resolution: - { - integrity: sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/helper-replace-supers@7.25.0': - resolution: - { - integrity: sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/helper-simple-access@7.24.7': - resolution: - { - integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} + engines: {node: '>=6.9.0'} '@babel/helper-skip-transparent-expression-wrappers@7.24.7': - resolution: - { - integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} + engines: {node: '>=6.9.0'} '@babel/helper-string-parser@7.24.8': - resolution: - { - integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + engines: {node: '>=6.9.0'} '@babel/helper-validator-identifier@7.24.7': - resolution: - { - integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} '@babel/helper-validator-option@7.24.8': - resolution: - { - integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} + engines: {node: '>=6.9.0'} '@babel/helper-wrap-function@7.25.0': - resolution: - { - integrity: sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==} + engines: {node: '>=6.9.0'} '@babel/helpers@7.25.0': - resolution: - { - integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} + engines: {node: '>=6.9.0'} '@babel/highlight@7.24.7': - resolution: - { - integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} '@babel/parser@7.25.4': - resolution: - { - integrity: sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==, - } - engines: { node: '>=6.0.0' } + resolution: {integrity: sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==} + engines: {node: '>=6.0.0'} hasBin: true '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.3': - resolution: - { - integrity: sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.0': - resolution: - { - integrity: sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.0': - resolution: - { - integrity: sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7': - resolution: - { - integrity: sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.0': - resolution: - { - integrity: sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/plugin-proposal-decorators@7.24.7': - resolution: - { - integrity: sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': - resolution: - { - integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-async-generators@7.8.4': - resolution: - { - integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==, - } + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-class-properties@7.12.13': - resolution: - { - integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==, - } + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-class-static-block@7.14.5': - resolution: - { - integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-decorators@7.24.7': - resolution: - { - integrity: sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-dynamic-import@7.8.3': - resolution: - { - integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==, - } + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-export-namespace-from@7.8.3': - resolution: - { - integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==, - } + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-import-assertions@7.24.7': - resolution: - { - integrity: sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-import-attributes@7.24.7': - resolution: - { - integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-import-meta@7.10.4': - resolution: - { - integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==, - } + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-json-strings@7.8.3': - resolution: - { - integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==, - } + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-jsx@7.24.7': - resolution: - { - integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-logical-assignment-operators@7.10.4': - resolution: - { - integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==, - } + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': - resolution: - { - integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==, - } + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-numeric-separator@7.10.4': - resolution: - { - integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==, - } + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-object-rest-spread@7.8.3': - resolution: - { - integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==, - } + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-optional-catch-binding@7.8.3': - resolution: - { - integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==, - } + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-optional-chaining@7.8.3': - resolution: - { - integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==, - } + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-private-property-in-object@7.14.5': - resolution: - { - integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-top-level-await@7.14.5': - resolution: - { - integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-typescript@7.25.4': - resolution: - { - integrity: sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-unicode-sets-regex@7.18.6': - resolution: - { - integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/plugin-transform-arrow-functions@7.24.7': - resolution: - { - integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-async-generator-functions@7.25.4': - resolution: - { - integrity: sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-async-to-generator@7.24.7': - resolution: - { - integrity: sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-block-scoped-functions@7.24.7': - resolution: - { - integrity: sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-block-scoping@7.25.0': - resolution: - { - integrity: sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-class-properties@7.25.4': - resolution: - { - integrity: sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-class-static-block@7.24.7': - resolution: - { - integrity: sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 '@babel/plugin-transform-classes@7.25.4': - resolution: - { - integrity: sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-computed-properties@7.24.7': - resolution: - { - integrity: sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-destructuring@7.24.8': - resolution: - { - integrity: sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-dotall-regex@7.24.7': - resolution: - { - integrity: sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-duplicate-keys@7.24.7': - resolution: - { - integrity: sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.0': - resolution: - { - integrity: sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/plugin-transform-dynamic-import@7.24.7': - resolution: - { - integrity: sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-exponentiation-operator@7.24.7': - resolution: - { - integrity: sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-export-namespace-from@7.24.7': - resolution: - { - integrity: sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-for-of@7.24.7': - resolution: - { - integrity: sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-function-name@7.25.1': - resolution: - { - integrity: sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-json-strings@7.24.7': - resolution: - { - integrity: sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-literals@7.25.2': - resolution: - { - integrity: sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-logical-assignment-operators@7.24.7': - resolution: - { - integrity: sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-member-expression-literals@7.24.7': - resolution: - { - integrity: sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-modules-amd@7.24.7': - resolution: - { - integrity: sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-modules-commonjs@7.24.8': - resolution: - { - integrity: sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-modules-systemjs@7.25.0': - resolution: - { - integrity: sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-modules-umd@7.24.7': - resolution: - { - integrity: sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-named-capturing-groups-regex@7.24.7': - resolution: - { - integrity: sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/plugin-transform-new-target@7.24.7': - resolution: - { - integrity: sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-nullish-coalescing-operator@7.24.7': - resolution: - { - integrity: sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-numeric-separator@7.24.7': - resolution: - { - integrity: sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-object-rest-spread@7.24.7': - resolution: - { - integrity: sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-object-super@7.24.7': - resolution: - { - integrity: sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-optional-catch-binding@7.24.7': - resolution: - { - integrity: sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-optional-chaining@7.24.8': - resolution: - { - integrity: sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-parameters@7.24.7': - resolution: - { - integrity: sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-private-methods@7.25.4': - resolution: - { - integrity: sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-private-property-in-object@7.24.7': - resolution: - { - integrity: sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-property-literals@7.24.7': - resolution: - { - integrity: sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-regenerator@7.24.7': - resolution: - { - integrity: sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-reserved-words@7.24.7': - resolution: - { - integrity: sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-runtime@7.25.4': - resolution: - { - integrity: sha512-8hsyG+KUYGY0coX6KUCDancA0Vw225KJ2HJO0yCNr1vq5r+lJTleDaJf0K7iOhjw4SWhu03TMBzYTJ9krmzULQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-8hsyG+KUYGY0coX6KUCDancA0Vw225KJ2HJO0yCNr1vq5r+lJTleDaJf0K7iOhjw4SWhu03TMBzYTJ9krmzULQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-shorthand-properties@7.24.7': - resolution: - { - integrity: sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-spread@7.24.7': - resolution: - { - integrity: sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-sticky-regex@7.24.7': - resolution: - { - integrity: sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-template-literals@7.24.7': - resolution: - { - integrity: sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-typeof-symbol@7.24.8': - resolution: - { - integrity: sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-typescript@7.25.2': - resolution: - { - integrity: sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-unicode-escapes@7.24.7': - resolution: - { - integrity: sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-unicode-property-regex@7.24.7': - resolution: - { - integrity: sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-unicode-regex@7.24.7': - resolution: - { - integrity: sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-unicode-sets-regex@7.25.4': - resolution: - { - integrity: sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/preset-env@7.25.4': - resolution: - { - integrity: sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/preset-modules@0.1.6-no-external-plugins': - resolution: - { - integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==, - } + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 '@babel/preset-typescript@7.24.7': - resolution: - { - integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/regjsgen@0.8.0': - resolution: - { - integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==, - } + resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} '@babel/runtime@7.25.4': - resolution: - { - integrity: sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==} + engines: {node: '>=6.9.0'} '@babel/template@7.25.0': - resolution: - { - integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} + engines: {node: '>=6.9.0'} '@babel/traverse@7.25.4': - resolution: - { - integrity: sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==} + engines: {node: '>=6.9.0'} '@babel/types@7.25.4': - resolution: - { - integrity: sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==} + engines: {node: '>=6.9.0'} '@cloudflare/kv-asset-handler@0.3.4': - resolution: - { - integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==, - } - engines: { node: '>=16.13' } + resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} + engines: {node: '>=16.13'} '@cloudflare/workerd-darwin-64@1.20240821.1': - resolution: - { - integrity: sha512-CDBpfZKrSy4YrIdqS84z67r3Tzal2pOhjCsIb63IuCnvVes59/ft1qhczBzk9EffeOE2iTCrA4YBT7Sbn7USew==, - } - engines: { node: '>=16' } + resolution: {integrity: sha512-CDBpfZKrSy4YrIdqS84z67r3Tzal2pOhjCsIb63IuCnvVes59/ft1qhczBzk9EffeOE2iTCrA4YBT7Sbn7USew==} + engines: {node: '>=16'} cpu: [x64] os: [darwin] '@cloudflare/workerd-darwin-arm64@1.20240821.1': - resolution: - { - integrity: sha512-Q+9RedvNbPcEt/dKni1oN94OxbvuNAeJkgHmrLFTGF8zu21wzOhVkQeRNxcYxrMa9mfStc457NAg13OVCj2kHQ==, - } - engines: { node: '>=16' } + resolution: {integrity: sha512-Q+9RedvNbPcEt/dKni1oN94OxbvuNAeJkgHmrLFTGF8zu21wzOhVkQeRNxcYxrMa9mfStc457NAg13OVCj2kHQ==} + engines: {node: '>=16'} cpu: [arm64] os: [darwin] '@cloudflare/workerd-linux-64@1.20240821.1': - resolution: - { - integrity: sha512-j6z3KsPtawrscoLuP985LbqFrmsJL6q1mvSXOXTqXGODAHIzGBipHARdOjms3UQqovzvqB2lQaQsZtLBwCZxtA==, - } - engines: { node: '>=16' } + resolution: {integrity: sha512-j6z3KsPtawrscoLuP985LbqFrmsJL6q1mvSXOXTqXGODAHIzGBipHARdOjms3UQqovzvqB2lQaQsZtLBwCZxtA==} + engines: {node: '>=16'} cpu: [x64] os: [linux] '@cloudflare/workerd-linux-arm64@1.20240821.1': - resolution: - { - integrity: sha512-I9bHgZOxJQW0CV5gTdilyxzTG7ILzbTirehQWgfPx9X77E/7eIbR9sboOMgyeC69W4he0SKtpx0sYZuTJu4ERw==, - } - engines: { node: '>=16' } + resolution: {integrity: sha512-I9bHgZOxJQW0CV5gTdilyxzTG7ILzbTirehQWgfPx9X77E/7eIbR9sboOMgyeC69W4he0SKtpx0sYZuTJu4ERw==} + engines: {node: '>=16'} cpu: [arm64] os: [linux] '@cloudflare/workerd-windows-64@1.20240821.1': - resolution: - { - integrity: sha512-keC97QPArs6LWbPejQM7/Y8Jy8QqyaZow4/ZdsGo+QjlOLiZRDpAenfZx3CBUoWwEeFwQTl2FLO+8hV1SWFFYw==, - } - engines: { node: '>=16' } + resolution: {integrity: sha512-keC97QPArs6LWbPejQM7/Y8Jy8QqyaZow4/ZdsGo+QjlOLiZRDpAenfZx3CBUoWwEeFwQTl2FLO+8hV1SWFFYw==} + engines: {node: '>=16'} cpu: [x64] os: [win32] '@cloudflare/workers-shared@0.4.0': - resolution: - { - integrity: sha512-XAFOldVQsbxQ7mjbqX2q1dNIgcLbKSytk41pwuZTn9e0p7OeTpFTosJef8uwosL6CcOAHqcW1f1HJxyjwmtGxw==, - } - engines: { node: '>=16.7.0' } + resolution: {integrity: sha512-XAFOldVQsbxQ7mjbqX2q1dNIgcLbKSytk41pwuZTn9e0p7OeTpFTosJef8uwosL6CcOAHqcW1f1HJxyjwmtGxw==} + engines: {node: '>=16.7.0'} '@cloudflare/workers-types@4.20240821.1': - resolution: - { - integrity: sha512-icAkbnAqgVl6ef9lgLTom8na+kj2RBw2ViPAQ586hbdj0xZcnrjK7P46Eu08OU9D/lNDgN2sKU/sxhe2iK/gIg==, - } + resolution: {integrity: sha512-icAkbnAqgVl6ef9lgLTom8na+kj2RBw2ViPAQ586hbdj0xZcnrjK7P46Eu08OU9D/lNDgN2sKU/sxhe2iK/gIg==} '@cspotcode/source-map-support@0.8.1': - resolution: - { - integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} '@emnapi/core@1.2.0': - resolution: - { - integrity: sha512-E7Vgw78I93we4ZWdYCb4DGAwRROGkMIXk7/y87UmANR+J6qsWusmC3gLt0H+O0KOt5e6O38U8oJamgbudrES/w==, - } + resolution: {integrity: sha512-E7Vgw78I93we4ZWdYCb4DGAwRROGkMIXk7/y87UmANR+J6qsWusmC3gLt0H+O0KOt5e6O38U8oJamgbudrES/w==} '@emnapi/runtime@1.2.0': - resolution: - { - integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==, - } + resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==} '@emnapi/wasi-threads@1.0.1': - resolution: - { - integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==, - } + resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} '@esbuild-plugins/node-globals-polyfill@0.2.3': - resolution: - { - integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==, - } + resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} peerDependencies: esbuild: '*' '@esbuild-plugins/node-modules-polyfill@0.2.2': - resolution: - { - integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==, - } + resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} peerDependencies: esbuild: '*' '@esbuild/android-arm64@0.17.19': - resolution: - { - integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} + engines: {node: '>=12'} cpu: [arm64] os: [android] '@esbuild/android-arm@0.17.19': - resolution: - { - integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} + engines: {node: '>=12'} cpu: [arm] os: [android] '@esbuild/android-x64@0.17.19': - resolution: - { - integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} + engines: {node: '>=12'} cpu: [x64] os: [android] '@esbuild/darwin-arm64@0.17.19': - resolution: - { - integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} + engines: {node: '>=12'} cpu: [arm64] os: [darwin] '@esbuild/darwin-x64@0.17.19': - resolution: - { - integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} + engines: {node: '>=12'} cpu: [x64] os: [darwin] '@esbuild/freebsd-arm64@0.17.19': - resolution: - { - integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} + engines: {node: '>=12'} cpu: [arm64] os: [freebsd] '@esbuild/freebsd-x64@0.17.19': - resolution: - { - integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} + engines: {node: '>=12'} cpu: [x64] os: [freebsd] '@esbuild/linux-arm64@0.17.19': - resolution: - { - integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} + engines: {node: '>=12'} cpu: [arm64] os: [linux] '@esbuild/linux-arm@0.17.19': - resolution: - { - integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} + engines: {node: '>=12'} cpu: [arm] os: [linux] '@esbuild/linux-ia32@0.17.19': - resolution: - { - integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} + engines: {node: '>=12'} cpu: [ia32] os: [linux] '@esbuild/linux-loong64@0.17.19': - resolution: - { - integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} + engines: {node: '>=12'} cpu: [loong64] os: [linux] '@esbuild/linux-mips64el@0.17.19': - resolution: - { - integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} + engines: {node: '>=12'} cpu: [mips64el] os: [linux] '@esbuild/linux-ppc64@0.17.19': - resolution: - { - integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} + engines: {node: '>=12'} cpu: [ppc64] os: [linux] '@esbuild/linux-riscv64@0.17.19': - resolution: - { - integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} + engines: {node: '>=12'} cpu: [riscv64] os: [linux] '@esbuild/linux-s390x@0.17.19': - resolution: - { - integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} + engines: {node: '>=12'} cpu: [s390x] os: [linux] '@esbuild/linux-x64@0.17.19': - resolution: - { - integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} + engines: {node: '>=12'} cpu: [x64] os: [linux] '@esbuild/netbsd-x64@0.17.19': - resolution: - { - integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} + engines: {node: '>=12'} cpu: [x64] os: [netbsd] '@esbuild/openbsd-x64@0.17.19': - resolution: - { - integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} + engines: {node: '>=12'} cpu: [x64] os: [openbsd] '@esbuild/sunos-x64@0.17.19': - resolution: - { - integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} + engines: {node: '>=12'} cpu: [x64] os: [sunos] '@esbuild/win32-arm64@0.17.19': - resolution: - { - integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} + engines: {node: '>=12'} cpu: [arm64] os: [win32] '@esbuild/win32-ia32@0.17.19': - resolution: - { - integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} + engines: {node: '>=12'} cpu: [ia32] os: [win32] '@esbuild/win32-x64@0.17.19': - resolution: - { - integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} + engines: {node: '>=12'} cpu: [x64] os: [win32] '@fastify/busboy@2.1.1': - resolution: - { - integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==, - } - engines: { node: '>=14' } + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} '@fastify/busboy@3.0.0': - resolution: - { - integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==, - } + resolution: {integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==} '@jest/schemas@29.6.3': - resolution: - { - integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} '@jridgewell/gen-mapping@0.3.5': - resolution: - { - integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==, - } - engines: { node: '>=6.0.0' } + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} '@jridgewell/resolve-uri@3.1.2': - resolution: - { - integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, - } - engines: { node: '>=6.0.0' } + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} '@jridgewell/set-array@1.2.1': - resolution: - { - integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==, - } - engines: { node: '>=6.0.0' } + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} '@jridgewell/sourcemap-codec@1.5.0': - resolution: - { - integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==, - } + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} '@jridgewell/trace-mapping@0.3.25': - resolution: - { - integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==, - } + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} '@jridgewell/trace-mapping@0.3.9': - resolution: - { - integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==, - } + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} '@mjackson/headers@0.5.1': - resolution: - { - integrity: sha512-sJpFgecPT/zJvwk3GRNVWNs8EkwaJoUNU2D0VMlp+gDJs6cuSTm1q/aCZi3ZtuV6CgDEQ4l2ZjUG3A9JrQlbNA==, - } + resolution: {integrity: sha512-sJpFgecPT/zJvwk3GRNVWNs8EkwaJoUNU2D0VMlp+gDJs6cuSTm1q/aCZi3ZtuV6CgDEQ4l2ZjUG3A9JrQlbNA==} '@mjackson/lazy-file@2.2.0': - resolution: - { - integrity: sha512-51M2TAL5eMZj5mh1e22/qBl4C5udViZqSBEqwiHSi1lTAixCp4YiAOV62VaTSqVp771OkmgNCPsh8/LpJ/A/Yw==, - } + resolution: {integrity: sha512-51M2TAL5eMZj5mh1e22/qBl4C5udViZqSBEqwiHSi1lTAixCp4YiAOV62VaTSqVp771OkmgNCPsh8/LpJ/A/Yw==} '@mjackson/multipart-parser@0.6.2': - resolution: - { - integrity: sha512-xG3mINK6gFVposxu83x3n4ueJfjWoxOl3UaBADXNjh/NL84L+Zc/kmz2mTQA9GHvHFPAMlXqPSLTocIDkmhemQ==, - } + resolution: {integrity: sha512-xG3mINK6gFVposxu83x3n4ueJfjWoxOl3UaBADXNjh/NL84L+Zc/kmz2mTQA9GHvHFPAMlXqPSLTocIDkmhemQ==} '@napi-rs/wasm-runtime@0.2.4': - resolution: - { - integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==, - } + resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} '@nodelib/fs.scandir@2.1.5': - resolution: - { - integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, - } - engines: { node: '>= 8' } + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} '@nodelib/fs.stat@2.0.5': - resolution: - { - integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, - } - engines: { node: '>= 8' } + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} '@nodelib/fs.walk@1.2.8': - resolution: - { - integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, - } - engines: { node: '>= 8' } + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} '@nrwl/devkit@19.6.4': - resolution: - { - integrity: sha512-jpr+T5/+21W/fwAMB6zDLZKO+ReYAfOOMIeM8CpeBi/r9nWmjGXaXN9YKwEOYS1fath62Y5ldGK4yZUttv1tkw==, - } + resolution: {integrity: sha512-jpr+T5/+21W/fwAMB6zDLZKO+ReYAfOOMIeM8CpeBi/r9nWmjGXaXN9YKwEOYS1fath62Y5ldGK4yZUttv1tkw==} '@nrwl/js@19.6.4': - resolution: - { - integrity: sha512-yjxxSRST/lWylw4SO1qILg9oiKlBbcVst1nVFZzneTFo2oNuFVSEhluVh5tZ0bz3GZ1RPtHxjiBuWDwQ/QmmAA==, - } + resolution: {integrity: sha512-yjxxSRST/lWylw4SO1qILg9oiKlBbcVst1nVFZzneTFo2oNuFVSEhluVh5tZ0bz3GZ1RPtHxjiBuWDwQ/QmmAA==} '@nrwl/tao@19.6.4': - resolution: - { - integrity: sha512-1J8cD+MFzsmboiGe03VlQZ8gt64k/TaYYPZivnnhOJolPPs75nz1JyJX55uWcKKRy/b7FZNKWIu/6Wp9JDhJrQ==, - } + resolution: {integrity: sha512-1J8cD+MFzsmboiGe03VlQZ8gt64k/TaYYPZivnnhOJolPPs75nz1JyJX55uWcKKRy/b7FZNKWIu/6Wp9JDhJrQ==} hasBin: true '@nrwl/workspace@19.6.4': - resolution: - { - integrity: sha512-jjqtRjm5AP39s8oPUEehA6O0Zew6BeTi+Uhjb+ggqbFKH9R9hoSITnbJY670WlO4W8yWYxT8isPf1TNdSHkmBw==, - } + resolution: {integrity: sha512-jjqtRjm5AP39s8oPUEehA6O0Zew6BeTi+Uhjb+ggqbFKH9R9hoSITnbJY670WlO4W8yWYxT8isPf1TNdSHkmBw==} '@nx/devkit@19.6.4': - resolution: - { - integrity: sha512-mBitFwb/gcz8MR7STt7KQG0vf+QcsasDXiSYcf3OWpc6lGE5wn1q5jg6Iabp49Bd/mdHXVLQnP1aV5A+QqFIOQ==, - } + resolution: {integrity: sha512-mBitFwb/gcz8MR7STt7KQG0vf+QcsasDXiSYcf3OWpc6lGE5wn1q5jg6Iabp49Bd/mdHXVLQnP1aV5A+QqFIOQ==} peerDependencies: nx: '>= 17 <= 20' '@nx/js@19.6.4': - resolution: - { - integrity: sha512-Z09whMis90on3/5V0RIG1On5bRlNI4q2SGZQmj530+BqRTNdKNqxuYdpGf3oNbw5cgLVGiHcWtHzZROaAzpc4g==, - } + resolution: {integrity: sha512-Z09whMis90on3/5V0RIG1On5bRlNI4q2SGZQmj530+BqRTNdKNqxuYdpGf3oNbw5cgLVGiHcWtHzZROaAzpc4g==} peerDependencies: verdaccio: ^5.0.4 peerDependenciesMeta: @@ -1598,316 +1077,205 @@ packages: optional: true '@nx/nx-darwin-arm64@19.6.4': - resolution: - { - integrity: sha512-kRn2FLvhwJA/TJrNlsCSqqQTrguNZLmiRsiXhvjkfUMbUKwyQfVMgJlvkZ+KoqraUSG+Qyb0FmrGur1I/Mld0Q==, - } - engines: { node: '>= 10' } + resolution: {integrity: sha512-kRn2FLvhwJA/TJrNlsCSqqQTrguNZLmiRsiXhvjkfUMbUKwyQfVMgJlvkZ+KoqraUSG+Qyb0FmrGur1I/Mld0Q==} + engines: {node: '>= 10'} cpu: [arm64] os: [darwin] '@nx/nx-darwin-x64@19.6.4': - resolution: - { - integrity: sha512-3uABBUhxVk+SdRwpUu30iuBlgRWm3tA/G9seG+wt7oN2R+fOu8zzRCYa+Blvoh1Ef+D9743Ir4rDc9Mhzl2B2g==, - } - engines: { node: '>= 10' } + resolution: {integrity: sha512-3uABBUhxVk+SdRwpUu30iuBlgRWm3tA/G9seG+wt7oN2R+fOu8zzRCYa+Blvoh1Ef+D9743Ir4rDc9Mhzl2B2g==} + engines: {node: '>= 10'} cpu: [x64] os: [darwin] '@nx/nx-freebsd-x64@19.6.4': - resolution: - { - integrity: sha512-OG83MiEk5L54/vAldmwZJBKEvZaM+DEIDqn2yZLTToBRj5Z9jwKJX3jKP60xbHiaT/hzsb1xPlwhOHJnYd80EQ==, - } - engines: { node: '>= 10' } + resolution: {integrity: sha512-OG83MiEk5L54/vAldmwZJBKEvZaM+DEIDqn2yZLTToBRj5Z9jwKJX3jKP60xbHiaT/hzsb1xPlwhOHJnYd80EQ==} + engines: {node: '>= 10'} cpu: [x64] os: [freebsd] '@nx/nx-linux-arm-gnueabihf@19.6.4': - resolution: - { - integrity: sha512-hQ9x4qSKUh9mIVDuD270ULrBnmYfDTjXq7LnIwECw1AuP4LkKzKxULhsbqVnFQ/k3xxyFkwyGTIu2mfDcw16Gw==, - } - engines: { node: '>= 10' } + resolution: {integrity: sha512-hQ9x4qSKUh9mIVDuD270ULrBnmYfDTjXq7LnIwECw1AuP4LkKzKxULhsbqVnFQ/k3xxyFkwyGTIu2mfDcw16Gw==} + engines: {node: '>= 10'} cpu: [arm] os: [linux] '@nx/nx-linux-arm64-gnu@19.6.4': - resolution: - { - integrity: sha512-OFKpAHiaVg3YGFIMBmi/JshciP9buwtOPiHDXcQdzQgE22jyYzKEiFxfcpG0nCT8PlMYAbHPAda15WfWkfVGVQ==, - } - engines: { node: '>= 10' } + resolution: {integrity: sha512-OFKpAHiaVg3YGFIMBmi/JshciP9buwtOPiHDXcQdzQgE22jyYzKEiFxfcpG0nCT8PlMYAbHPAda15WfWkfVGVQ==} + engines: {node: '>= 10'} cpu: [arm64] os: [linux] '@nx/nx-linux-arm64-musl@19.6.4': - resolution: - { - integrity: sha512-ZIR9u+mN0A7SmNd6vDxmPV1QVTgYPTdfBSM5TEnKl3q2fHw2Nkui81QBxA4d7VopJoJUz/pRHiUV+dlgEEZ6nA==, - } - engines: { node: '>= 10' } + resolution: {integrity: sha512-ZIR9u+mN0A7SmNd6vDxmPV1QVTgYPTdfBSM5TEnKl3q2fHw2Nkui81QBxA4d7VopJoJUz/pRHiUV+dlgEEZ6nA==} + engines: {node: '>= 10'} cpu: [arm64] os: [linux] '@nx/nx-linux-x64-gnu@19.6.4': - resolution: - { - integrity: sha512-AUMPvLs9KeCUuWD5DdlpbP3VfVsiD0IlptS2b3ul336rsQ7LwwdvE7jTVO5CixFOsiRZxP72fKJhaEargMn5Aw==, - } - engines: { node: '>= 10' } + resolution: {integrity: sha512-AUMPvLs9KeCUuWD5DdlpbP3VfVsiD0IlptS2b3ul336rsQ7LwwdvE7jTVO5CixFOsiRZxP72fKJhaEargMn5Aw==} + engines: {node: '>= 10'} cpu: [x64] os: [linux] '@nx/nx-linux-x64-musl@19.6.4': - resolution: - { - integrity: sha512-PU7AaBlrgnJnDxTiV/PNCu0pHUCzaogm6uNcbzCyFJLGn7DoQK9rkqUMPJjb3CnJkAj9XrrhuZwmOdbrhvHAvA==, - } - engines: { node: '>= 10' } + resolution: {integrity: sha512-PU7AaBlrgnJnDxTiV/PNCu0pHUCzaogm6uNcbzCyFJLGn7DoQK9rkqUMPJjb3CnJkAj9XrrhuZwmOdbrhvHAvA==} + engines: {node: '>= 10'} cpu: [x64] os: [linux] '@nx/nx-win32-arm64-msvc@19.6.4': - resolution: - { - integrity: sha512-6CCmGWwH/J2k+Uxeci48w4QVhtcQ3hRZ5Z2jh26HI8YzH4wqZyA7QPgLBE6sNCPVLoGW5cBgTsfnyEdr+xarQA==, - } - engines: { node: '>= 10' } + resolution: {integrity: sha512-6CCmGWwH/J2k+Uxeci48w4QVhtcQ3hRZ5Z2jh26HI8YzH4wqZyA7QPgLBE6sNCPVLoGW5cBgTsfnyEdr+xarQA==} + engines: {node: '>= 10'} cpu: [arm64] os: [win32] '@nx/nx-win32-x64-msvc@19.6.4': - resolution: - { - integrity: sha512-jTNrlaFaKtbL2mYOcfPAiljtpF5CI7vbHIqYqBFYLUQXOwW9lOHlO+SeQnft6JYZs0FIr1IdHaCfdOw/hpnCiQ==, - } - engines: { node: '>= 10' } + resolution: {integrity: sha512-jTNrlaFaKtbL2mYOcfPAiljtpF5CI7vbHIqYqBFYLUQXOwW9lOHlO+SeQnft6JYZs0FIr1IdHaCfdOw/hpnCiQ==} + engines: {node: '>= 10'} cpu: [x64] os: [win32] '@nx/workspace@19.6.4': - resolution: - { - integrity: sha512-SMrI03OmjYm93XpDTlIWgAyIaEhToN4LNu4cxOXW9ygpzPe8HJlqR18aTaCqu1T+BY8XeaZ8BQ7qYS1kEjM9YA==, - } + resolution: {integrity: sha512-SMrI03OmjYm93XpDTlIWgAyIaEhToN4LNu4cxOXW9ygpzPe8HJlqR18aTaCqu1T+BY8XeaZ8BQ7qYS1kEjM9YA==} '@oxc-resolver/binding-darwin-arm64@1.11.0': - resolution: - { - integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==, - } + resolution: {integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==} cpu: [arm64] os: [darwin] '@oxc-resolver/binding-darwin-x64@1.11.0': - resolution: - { - integrity: sha512-w/svTRKnuRinojYAVsWRozVoPar7XUPlJhpfnsYlReRjls6A53/ziTzHfpmcKjdBrP/AXPcDVJDnM4pOSsvWvA==, - } + resolution: {integrity: sha512-w/svTRKnuRinojYAVsWRozVoPar7XUPlJhpfnsYlReRjls6A53/ziTzHfpmcKjdBrP/AXPcDVJDnM4pOSsvWvA==} cpu: [x64] os: [darwin] '@oxc-resolver/binding-freebsd-x64@1.11.0': - resolution: - { - integrity: sha512-thGp8g8maYUx7vYJqD0vSsuUO95vWNJwKS2AXchq212J5dQ0Dybq4gjt2O2N9iU+lxj1QzmIDXGw7q5HCagOiw==, - } + resolution: {integrity: sha512-thGp8g8maYUx7vYJqD0vSsuUO95vWNJwKS2AXchq212J5dQ0Dybq4gjt2O2N9iU+lxj1QzmIDXGw7q5HCagOiw==} cpu: [x64] os: [freebsd] '@oxc-resolver/binding-linux-arm-gnueabihf@1.11.0': - resolution: - { - integrity: sha512-8G99bs4cnwpJRjRK2cEJXiJVyLogzPJq4JgLlcMEKSGhdkoMV1Ia0dghLk9lAFog33U4lWIwKmPgqQzTO6JM8g==, - } + resolution: {integrity: sha512-8G99bs4cnwpJRjRK2cEJXiJVyLogzPJq4JgLlcMEKSGhdkoMV1Ia0dghLk9lAFog33U4lWIwKmPgqQzTO6JM8g==} cpu: [arm] os: [linux] '@oxc-resolver/binding-linux-arm64-gnu@1.11.0': - resolution: - { - integrity: sha512-hNcB/wbuCFbsspg4h9+Nz5gSL8PbRW7zG/eVvmEpzGhmVubzDFuNmlYtmaUaZ6b9jzOrrqTkYCt9t7Q2TDHnBA==, - } + resolution: {integrity: sha512-hNcB/wbuCFbsspg4h9+Nz5gSL8PbRW7zG/eVvmEpzGhmVubzDFuNmlYtmaUaZ6b9jzOrrqTkYCt9t7Q2TDHnBA==} cpu: [arm64] os: [linux] '@oxc-resolver/binding-linux-arm64-musl@1.11.0': - resolution: - { - integrity: sha512-H9rjqCcNQT9aip1VLrtsiyj9So0DEKUoutMNu1oL9UuD3H5lWIaxhDlHTAFsobWeUHCnuaCbizhGb9wyLRHSuA==, - } + resolution: {integrity: sha512-H9rjqCcNQT9aip1VLrtsiyj9So0DEKUoutMNu1oL9UuD3H5lWIaxhDlHTAFsobWeUHCnuaCbizhGb9wyLRHSuA==} cpu: [arm64] os: [linux] '@oxc-resolver/binding-linux-x64-gnu@1.11.0': - resolution: - { - integrity: sha512-6hdv/kmaGysK3/hUaGTYG07yX+nvk6hGoWombmOuc0vBnGLRtSjqvvgDBdAs9/iIcOSQI2YNUEiJvTyy6eb5GA==, - } + resolution: {integrity: sha512-6hdv/kmaGysK3/hUaGTYG07yX+nvk6hGoWombmOuc0vBnGLRtSjqvvgDBdAs9/iIcOSQI2YNUEiJvTyy6eb5GA==} cpu: [x64] os: [linux] '@oxc-resolver/binding-linux-x64-musl@1.11.0': - resolution: - { - integrity: sha512-AYUvI4VwQkBq0rcYI3Z7a9+BpllbllbxQCD30ZRgHghvqXvDECWfP8r98iynz7u0oKGO8ZPf15d/l9VrkRtiuQ==, - } + resolution: {integrity: sha512-AYUvI4VwQkBq0rcYI3Z7a9+BpllbllbxQCD30ZRgHghvqXvDECWfP8r98iynz7u0oKGO8ZPf15d/l9VrkRtiuQ==} cpu: [x64] os: [linux] '@oxc-resolver/binding-wasm32-wasi@1.11.0': - resolution: - { - integrity: sha512-vhXnOs34q8p7QhqQ04bIGy7ZzLEHBaBTsqh2wpAzSBCmjL7MmTpM8KWwXFPFB+Wj0P7/parjGDHzbZG20pEePg==, - } - engines: { node: '>=14.0.0' } + resolution: {integrity: sha512-vhXnOs34q8p7QhqQ04bIGy7ZzLEHBaBTsqh2wpAzSBCmjL7MmTpM8KWwXFPFB+Wj0P7/parjGDHzbZG20pEePg==} + engines: {node: '>=14.0.0'} cpu: [wasm32] '@oxc-resolver/binding-win32-arm64-msvc@1.11.0': - resolution: - { - integrity: sha512-5XMm8EELDkAVQoMGv4QKqi+SjWnhcU1aq5B9q59iqiXIBNAs72f0d3LAldLrqE2XomP2QweorpsoxuGuIk2Cnw==, - } + resolution: {integrity: sha512-5XMm8EELDkAVQoMGv4QKqi+SjWnhcU1aq5B9q59iqiXIBNAs72f0d3LAldLrqE2XomP2QweorpsoxuGuIk2Cnw==} cpu: [arm64] os: [win32] '@oxc-resolver/binding-win32-x64-msvc@1.11.0': - resolution: - { - integrity: sha512-rVKiZSTgao4SBWyqWvStxDhKmwbKEN/E8+H3CJzIP4FcsL7MQtWH2HT86bmoefkyRe1yO+m2/mG7j3TfADh/Fg==, - } + resolution: {integrity: sha512-rVKiZSTgao4SBWyqWvStxDhKmwbKEN/E8+H3CJzIP4FcsL7MQtWH2HT86bmoefkyRe1yO+m2/mG7j3TfADh/Fg==} cpu: [x64] os: [win32] '@sinclair/typebox@0.27.8': - resolution: - { - integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==, - } + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} '@swc-node/core@1.13.3': - resolution: - { - integrity: sha512-OGsvXIid2Go21kiNqeTIn79jcaX4l0G93X2rAnas4LFoDyA9wAwVK7xZdm+QsKoMn5Mus2yFLCc4OtX2dD/PWA==, - } - engines: { node: '>= 10' } + resolution: {integrity: sha512-OGsvXIid2Go21kiNqeTIn79jcaX4l0G93X2rAnas4LFoDyA9wAwVK7xZdm+QsKoMn5Mus2yFLCc4OtX2dD/PWA==} + engines: {node: '>= 10'} peerDependencies: '@swc/core': '>= 1.4.13' '@swc/types': '>= 0.1' '@swc-node/register@1.10.9': - resolution: - { - integrity: sha512-iXy2sjP0phPEpK2yivjRC3PAgoLaT4sjSk0LDWCTdcTBJmR4waEog0E6eJbvoOkLkOtWw37SB8vCkl/bbh4+8A==, - } + resolution: {integrity: sha512-iXy2sjP0phPEpK2yivjRC3PAgoLaT4sjSk0LDWCTdcTBJmR4waEog0E6eJbvoOkLkOtWw37SB8vCkl/bbh4+8A==} peerDependencies: '@swc/core': '>= 1.4.13' typescript: '>= 4.3' '@swc-node/sourcemap-support@0.5.1': - resolution: - { - integrity: sha512-JxIvIo/Hrpv0JCHSyRpetAdQ6lB27oFYhv0PKCNf1g2gUXOjpeR1exrXccRxLMuAV5WAmGFBwRnNOJqN38+qtg==, - } + resolution: {integrity: sha512-JxIvIo/Hrpv0JCHSyRpetAdQ6lB27oFYhv0PKCNf1g2gUXOjpeR1exrXccRxLMuAV5WAmGFBwRnNOJqN38+qtg==} '@swc/core-darwin-arm64@1.5.29': - resolution: - { - integrity: sha512-6F/sSxpHaq3nzg2ADv9FHLi4Fu2A8w8vP8Ich8gIl16D2htStlwnaPmCLjRswO+cFkzgVqy/l01gzNGWd4DFqA==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-6F/sSxpHaq3nzg2ADv9FHLi4Fu2A8w8vP8Ich8gIl16D2htStlwnaPmCLjRswO+cFkzgVqy/l01gzNGWd4DFqA==} + engines: {node: '>=10'} cpu: [arm64] os: [darwin] '@swc/core-darwin-x64@1.5.29': - resolution: - { - integrity: sha512-rF/rXkvUOTdTIfoYbmszbSUGsCyvqACqy1VeP3nXONS+LxFl4bRmRcUTRrblL7IE5RTMCKUuPbqbQSE2hK7bqg==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-rF/rXkvUOTdTIfoYbmszbSUGsCyvqACqy1VeP3nXONS+LxFl4bRmRcUTRrblL7IE5RTMCKUuPbqbQSE2hK7bqg==} + engines: {node: '>=10'} cpu: [x64] os: [darwin] '@swc/core-linux-arm-gnueabihf@1.5.29': - resolution: - { - integrity: sha512-2OAPL8iWBsmmwkjGXqvuUhbmmoLxS1xNXiMq87EsnCNMAKohGc7wJkdAOUL6J/YFpean/vwMWg64rJD4pycBeg==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-2OAPL8iWBsmmwkjGXqvuUhbmmoLxS1xNXiMq87EsnCNMAKohGc7wJkdAOUL6J/YFpean/vwMWg64rJD4pycBeg==} + engines: {node: '>=10'} cpu: [arm] os: [linux] '@swc/core-linux-arm64-gnu@1.5.29': - resolution: - { - integrity: sha512-eH/Q9+8O5qhSxMestZnhuS1xqQMr6M7SolZYxiXJqxArXYILLCF+nq2R9SxuMl0CfjHSpb6+hHPk/HXy54eIRA==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-eH/Q9+8O5qhSxMestZnhuS1xqQMr6M7SolZYxiXJqxArXYILLCF+nq2R9SxuMl0CfjHSpb6+hHPk/HXy54eIRA==} + engines: {node: '>=10'} cpu: [arm64] os: [linux] '@swc/core-linux-arm64-musl@1.5.29': - resolution: - { - integrity: sha512-TERh2OICAJz+SdDIK9+0GyTUwF6r4xDlFmpoiHKHrrD/Hh3u+6Zue0d7jQ/he/i80GDn4tJQkHlZys+RZL5UZg==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-TERh2OICAJz+SdDIK9+0GyTUwF6r4xDlFmpoiHKHrrD/Hh3u+6Zue0d7jQ/he/i80GDn4tJQkHlZys+RZL5UZg==} + engines: {node: '>=10'} cpu: [arm64] os: [linux] '@swc/core-linux-x64-gnu@1.5.29': - resolution: - { - integrity: sha512-WMDPqU7Ji9dJpA+Llek2p9t7pcy7Bob8ggPUvgsIlv3R/eesF9DIzSbrgl6j3EAEPB9LFdSafsgf6kT/qnvqFg==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-WMDPqU7Ji9dJpA+Llek2p9t7pcy7Bob8ggPUvgsIlv3R/eesF9DIzSbrgl6j3EAEPB9LFdSafsgf6kT/qnvqFg==} + engines: {node: '>=10'} cpu: [x64] os: [linux] '@swc/core-linux-x64-musl@1.5.29': - resolution: - { - integrity: sha512-DO14glwpdKY4POSN0201OnGg1+ziaSVr6/RFzuSLggshwXeeyVORiHv3baj7NENhJhWhUy3NZlDsXLnRFkmhHQ==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-DO14glwpdKY4POSN0201OnGg1+ziaSVr6/RFzuSLggshwXeeyVORiHv3baj7NENhJhWhUy3NZlDsXLnRFkmhHQ==} + engines: {node: '>=10'} cpu: [x64] os: [linux] '@swc/core-win32-arm64-msvc@1.5.29': - resolution: - { - integrity: sha512-V3Y1+a1zG1zpYXUMqPIHEMEOd+rHoVnIpO/KTyFwAmKVu8v+/xPEVx/AGoYE67x4vDAAvPQrKI3Aokilqa5yVg==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-V3Y1+a1zG1zpYXUMqPIHEMEOd+rHoVnIpO/KTyFwAmKVu8v+/xPEVx/AGoYE67x4vDAAvPQrKI3Aokilqa5yVg==} + engines: {node: '>=10'} cpu: [arm64] os: [win32] '@swc/core-win32-ia32-msvc@1.5.29': - resolution: - { - integrity: sha512-OrM6yfXw4wXhnVFosOJzarw0Fdz5Y0okgHfn9oFbTPJhoqxV5Rdmd6kXxWu2RiVKs6kGSJFZXHDeUq2w5rTIMg==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-OrM6yfXw4wXhnVFosOJzarw0Fdz5Y0okgHfn9oFbTPJhoqxV5Rdmd6kXxWu2RiVKs6kGSJFZXHDeUq2w5rTIMg==} + engines: {node: '>=10'} cpu: [ia32] os: [win32] '@swc/core-win32-x64-msvc@1.5.29': - resolution: - { - integrity: sha512-eD/gnxqKyZQQR0hR7TMkIlJ+nCF9dzYmVVNbYZWuA1Xy94aBPUsEk3Uw3oG7q6R3ErrEUPP0FNf2ztEnv+I+dw==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-eD/gnxqKyZQQR0hR7TMkIlJ+nCF9dzYmVVNbYZWuA1Xy94aBPUsEk3Uw3oG7q6R3ErrEUPP0FNf2ztEnv+I+dw==} + engines: {node: '>=10'} cpu: [x64] os: [win32] '@swc/core@1.5.29': - resolution: - { - integrity: sha512-nvTtHJI43DUSOAf3h9XsqYg8YXKc0/N4il9y4j0xAkO0ekgDNo+3+jbw6MInawjKJF9uulyr+f5bAutTsOKVlw==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-nvTtHJI43DUSOAf3h9XsqYg8YXKc0/N4il9y4j0xAkO0ekgDNo+3+jbw6MInawjKJF9uulyr+f5bAutTsOKVlw==} + engines: {node: '>=10'} peerDependencies: '@swc/helpers': '*' peerDependenciesMeta: @@ -1915,355 +1283,187 @@ packages: optional: true '@swc/counter@0.1.3': - resolution: - { - integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==, - } + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} '@swc/helpers@0.5.12': - resolution: - { - integrity: sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==, - } + resolution: {integrity: sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==} '@swc/types@0.1.12': - resolution: - { - integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==, - } + resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==} '@tsconfig/node10@1.0.11': - resolution: - { - integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==, - } + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} '@tsconfig/node12@1.0.11': - resolution: - { - integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==, - } + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} '@tsconfig/node14@1.0.3': - resolution: - { - integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==, - } + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} '@tsconfig/node16@1.0.4': - resolution: - { - integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==, - } + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} '@tybys/wasm-util@0.9.0': - resolution: - { - integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==, - } + resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} '@types/body-parser@1.19.5': - resolution: - { - integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==, - } + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} '@types/bun@1.1.8': - resolution: - { - integrity: sha512-PIwVFQKPviksiibobyvcWtMvMFMTj91T8dQEh9l1P3Ypr3ZuVn9w7HSr+5mTNrPqD1xpdDLEErzZPU8gqHBu6g==, - } + resolution: {integrity: sha512-PIwVFQKPviksiibobyvcWtMvMFMTj91T8dQEh9l1P3Ypr3ZuVn9w7HSr+5mTNrPqD1xpdDLEErzZPU8gqHBu6g==} '@types/busboy@1.5.4': - resolution: - { - integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==, - } + resolution: {integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==} '@types/connect@3.4.38': - resolution: - { - integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==, - } + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} '@types/express-serve-static-core@4.19.5': - resolution: - { - integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==, - } + resolution: {integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==} '@types/express@4.17.21': - resolution: - { - integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==, - } + resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} '@types/http-errors@2.0.4': - resolution: - { - integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==, - } + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} '@types/mime@1.3.5': - resolution: - { - integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==, - } + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} '@types/node-forge@1.3.11': - resolution: - { - integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==, - } + resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} '@types/node@20.12.14': - resolution: - { - integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==, - } + resolution: {integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==} '@types/node@20.16.1': - resolution: - { - integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==, - } + resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==} '@types/node@22.5.0': - resolution: - { - integrity: sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==, - } + resolution: {integrity: sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==} '@types/parse-json@4.0.2': - resolution: - { - integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==, - } - - '@types/proxy-addr@2.0.3': - resolution: - { - integrity: sha512-TgAHHO4tNG3HgLTUhB+hM4iwW6JUNeQHCLnF1DjaDA9c69PN+IasoFu2MYDhubFc+ZIw5c5t9DMtjvrD6R3Egg==, - } + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} '@types/qs@6.9.15': - resolution: - { - integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==, - } + resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} '@types/range-parser@1.2.7': - resolution: - { - integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==, - } + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} '@types/send@0.17.4': - resolution: - { - integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==, - } + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} '@types/serve-static@1.15.7': - resolution: - { - integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==, - } + resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} '@types/tmp@0.2.6': - resolution: - { - integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==, - } + resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} '@types/ws@8.5.12': - resolution: - { - integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==, - } + resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} '@yarnpkg/lockfile@1.1.0': - resolution: - { - integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==, - } + resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} '@yarnpkg/parsers@3.0.0-rc.46': - resolution: - { - integrity: sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==, - } - engines: { node: '>=14.15.0' } + resolution: {integrity: sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==} + engines: {node: '>=14.15.0'} '@zkochan/js-yaml@0.0.7': - resolution: - { - integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==, - } + resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} hasBin: true accepts@1.3.8: - resolution: - { - integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} acorn-walk@8.3.3: - resolution: - { - integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==, - } - engines: { node: '>=0.4.0' } + resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} + engines: {node: '>=0.4.0'} acorn@8.12.1: - resolution: - { - integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==, - } - engines: { node: '>=0.4.0' } + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} hasBin: true address@1.2.2: - resolution: - { - integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==, - } - engines: { node: '>= 10.0.0' } + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} ansi-colors@4.1.3: - resolution: - { - integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==, - } - engines: { node: '>=6' } + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} ansi-regex@5.0.1: - resolution: - { - integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} ansi-styles@3.2.1: - resolution: - { - integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} ansi-styles@4.3.0: - resolution: - { - integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} ansi-styles@5.2.0: - resolution: - { - integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} anymatch@3.1.3: - resolution: - { - integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, - } - engines: { node: '>= 8' } + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} arg@4.1.3: - resolution: - { - integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==, - } + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} argparse@1.0.10: - resolution: - { - integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, - } + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} argparse@2.0.1: - resolution: - { - integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, - } + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} array-flatten@1.1.1: - resolution: - { - integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==, - } + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} as-table@1.0.55: - resolution: - { - integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==, - } + resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} async@3.2.6: - resolution: - { - integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==, - } + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} asynckit@0.4.0: - resolution: - { - integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, - } + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} axios@1.7.5: - resolution: - { - integrity: sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==, - } + resolution: {integrity: sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==} babel-plugin-const-enum@1.2.0: - resolution: - { - integrity: sha512-o1m/6iyyFnp9MRsK1dHF3bneqyf3AlM2q3A/YbgQr2pCat6B6XJVDv2TXqzfY2RYUi4mak6WAksSBPlyYGx9dg==, - } + resolution: {integrity: sha512-o1m/6iyyFnp9MRsK1dHF3bneqyf3AlM2q3A/YbgQr2pCat6B6XJVDv2TXqzfY2RYUi4mak6WAksSBPlyYGx9dg==} peerDependencies: '@babel/core': ^7.0.0-0 babel-plugin-macros@2.8.0: - resolution: - { - integrity: sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==, - } + resolution: {integrity: sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==} babel-plugin-polyfill-corejs2@0.4.11: - resolution: - { - integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==, - } + resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 babel-plugin-polyfill-corejs3@0.10.6: - resolution: - { - integrity: sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==, - } + resolution: {integrity: sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 babel-plugin-polyfill-regenerator@0.6.2: - resolution: - { - integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==, - } + resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 babel-plugin-transform-typescript-metadata@0.3.2: - resolution: - { - integrity: sha512-mWEvCQTgXQf48yDqgN7CH50waTyYBeP2Lpqx4nNWab9sxEpdXVeKgfj1qYI2/TgUPQtNFZ85i3PemRtnXVYYJg==, - } + resolution: {integrity: sha512-mWEvCQTgXQf48yDqgN7CH50waTyYBeP2Lpqx4nNWab9sxEpdXVeKgfj1qYI2/TgUPQtNFZ85i3PemRtnXVYYJg==} peerDependencies: '@babel/core': ^7 '@babel/traverse': ^7 @@ -2272,311 +1472,170 @@ packages: optional: true balanced-match@1.0.2: - resolution: - { - integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, - } + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} base64-js@1.5.1: - resolution: - { - integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==, - } + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} binary-extensions@2.3.0: - resolution: - { - integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} bl@4.1.0: - resolution: - { - integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==, - } + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} blake3-wasm@2.1.5: - resolution: - { - integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==, - } + resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} body-parser@1.20.2: - resolution: - { - integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==, - } - engines: { node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16 } + resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} brace-expansion@1.1.11: - resolution: - { - integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, - } + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} brace-expansion@2.0.1: - resolution: - { - integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==, - } + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} braces@3.0.3: - resolution: - { - integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} browserslist@4.23.3: - resolution: - { - integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==, - } - engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } + resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true buffer-from@1.1.2: - resolution: - { - integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, - } + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} buffer@5.7.1: - resolution: - { - integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==, - } + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} bun-types@1.1.26: - resolution: - { - integrity: sha512-n7jDe62LsB2+WE8Q8/mT3azkPaatKlj/2MyP6hi3mKvPz9oPpB6JW/Ll6JHtNLudasFFuvfgklYSE+rreGvBjw==, - } + resolution: {integrity: sha512-n7jDe62LsB2+WE8Q8/mT3azkPaatKlj/2MyP6hi3mKvPz9oPpB6JW/Ll6JHtNLudasFFuvfgklYSE+rreGvBjw==} busboy@1.6.0: - resolution: - { - integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==, - } - engines: { node: '>=10.16.0' } + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} bytes@3.1.2: - resolution: - { - integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==, - } - engines: { node: '>= 0.8' } + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} call-bind@1.0.7: - resolution: - { - integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==, - } - engines: { node: '>= 0.4' } + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} callsites@3.1.0: - resolution: - { - integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, - } - engines: { node: '>=6' } + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} caniuse-lite@1.0.30001653: - resolution: - { - integrity: sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==, - } + resolution: {integrity: sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==} capnp-ts@0.7.0: - resolution: - { - integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==, - } + resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} chalk@2.4.2: - resolution: - { - integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} chalk@4.1.2: - resolution: - { - integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} chokidar@3.6.0: - resolution: - { - integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==, - } - engines: { node: '>= 8.10.0' } + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} cli-cursor@3.1.0: - resolution: - { - integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} cli-spinners@2.6.1: - resolution: - { - integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==, - } - engines: { node: '>=6' } + resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} + engines: {node: '>=6'} cliui@8.0.1: - resolution: - { - integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} clone@1.0.4: - resolution: - { - integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==, - } - engines: { node: '>=0.8' } + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} color-convert@1.9.3: - resolution: - { - integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, - } + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} color-convert@2.0.1: - resolution: - { - integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, - } - engines: { node: '>=7.0.0' } + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} color-name@1.1.3: - resolution: - { - integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, - } + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} color-name@1.1.4: - resolution: - { - integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, - } + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} colorette@2.0.20: - resolution: - { - integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==, - } + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} columnify@1.6.0: - resolution: - { - integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==, - } - engines: { node: '>=8.0.0' } + resolution: {integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==} + engines: {node: '>=8.0.0'} combined-stream@1.0.8: - resolution: - { - integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, - } - engines: { node: '>= 0.8' } + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} concat-map@0.0.1: - resolution: - { - integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, - } + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} consola@3.2.3: - resolution: - { - integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==, - } - engines: { node: ^14.18.0 || >=16.10.0 } + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} content-disposition@0.5.4: - resolution: - { - integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} content-type@1.0.5: - resolution: - { - integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} convert-source-map@2.0.0: - resolution: - { - integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, - } + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} cookie-signature@1.0.6: - resolution: - { - integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==, - } + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} cookie@0.5.0: - resolution: - { - integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} cookie@0.6.0: - resolution: - { - integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} core-js-compat@3.38.1: - resolution: - { - integrity: sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==, - } + resolution: {integrity: sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==} cosmiconfig@6.0.0: - resolution: - { - integrity: sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==} + engines: {node: '>=8'} create-require@1.1.1: - resolution: - { - integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==, - } + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} data-uri-to-buffer@2.0.2: - resolution: - { - integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==, - } + resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} date-fns@3.6.0: - resolution: - { - integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==, - } + resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} debug@2.6.9: - resolution: - { - integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==, - } + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: supports-color: '*' peerDependenciesMeta: @@ -2584,11 +1643,8 @@ packages: optional: true debug@4.3.6: - resolution: - { - integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==, - } - engines: { node: '>=6.0' } + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} peerDependencies: supports-color: '*' peerDependenciesMeta: @@ -2596,290 +1652,164 @@ packages: optional: true defaults@1.0.4: - resolution: - { - integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==, - } + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} define-data-property@1.1.4: - resolution: - { - integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==, - } - engines: { node: '>= 0.4' } + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} define-lazy-prop@2.0.0: - resolution: - { - integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} defu@6.1.4: - resolution: - { - integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==, - } + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} delayed-stream@1.0.0: - resolution: - { - integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, - } - engines: { node: '>=0.4.0' } + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} depd@2.0.0: - resolution: - { - integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==, - } - engines: { node: '>= 0.8' } + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} destroy@1.2.0: - resolution: - { - integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==, - } - engines: { node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16 } + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} detect-port@1.6.1: - resolution: - { - integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==, - } - engines: { node: '>= 4.0.0' } + resolution: {integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==} + engines: {node: '>= 4.0.0'} hasBin: true diff-sequences@29.6.3: - resolution: - { - integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} diff@4.0.2: - resolution: - { - integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==, - } - engines: { node: '>=0.3.1' } + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} dotenv-expand@11.0.6: - resolution: - { - integrity: sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==} + engines: {node: '>=12'} dotenv@16.4.5: - resolution: - { - integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} duplexer@0.1.2: - resolution: - { - integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==, - } + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} ee-first@1.1.1: - resolution: - { - integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==, - } + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} ejs@3.1.10: - resolution: - { - integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==, - } - engines: { node: '>=0.10.0' } + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} hasBin: true electron-to-chromium@1.5.13: - resolution: - { - integrity: sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==, - } + resolution: {integrity: sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==} emoji-regex@8.0.0: - resolution: - { - integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, - } + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} encodeurl@1.0.2: - resolution: - { - integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==, - } - engines: { node: '>= 0.8' } + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} end-of-stream@1.4.4: - resolution: - { - integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==, - } + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} enquirer@2.3.6: - resolution: - { - integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==, - } - engines: { node: '>=8.6' } + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} error-ex@1.3.2: - resolution: - { - integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==, - } + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} es-define-property@1.0.0: - resolution: - { - integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==, - } - engines: { node: '>= 0.4' } + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} es-errors@1.3.0: - resolution: - { - integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==, - } - engines: { node: '>= 0.4' } + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} esbuild@0.17.19: - resolution: - { - integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} + engines: {node: '>=12'} hasBin: true escalade@3.1.2: - resolution: - { - integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==, - } - engines: { node: '>=6' } + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} escape-html@1.0.3: - resolution: - { - integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==, - } + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} escape-string-regexp@1.0.5: - resolution: - { - integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==, - } - engines: { node: '>=0.8.0' } + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} escape-string-regexp@4.0.0: - resolution: - { - integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} esprima@4.0.1: - resolution: - { - integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} hasBin: true estree-walker@0.6.1: - resolution: - { - integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==, - } + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} esutils@2.0.3: - resolution: - { - integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, - } - engines: { node: '>=0.10.0' } + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} etag@1.8.1: - resolution: - { - integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} exit-hook@2.2.1: - resolution: - { - integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==, - } - engines: { node: '>=6' } + resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} + engines: {node: '>=6'} express@4.19.2: - resolution: - { - integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==, - } - engines: { node: '>= 0.10.0' } + resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} + engines: {node: '>= 0.10.0'} fast-glob@3.2.7: - resolution: - { - integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==} + engines: {node: '>=8'} fastq@1.17.1: - resolution: - { - integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==, - } + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} figures@3.2.0: - resolution: - { - integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} filelist@1.0.4: - resolution: - { - integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==, - } + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} fill-range@7.1.1: - resolution: - { - integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} finalhandler@1.2.0: - resolution: - { - integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==, - } - engines: { node: '>= 0.8' } + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} flat@5.0.2: - resolution: - { - integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==, - } + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true follow-redirects@1.15.6: - resolution: - { - integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==, - } - engines: { node: '>=4.0' } + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} peerDependencies: debug: '*' peerDependenciesMeta: @@ -2887,625 +1817,349 @@ packages: optional: true form-data@4.0.0: - resolution: - { - integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==, - } - engines: { node: '>= 6' } + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} forwarded@0.2.0: - resolution: - { - integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} fresh@0.5.2: - resolution: - { - integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} front-matter@4.0.2: - resolution: - { - integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==, - } + resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} fs-constants@1.0.0: - resolution: - { - integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==, - } + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} fs-extra@11.2.0: - resolution: - { - integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==, - } - engines: { node: '>=14.14' } + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} fsevents@2.3.3: - resolution: - { - integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, - } - engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] function-bind@1.1.2: - resolution: - { - integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, - } + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} gensync@1.0.0-beta.2: - resolution: - { - integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, - } - engines: { node: '>=6.9.0' } + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} get-caller-file@2.0.5: - resolution: - { - integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, - } - engines: { node: 6.* || 8.* || >= 10.* } + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} get-intrinsic@1.2.4: - resolution: - { - integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==, - } - engines: { node: '>= 0.4' } + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} get-source@2.0.12: - resolution: - { - integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==, - } + resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} glob-parent@5.1.2: - resolution: - { - integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, - } - engines: { node: '>= 6' } + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} glob-to-regexp@0.4.1: - resolution: - { - integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==, - } + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} globals@11.12.0: - resolution: - { - integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} gopd@1.0.1: - resolution: - { - integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==, - } + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} graceful-fs@4.2.11: - resolution: - { - integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, - } + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} has-flag@3.0.0: - resolution: - { - integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} has-flag@4.0.0: - resolution: - { - integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} has-property-descriptors@1.0.2: - resolution: - { - integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==, - } + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} has-proto@1.0.3: - resolution: - { - integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==, - } - engines: { node: '>= 0.4' } + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} has-symbols@1.0.3: - resolution: - { - integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==, - } - engines: { node: '>= 0.4' } + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} hasown@2.0.2: - resolution: - { - integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==, - } - engines: { node: '>= 0.4' } + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} hosted-git-info@7.0.2: - resolution: - { - integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==, - } - engines: { node: ^16.14.0 || >=18.0.0 } + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} http-errors@2.0.0: - resolution: - { - integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==, - } - engines: { node: '>= 0.8' } + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} iconv-lite@0.4.24: - resolution: - { - integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==, - } - engines: { node: '>=0.10.0' } + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} ieee754@1.2.1: - resolution: - { - integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==, - } + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} ignore@5.3.2: - resolution: - { - integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==, - } - engines: { node: '>= 4' } + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} import-fresh@3.3.0: - resolution: - { - integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==, - } - engines: { node: '>=6' } + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} inherits@2.0.4: - resolution: - { - integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, - } + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} ipaddr.js@1.9.1: - resolution: - { - integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==, - } - engines: { node: '>= 0.10' } + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} is-arrayish@0.2.1: - resolution: - { - integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==, - } + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} is-binary-path@2.1.0: - resolution: - { - integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} is-core-module@2.15.1: - resolution: - { - integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==, - } - engines: { node: '>= 0.4' } + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} is-docker@2.2.1: - resolution: - { - integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} hasBin: true is-extglob@2.1.1: - resolution: - { - integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, - } - engines: { node: '>=0.10.0' } + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} is-fullwidth-code-point@3.0.0: - resolution: - { - integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} is-glob@4.0.3: - resolution: - { - integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, - } - engines: { node: '>=0.10.0' } + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} is-interactive@1.0.0: - resolution: - { - integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} is-number@7.0.0: - resolution: - { - integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, - } - engines: { node: '>=0.12.0' } + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} is-unicode-supported@0.1.0: - resolution: - { - integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} is-wsl@2.2.0: - resolution: - { - integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} jake@10.9.2: - resolution: - { - integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} + engines: {node: '>=10'} hasBin: true jest-diff@29.7.0: - resolution: - { - integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-get-type@29.6.3: - resolution: - { - integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} js-tokens@4.0.0: - resolution: - { - integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, - } + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} js-yaml@3.14.1: - resolution: - { - integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==, - } + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true jsesc@0.5.0: - resolution: - { - integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==, - } + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} hasBin: true jsesc@2.5.2: - resolution: - { - integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} hasBin: true json-parse-even-better-errors@2.3.1: - resolution: - { - integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, - } + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} json5@2.2.3: - resolution: - { - integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, - } - engines: { node: '>=6' } + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} hasBin: true jsonc-parser@3.2.0: - resolution: - { - integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==, - } + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} jsonfile@6.1.0: - resolution: - { - integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==, - } + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} lines-and-columns@1.2.4: - resolution: - { - integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, - } + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} lines-and-columns@2.0.4: - resolution: - { - integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==, - } - engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} lodash.debounce@4.0.8: - resolution: - { - integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==, - } + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} log-symbols@4.1.0: - resolution: - { - integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} lru-cache@10.4.3: - resolution: - { - integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==, - } + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} lru-cache@5.1.1: - resolution: - { - integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, - } + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} magic-string@0.25.9: - resolution: - { - integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==, - } + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} make-error@1.3.6: - resolution: - { - integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==, - } + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} media-typer@0.3.0: - resolution: - { - integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} merge-descriptors@1.0.1: - resolution: - { - integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==, - } + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} merge2@1.4.1: - resolution: - { - integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, - } - engines: { node: '>= 8' } + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} methods@1.1.2: - resolution: - { - integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} micromatch@4.0.8: - resolution: - { - integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, - } - engines: { node: '>=8.6' } + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} mime-db@1.52.0: - resolution: - { - integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} mime-types@2.1.35: - resolution: - { - integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} mime@1.6.0: - resolution: - { - integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} hasBin: true mime@3.0.0: - resolution: - { - integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==, - } - engines: { node: '>=10.0.0' } + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} hasBin: true mimic-fn@2.1.0: - resolution: - { - integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, - } - engines: { node: '>=6' } + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} miniflare@3.20240821.0: - resolution: - { - integrity: sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==, - } - engines: { node: '>=16.13' } + resolution: {integrity: sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==} + engines: {node: '>=16.13'} hasBin: true minimatch@3.1.2: - resolution: - { - integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, - } + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} minimatch@5.1.6: - resolution: - { - integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} minimatch@9.0.3: - resolution: - { - integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==, - } - engines: { node: '>=16 || 14 >=14.17' } + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.8: - resolution: - { - integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==, - } + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} mrmime@2.0.0: - resolution: - { - integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + engines: {node: '>=10'} ms@2.0.0: - resolution: - { - integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==, - } + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} ms@2.1.2: - resolution: - { - integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, - } + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} ms@2.1.3: - resolution: - { - integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, - } + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} multipasta@0.2.5: - resolution: - { - integrity: sha512-c8eMDb1WwZcE02WVjHoOmUVk7fnKU/RmUcosHACglrWAuPQsEJv+E8430sXj6jNc1jHw0zrS16aCjQh4BcEb4A==, - } + resolution: {integrity: sha512-c8eMDb1WwZcE02WVjHoOmUVk7fnKU/RmUcosHACglrWAuPQsEJv+E8430sXj6jNc1jHw0zrS16aCjQh4BcEb4A==} mustache@4.2.0: - resolution: - { - integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==, - } + resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} hasBin: true nanoid@3.3.7: - resolution: - { - integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==, - } - engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true negotiator@0.6.3: - resolution: - { - integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} node-fetch-native@1.6.4: - resolution: - { - integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==, - } + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} node-forge@1.3.1: - resolution: - { - integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==, - } - engines: { node: '>= 6.13.0' } + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} node-machine-id@1.1.12: - resolution: - { - integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==, - } + resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} node-releases@2.0.18: - resolution: - { - integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==, - } + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} normalize-path@3.0.0: - resolution: - { - integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, - } - engines: { node: '>=0.10.0' } + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} npm-package-arg@11.0.1: - resolution: - { - integrity: sha512-M7s1BD4NxdAvBKUPqqRW957Xwcl/4Zvo8Aj+ANrzvIPzGJZElrH7Z//rSaec2ORcND6FHHLnZeY8qgTpXDMFQQ==, - } - engines: { node: ^16.14.0 || >=18.0.0 } + resolution: {integrity: sha512-M7s1BD4NxdAvBKUPqqRW957Xwcl/4Zvo8Aj+ANrzvIPzGJZElrH7Z//rSaec2ORcND6FHHLnZeY8qgTpXDMFQQ==} + engines: {node: ^16.14.0 || >=18.0.0} npm-run-path@4.0.1: - resolution: - { - integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} nx@19.6.4: - resolution: - { - integrity: sha512-yudYlBd3cMchRd8c0ZNan1SfT19AYK2zYOp77XVqVVwgqb6rJVxz6StFGFluUQ7Q7uSpkeT/8PsjwPVLt85EoQ==, - } + resolution: {integrity: sha512-yudYlBd3cMchRd8c0ZNan1SfT19AYK2zYOp77XVqVVwgqb6rJVxz6StFGFluUQ7Q7uSpkeT/8PsjwPVLt85EoQ==} hasBin: true peerDependencies: '@swc-node/register': ^1.8.0 @@ -3517,560 +2171,311 @@ packages: optional: true object-inspect@1.13.2: - resolution: - { - integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==, - } - engines: { node: '>= 0.4' } + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} on-finished@2.4.1: - resolution: - { - integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==, - } - engines: { node: '>= 0.8' } + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} once@1.4.0: - resolution: - { - integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, - } + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} onetime@5.1.2: - resolution: - { - integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, - } - engines: { node: '>=6' } + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} open@8.4.2: - resolution: - { - integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} ora@5.3.0: - resolution: - { - integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} + engines: {node: '>=10'} oxc-resolver@1.11.0: - resolution: - { - integrity: sha512-N3qMse2AM7uST8PaiUMXZkcACyGAMN073tomyvzHTICSzaOqKHvVS0IZ3vj/OqoE140QP4CyOiWmgC1Hw5Urmg==, - } + resolution: {integrity: sha512-N3qMse2AM7uST8PaiUMXZkcACyGAMN073tomyvzHTICSzaOqKHvVS0IZ3vj/OqoE140QP4CyOiWmgC1Hw5Urmg==} parent-module@1.0.1: - resolution: - { - integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, - } - engines: { node: '>=6' } + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} parse-json@5.2.0: - resolution: - { - integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} parseurl@1.3.3: - resolution: - { - integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==, - } - engines: { node: '>= 0.8' } + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} path-key@3.1.1: - resolution: - { - integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} path-parse@1.0.7: - resolution: - { - integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, - } + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} path-to-regexp@0.1.7: - resolution: - { - integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==, - } + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} path-to-regexp@6.2.2: - resolution: - { - integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==, - } + resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} path-type@4.0.0: - resolution: - { - integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} pathe@1.1.2: - resolution: - { - integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==, - } + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} picocolors@1.0.1: - resolution: - { - integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==, - } + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} picomatch@2.3.1: - resolution: - { - integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, - } - engines: { node: '>=8.6' } + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} pirates@4.0.6: - resolution: - { - integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==, - } - engines: { node: '>= 6' } + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} prettier@3.3.3: - resolution: - { - integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==, - } - engines: { node: '>=14' } + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} hasBin: true pretty-format@29.7.0: - resolution: - { - integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} printable-characters@1.0.42: - resolution: - { - integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==, - } + resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} proc-log@3.0.0: - resolution: - { - integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==, - } - engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } + resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} proxy-addr@2.0.7: - resolution: - { - integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==, - } - engines: { node: '>= 0.10' } + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} proxy-from-env@1.1.0: - resolution: - { - integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==, - } + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} qs@6.11.0: - resolution: - { - integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==, - } - engines: { node: '>=0.6' } + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} queue-microtask@1.2.3: - resolution: - { - integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, - } + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} range-parser@1.2.1: - resolution: - { - integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} raw-body@2.5.2: - resolution: - { - integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==, - } - engines: { node: '>= 0.8' } + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} react-is@18.3.1: - resolution: - { - integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==, - } + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} readable-stream@3.6.2: - resolution: - { - integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==, - } - engines: { node: '>= 6' } + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} readdirp@3.6.0: - resolution: - { - integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==, - } - engines: { node: '>=8.10.0' } + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} regenerate-unicode-properties@10.1.1: - resolution: - { - integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} + engines: {node: '>=4'} regenerate@1.4.2: - resolution: - { - integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==, - } + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} regenerator-runtime@0.14.1: - resolution: - { - integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==, - } + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} regenerator-transform@0.15.2: - resolution: - { - integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==, - } + resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} regexpu-core@5.3.2: - resolution: - { - integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + engines: {node: '>=4'} regjsparser@0.9.1: - resolution: - { - integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==, - } + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} hasBin: true require-directory@2.1.1: - resolution: - { - integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, - } - engines: { node: '>=0.10.0' } + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} resolve-from@4.0.0: - resolution: - { - integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} resolve.exports@2.0.2: - resolution: - { - integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} resolve@1.22.8: - resolution: - { - integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==, - } + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true restore-cursor@3.1.0: - resolution: - { - integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} reusify@1.0.4: - resolution: - { - integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==, - } - engines: { iojs: '>=1.0.0', node: '>=0.10.0' } + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} rollup-plugin-inject@3.0.2: - resolution: - { - integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==, - } + resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. rollup-plugin-node-polyfills@0.2.1: - resolution: - { - integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==, - } + resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} rollup-pluginutils@2.8.2: - resolution: - { - integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==, - } + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} run-parallel@1.2.0: - resolution: - { - integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, - } + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} safe-buffer@5.2.1: - resolution: - { - integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, - } + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} safer-buffer@2.1.2: - resolution: - { - integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, - } + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} selfsigned@2.4.1: - resolution: - { - integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} + engines: {node: '>=10'} semver@6.3.1: - resolution: - { - integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, - } + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true semver@7.6.3: - resolution: - { - integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} hasBin: true send@0.18.0: - resolution: - { - integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==, - } - engines: { node: '>= 0.8.0' } + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} serve-static@1.15.0: - resolution: - { - integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==, - } - engines: { node: '>= 0.8.0' } + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} set-function-length@1.2.2: - resolution: - { - integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==, - } - engines: { node: '>= 0.4' } + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} setprototypeof@1.2.0: - resolution: - { - integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==, - } + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} side-channel@1.0.6: - resolution: - { - integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==, - } - engines: { node: '>= 0.4' } + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} signal-exit@3.0.7: - resolution: - { - integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, - } + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} source-map-support@0.5.19: - resolution: - { - integrity: sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==, - } + resolution: {integrity: sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==} source-map-support@0.5.21: - resolution: - { - integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==, - } + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} source-map@0.6.1: - resolution: - { - integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, - } - engines: { node: '>=0.10.0' } + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} sourcemap-codec@1.4.8: - resolution: - { - integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==, - } + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} deprecated: Please use @jridgewell/sourcemap-codec instead sprintf-js@1.0.3: - resolution: - { - integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, - } + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} stacktracey@2.1.8: - resolution: - { - integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==, - } + resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} statuses@2.0.1: - resolution: - { - integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==, - } - engines: { node: '>= 0.8' } + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} stoppable@1.1.0: - resolution: - { - integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==, - } - engines: { node: '>=4', npm: '>=6' } + resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} + engines: {node: '>=4', npm: '>=6'} streamsearch@1.1.0: - resolution: - { - integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==, - } - engines: { node: '>=10.0.0' } + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} string-width@4.2.3: - resolution: - { - integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} string_decoder@1.3.0: - resolution: - { - integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==, - } + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} strip-ansi@6.0.1: - resolution: - { - integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} strip-bom@3.0.0: - resolution: - { - integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} strong-log-transformer@2.1.0: - resolution: - { - integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==} + engines: {node: '>=4'} hasBin: true supports-color@5.5.0: - resolution: - { - integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} supports-color@7.2.0: - resolution: - { - integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, - } - engines: { node: '>=8' } + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} supports-preserve-symlinks-flag@1.0.0: - resolution: - { - integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, - } - engines: { node: '>= 0.4' } + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} tar-stream@2.2.0: - resolution: - { - integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==, - } - engines: { node: '>=6' } + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} through@2.3.8: - resolution: - { - integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==, - } + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} tmp@0.2.3: - resolution: - { - integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==, - } - engines: { node: '>=14.14' } + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + engines: {node: '>=14.14'} to-fast-properties@2.0.0: - resolution: - { - integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} to-regex-range@5.0.1: - resolution: - { - integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, - } - engines: { node: '>=8.0' } + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} toidentifier@1.0.1: - resolution: - { - integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==, - } - engines: { node: '>=0.6' } + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} ts-node@10.9.1: - resolution: - { - integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==, - } + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: '@swc/core': '>=1.2.50' @@ -4084,168 +2489,96 @@ packages: optional: true tsconfig-paths@4.2.0: - resolution: - { - integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==, - } - engines: { node: '>=6' } + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} tslib@2.7.0: - resolution: - { - integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==, - } + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} type-is@1.6.18: - resolution: - { - integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==, - } - engines: { node: '>= 0.6' } + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} typescript@5.5.4: - resolution: - { - integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==, - } - engines: { node: '>=14.17' } + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} hasBin: true ufo@1.5.4: - resolution: - { - integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==, - } + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} undici-types@5.26.5: - resolution: - { - integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==, - } + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} undici-types@6.19.8: - resolution: - { - integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==, - } + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} undici@5.28.4: - resolution: - { - integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==, - } - engines: { node: '>=14.0' } + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} + engines: {node: '>=14.0'} unenv-nightly@1.10.0-1717606461.a117952: - resolution: - { - integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==, - } + resolution: {integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==} unicode-canonical-property-names-ecmascript@2.0.0: - resolution: - { - integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} unicode-match-property-ecmascript@2.0.0: - resolution: - { - integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} unicode-match-property-value-ecmascript@2.1.0: - resolution: - { - integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} unicode-property-aliases-ecmascript@2.1.0: - resolution: - { - integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==, - } - engines: { node: '>=4' } + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} universalify@2.0.1: - resolution: - { - integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==, - } - engines: { node: '>= 10.0.0' } + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} unpipe@1.0.0: - resolution: - { - integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==, - } - engines: { node: '>= 0.8' } + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} update-browserslist-db@1.1.0: - resolution: - { - integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==, - } + resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' util-deprecate@1.0.2: - resolution: - { - integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==, - } + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} utils-merge@1.0.1: - resolution: - { - integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==, - } - engines: { node: '>= 0.4.0' } + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} v8-compile-cache-lib@3.0.1: - resolution: - { - integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==, - } + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} validate-npm-package-name@5.0.1: - resolution: - { - integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==, - } - engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } + resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} vary@1.1.2: - resolution: - { - integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==, - } - engines: { node: '>= 0.8' } + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} wcwidth@1.0.1: - resolution: - { - integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==, - } + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} workerd@1.20240821.1: - resolution: - { - integrity: sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==, - } - engines: { node: '>=16' } + resolution: {integrity: sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==} + engines: {node: '>=16'} hasBin: true wrangler@3.72.3: - resolution: - { - integrity: sha512-EBlJGOcwanbzFkiJkRB47WKhvevh1AZK0ty0MyD0gptsgWnAxBfmFGiBuzOuRXbvH45ZrFrTqgi8c67EwcV1nA==, - } - engines: { node: '>=16.17.0' } + resolution: {integrity: sha512-EBlJGOcwanbzFkiJkRB47WKhvevh1AZK0ty0MyD0gptsgWnAxBfmFGiBuzOuRXbvH45ZrFrTqgi8c67EwcV1nA==} + engines: {node: '>=16.17.0'} hasBin: true peerDependencies: '@cloudflare/workers-types': ^4.20240821.1 @@ -4254,24 +2587,15 @@ packages: optional: true wrap-ansi@7.0.0: - resolution: - { - integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} wrappy@1.0.2: - resolution: - { - integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, - } + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} ws@8.18.0: - resolution: - { - integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==, - } - engines: { node: '>=10.0.0' } + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 utf-8-validate: '>=5.0.2' @@ -4282,65 +2606,39 @@ packages: optional: true xxhash-wasm@1.0.2: - resolution: - { - integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==, - } + resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} y18n@5.0.8: - resolution: - { - integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, - } - engines: { node: '>=10' } + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} yallist@3.1.1: - resolution: - { - integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, - } + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} yaml@1.10.2: - resolution: - { - integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==, - } - engines: { node: '>= 6' } + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} yargs-parser@21.1.1: - resolution: - { - integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} yargs@17.7.2: - resolution: - { - integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, - } - engines: { node: '>=12' } + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} yn@3.1.1: - resolution: - { - integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==, - } - engines: { node: '>=6' } + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} youch@3.3.3: - resolution: - { - integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==, - } + resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} zod@3.23.8: - resolution: - { - integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==, - } + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} snapshots: + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.5 @@ -5661,10 +3959,6 @@ snapshots: '@types/parse-json@4.0.2': {} - '@types/proxy-addr@2.0.3': - dependencies: - '@types/node': 22.5.0 - '@types/qs@6.9.15': {} '@types/range-parser@1.2.7': {} From 61e40836f004be66eb3a61bccc35e4fd49422001 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 13:57:59 -0700 Subject: [PATCH 399/730] Update README --- packages/node-fetch-server/README.md | 36 ++++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/node-fetch-server/README.md b/packages/node-fetch-server/README.md index 04b3324b512..06541571ea6 100644 --- a/packages/node-fetch-server/README.md +++ b/packages/node-fetch-server/README.md @@ -10,30 +10,30 @@ A basic benchmark shows `node-fetch-server` is able to serve more requests per s Platform: Darwin (23.5.0) CPU: Apple M1 Pro -Date: 8/31/2024, 12:14:41 PM +Date: 8/31/2024, 1:55:21 PM Running benchmark for node:http@22.1.0 ... Running 30s test @ http://127.0.0.1:3000/ 12 threads and 400 connections Thread Stats Avg Stdev Max +/- Stdev - Latency 31.70ms 109.12ms 2.00s 98.22% - Req/Sec 1.69k 342.98 2.99k 87.16% - 606083 requests in 30.10s, 124.27MB read - Socket errors: connect 0, read 633, write 117, timeout 20 -Requests/sec: 20135.72 -Transfer/sec: 4.13MB + Latency 37.16ms 127.85ms 1.93s 97.71% + Req/Sec 1.65k 380.84 4.42k 84.81% + 590123 requests in 30.09s, 121.00MB read + Socket errors: connect 0, read 432, write 224, timeout 0 +Requests/sec: 19612.18 +Transfer/sec: 4.02MB Running benchmark for node-fetch-server@0.1.0 ... Running 30s test @ http://127.0.0.1:3000/ 12 threads and 400 connections Thread Stats Avg Stdev Max +/- Stdev - Latency 42.37ms 96.58ms 2.00s 98.66% - Req/Sec 0.94k 255.57 3.01k 81.37% - 333862 requests in 30.10s, 68.46MB read - Socket errors: connect 0, read 419, write 10, timeout 168 -Requests/sec: 11091.24 + Latency 44.04ms 103.32ms 1.98s 98.46% + Req/Sec 0.93k 175.11 1.90k 81.25% + 332998 requests in 30.10s, 68.28MB read + Socket errors: connect 0, read 1394, write 115, timeout 152 +Requests/sec: 11062.58 Transfer/sec: 2.27MB Running benchmark for express@4.19.2 ... @@ -41,12 +41,12 @@ Running benchmark for express@4.19.2 ... Running 30s test @ http://127.0.0.1:3000/ 12 threads and 400 connections Thread Stats Avg Stdev Max +/- Stdev - Latency 48.42ms 95.22ms 2.00s 98.83% - Req/Sec 761.93 191.11 3.98k 79.46% - 272003 requests in 30.10s, 65.63MB read - Socket errors: connect 0, read 835, write 3, timeout 189 -Requests/sec: 9037.72 -Transfer/sec: 2.18MB + Latency 48.72ms 90.75ms 1.98s 98.88% + Req/Sec 746.08 249.77 4.40k 82.81% + 266534 requests in 30.10s, 64.31MB read + Socket errors: connect 0, read 745, write 60, timeout 186 +Requests/sec: 8854.66 +Transfer/sec: 2.14MB ``` I encourage you to run the benchmark yourself. To do so, you'll need to have [`wrk`](https://github.com/wg/wrk) installed. Then run: From dcdf88c029801fb8d792e2c45b1658c79c546e4a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 14:38:48 -0700 Subject: [PATCH 400/730] Client fields should always be set --- .../src/lib/request-listener.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index ed8c1448772..11e2f321634 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -15,19 +15,19 @@ export interface ClientAddr { * * [Node.js Reference](https://nodejs.org/api/net.html#socketremoteaddress) */ - address?: string; + address: string; /** - * The family of the IP address of the client that sent the request. Either `'IPv4'` or `'IPv6'`. + * The family of the client IP address. Either `"IPv4"` or `"IPv6"`. * * [Node.js Reference](https://nodejs.org/api/net.html#socketremotefamily) */ - family?: string; + family: string; /** - * The numeric representation of the remote port of the client that sent the request. + * The remote port of the client that sent the request. * * [Node.js Reference](https://nodejs.org/api/net.html#socketremoteport) */ - port?: number; + port: number; } /** @@ -94,9 +94,9 @@ export function createRequestListener( let url = new URL(req.url!, origin); let request = createRequest(req, res, url); let client: ClientAddr = { - address: req.socket.remoteAddress, - family: req.socket.remoteFamily, - port: req.socket.remotePort, + address: req.socket.remoteAddress!, + family: req.socket.remoteFamily!, + port: req.socket.remotePort!, }; try { From f0ed8a30c5e3aae722e7287f5c1fa9ee55fdf789 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 14:39:06 -0700 Subject: [PATCH 401/730] Small tweaks --- .../src/lib/request-listener.ts | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 11e2f321634..746a69ccc63 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -60,6 +60,13 @@ export interface RequestListenerOptions { /** * Overrides the origin of the incoming request URL. By default the request URL origin is derived * from the `Host` header and the connection protocol. + * + * For example, if you have a `$HOST` environment variable that contains the hostname of your + * server, you can use it to set the origin of all incoming request URLs like so: + * + * ```ts + * createRequestListener(handler, { origin: `http://${process.env.HOST}` }) + * ``` */ origin?: string; } @@ -104,8 +111,8 @@ export function createRequestListener( await sendResponse(res, response); } catch (error) { try { - let response = await onError(error); - await sendResponse(res, response ?? internalServerError()); + let errorResponse = await onError(error); + await sendResponse(res, errorResponse ?? internalServerError()); } catch (error) { console.error(`There was an error in the error handler: ${error}`); await sendResponse(res, internalServerError()); @@ -120,12 +127,19 @@ function defaultErrorHandler(error: unknown): Response { } function internalServerError(): Response { - return new Response('Internal Server Error', { - status: 500, - headers: { - 'Content-Type': 'text/plain', + return new Response( + // "Internal Server Error" + new Uint8Array([ + 73, 110, 116, 101, 114, 110, 97, 108, 32, 83, 101, 114, 118, 101, 114, 32, 69, 114, 114, 111, + 114, + ]), + { + status: 500, + headers: { + 'Content-Type': 'text/plain', + }, }, - }); + ); } function createRequest(req: http.IncomingMessage, res: http.ServerResponse, url: URL): Request { From e3e5c9162792ab691ae320b549863a6e138ae2c3 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 14:50:08 -0700 Subject: [PATCH 402/730] Small tweaks --- .../node-fetch-server/src/lib/request-listener.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 746a69ccc63..4fe0bda8b84 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -106,18 +106,19 @@ export function createRequestListener( port: req.socket.remotePort!, }; + let response: Response; try { - let response = await handler(request, client); - await sendResponse(res, response); + response = await handler(request, client); } catch (error) { try { - let errorResponse = await onError(error); - await sendResponse(res, errorResponse ?? internalServerError()); + response = (await onError(error)) ?? internalServerError(); } catch (error) { console.error(`There was an error in the error handler: ${error}`); - await sendResponse(res, internalServerError()); + response = internalServerError(); } } + + sendResponse(res, response); }; } @@ -207,9 +208,9 @@ async function sendResponse(res: http.ServerResponse, response: Response): Promi res.setHeader(name, value); } - res.flushHeaders(); - if (response.body != null) { + res.flushHeaders(); + for await (let chunk of response.body) { res.write(chunk); } From c7b36ccf01a9033c1a8f666f45cf11fa66da66d2 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 15:36:53 -0700 Subject: [PATCH 403/730] Update README --- packages/node-fetch-server/README.md | 54 ++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/packages/node-fetch-server/README.md b/packages/node-fetch-server/README.md index 06541571ea6..f50480ea53b 100644 --- a/packages/node-fetch-server/README.md +++ b/packages/node-fetch-server/README.md @@ -1,5 +1,55 @@ # node-fetch-server +`node-fetch-server` allows you to build servers for Node.js that use the [web Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) primitives (namely [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)) instead of the traditional `req`/`res` API used in libraries like [Express](https://expressjs.com/). + +This web standard API is already used in many places across the JavaScript ecosystem: + +- [`Bun.serve`](https://bun.sh/docs/api/http#bun-serve) +- [Cloudflare Workers](https://developers.cloudflare.com/workers/runtime-apis/handlers/fetch/) +- [`Deno.serve`](https://docs.deno.com/api/deno/~/Deno.serve) +- [Fastly Compute](https://js-compute-reference-docs.edgecompute.app/docs/) + +When you write servers using the `Request` and `Response` APIs, you maximize the chances that your code will be portable across all these different JavaScript runtimes. + +## Features + +- Use web standard [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) APIs for building servers, instead of node-specific API +- Seamless integration with `node:http` and `node:https` modules +- Supports streaming responses using `new Response(stream)` +- Exposes client IP info +- It's [faster than Express](#benchmark) + +## Installation + +```sh +npm install @mjackson/node-fetch-server +``` + +## Usage + +```ts +import * as http from 'node:http'; +import { type FetchHandler, createRequestListener } from '@mjackson/node-fetch-server'; + +let handler: FetchHandler = (request) => { + return new Response('Hello, world!'); +}; + +let server = http.createServer(createRequestListener(handler)); + +server.listen(3000); +``` + +Information about the remote client IP and port is passed as the 2nd argument to your `FetchHandler`: + +```ts +import { type FetchHandler } from '@mjackson/node-fetch-server'; + +let handler: FetchHandler = (request, client) => { + return new Response(`The client IP address is ${client.address}`); +}; +``` + ## Benchmark A basic benchmark shows `node-fetch-server` is able to serve more requests per second (and has higher overall throughput) than Express v4. The vanilla `node:http` module is also shown as a baseline for comparison. @@ -54,3 +104,7 @@ I encourage you to run the benchmark yourself. To do so, you'll need to have [`w ```sh pnpm run bench ``` + +## License + +See [LICENSE](https://github.com/mjackson/remix-the-web/blob/main/LICENSE) From 59be4bc947f85efcffee66b6fac30be4ca5ba910 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 16:03:35 -0700 Subject: [PATCH 404/730] Add host and protocol options, remove origin option --- .../src/lib/request-listener.spec.ts | 58 ++++++++++++++++++- .../src/lib/request-listener.ts | 43 +++++++------- 2 files changed, 78 insertions(+), 23 deletions(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.spec.ts b/packages/node-fetch-server/src/lib/request-listener.spec.ts index bddd48e6196..ceeeafdd789 100644 --- a/packages/node-fetch-server/src/lib/request-listener.spec.ts +++ b/packages/node-fetch-server/src/lib/request-listener.spec.ts @@ -4,8 +4,7 @@ import { describe, it, mock } from 'node:test'; import * as http from 'node:http'; import * as stream from 'node:stream'; -import { FetchHandler } from './fetch-handler.js'; -import { createRequestListener } from './request-listener.js'; +import { FetchHandler, createRequestListener } from './request-listener.js'; describe('createRequestListener', () => { it('returns a request listener', async () => { @@ -56,6 +55,60 @@ describe('createRequestListener', () => { listener(req, res); }); }); + + it('uses the `Host` header to construct the URL by default', async () => { + await new Promise((resolve) => { + let handler: FetchHandler = async (request) => { + assert.equal(request.url, 'http://example.com/'); + return new Response('Hello, world!'); + }; + + let listener = createRequestListener(handler); + assert.ok(listener); + + let req = createIncomingMessage({ headers: { host: 'example.com' } }); + let res = createServerResponse(); + + listener(req, res); + resolve(); + }); + }); + + it('uses the `host` option to override the `Host` header', async () => { + await new Promise((resolve) => { + let handler: FetchHandler = async (request) => { + assert.equal(request.url, 'http://remix.run/'); + return new Response('Hello, world!'); + }; + + let listener = createRequestListener(handler, { host: 'remix.run' }); + assert.ok(listener); + + let req = createIncomingMessage({ headers: { host: 'example.com' } }); + let res = createServerResponse(); + + listener(req, res); + resolve(); + }); + }); + + it('uses the `protocol` option to construct the URL', async () => { + await new Promise((resolve) => { + let handler: FetchHandler = async (request) => { + assert.equal(request.url, 'https://example.com/'); + return new Response('Hello, world!'); + }; + + let listener = createRequestListener(handler, { protocol: 'https:' }); + assert.ok(listener); + + let req = createIncomingMessage({ headers: { host: 'example.com' } }); + let res = createServerResponse(); + + listener(req, res); + resolve(); + }); + }); }); function createIncomingMessage({ @@ -95,6 +148,7 @@ function createServerResponse(): http.ServerResponse { statusCode: 200, statusMessage: 'OK', setHeader() {}, + flushHeaders() {}, write() {}, end() {}, }) as unknown as http.ServerResponse; diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 4fe0bda8b84..a92aeecdac4 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -1,14 +1,5 @@ import * as http from 'node:http'; -/** - * Returns the origin of an incoming request URL. - */ -export function getRequestOrigin(req: http.IncomingMessage): string { - let protocol = 'encrypted' in req.socket && req.socket.encrypted ? 'https:' : 'http:'; - let host = req.headers.host ?? 'localhost'; - return `${protocol}//${host}`; -} - export interface ClientAddr { /** * The IP address of the client that sent the request. @@ -53,22 +44,28 @@ export interface FetchHandler { export interface RequestListenerOptions { /** - * An error handler that determines the response when the request handler throws an error. By - * default a 500 Internal Server Error response will be sent. - */ - onError?: ErrorHandler; - /** - * Overrides the origin of the incoming request URL. By default the request URL origin is derived - * from the `Host` header and the connection protocol. + * Overrides the host portion of the incoming request URL. By default the request URL host is + * derived from the HTTP `Host` header. * * For example, if you have a `$HOST` environment variable that contains the hostname of your - * server, you can use it to set the origin of all incoming request URLs like so: + * server, you can use it to set the host of all incoming request URLs like so: * * ```ts - * createRequestListener(handler, { origin: `http://${process.env.HOST}` }) + * createRequestListener(handler, { host: process.env.HOST }) * ``` */ - origin?: string; + host?: string; + /** + * An error handler that determines the response when the request handler throws an error. By + * default a 500 Internal Server Error response will be sent. + */ + onError?: ErrorHandler; + /** + * Overrides the protocol of the incoming request URL. By default the request URL protocol is + * derived from the connection protocol. So e.g. when serving over HTTPS (using + * `https.createServer()`), the request URL will begin with `https:`. + */ + protocol?: string; } /** @@ -97,8 +94,12 @@ export function createRequestListener( let onError = options?.onError ?? defaultErrorHandler; return async (req, res) => { - let origin = options?.origin ?? getRequestOrigin(req); - let url = new URL(req.url!, origin); + let protocol = + (options?.protocol ?? ('encrypted' in req.socket && req.socket.encrypted)) + ? 'https:' + : 'http:'; + let host = options?.host ?? req.headers.host ?? 'localhost'; + let url = new URL(req.url!, `${protocol}//${host}`); let request = createRequest(req, res, url); let client: ClientAddr = { address: req.socket.remoteAddress!, From fa13fe6df509f4e4462cdf483ccd44f2b62a8908 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 16:10:37 -0700 Subject: [PATCH 405/730] Update README --- packages/node-fetch-server/README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/node-fetch-server/README.md b/packages/node-fetch-server/README.md index f50480ea53b..98266d28a19 100644 --- a/packages/node-fetch-server/README.md +++ b/packages/node-fetch-server/README.md @@ -15,6 +15,7 @@ When you write servers using the `Request` and `Response` APIs, you maximize the - Use web standard [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) APIs for building servers, instead of node-specific API - Seamless integration with `node:http` and `node:https` modules +- Supports custom hostnames (e.g. using `process.env.HOST` on a VPS to set the host portion of incoming request URLs) - Supports streaming responses using `new Response(stream)` - Exposes client IP info - It's [faster than Express](#benchmark) @@ -40,6 +41,24 @@ let server = http.createServer(createRequestListener(handler)); server.listen(3000); ``` +By default `request.url` is derived from the value of the `Host` HTTP header and the connection protocol being used. To support custom hostnames using e.g. a `$HOST` environment variable, you can use the `host` option: + +```ts +import * as assert from 'node:assert/strict'; +import * as http from 'node:http'; +import { type FetchHandler, createRequestListener } from '@mjackson/node-fetch-server'; + +let handler: FetchHandler = (request) => { + // This is now true + assert.equal(new URL(request.url).host, process.env.HOST); + return new Response('Hello, world!'); +}; + +let server = http.createServer(createRequestListener(handler, { host: process.env.HOST })); + +server.listen(3000); +``` + Information about the remote client IP and port is passed as the 2nd argument to your `FetchHandler`: ```ts From c6cd85f03b59318ebb9eb7991392939631c85fbb Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 16:24:38 -0700 Subject: [PATCH 406/730] Small tweak --- packages/node-fetch-server/src/lib/request-listener.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index a92aeecdac4..ff5aef1a5fe 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -95,9 +95,7 @@ export function createRequestListener( return async (req, res) => { let protocol = - (options?.protocol ?? ('encrypted' in req.socket && req.socket.encrypted)) - ? 'https:' - : 'http:'; + options?.protocol ?? ('encrypted' in req.socket && req.socket.encrypted ? 'https:' : 'http:'); let host = options?.host ?? req.headers.host ?? 'localhost'; let url = new URL(req.url!, `${protocol}//${host}`); let request = createRequest(req, res, url); From dce0f7496d9e448b32abf7e0265632182c25ebf1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 16:28:18 -0700 Subject: [PATCH 407/730] Remove export --- packages/node-fetch-server/src/lib/request-listener.ts | 2 +- packages/node-fetch-server/src/node-fetch-server.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index ff5aef1a5fe..16dc272b15d 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -28,7 +28,7 @@ export interface ClientAddr { * [MDN `Response` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Response) */ export interface ErrorHandler { - (error: unknown): Response | void | Promise; + (error: unknown): void | Response | Promise; } /** diff --git a/packages/node-fetch-server/src/node-fetch-server.ts b/packages/node-fetch-server/src/node-fetch-server.ts index 48961a2588a..ce7d4d7b7c0 100644 --- a/packages/node-fetch-server/src/node-fetch-server.ts +++ b/packages/node-fetch-server/src/node-fetch-server.ts @@ -3,6 +3,5 @@ export { type ErrorHandler, type FetchHandler, type RequestListenerOptions, - getRequestOrigin, createRequestListener, } from './lib/request-listener.js'; From b007b2c36f3c5c74b24ed25f71be7fb07a9dac23 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 16:30:06 -0700 Subject: [PATCH 408/730] Remove short name --- packages/headers/package.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/headers/package.json b/packages/headers/package.json index 8f36acd515d..9c2d22bf569 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -32,8 +32,5 @@ "http", "header", "headers" - ], - "nx": { - "name": "headers" - } + ] } From 9f02ea9ad3ff72dc5708696900487d170151684c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 16:30:18 -0700 Subject: [PATCH 409/730] Prep for release --- .nx/version-plans/version-plan-1725146936111.md | 5 +++++ packages/node-fetch-server/package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .nx/version-plans/version-plan-1725146936111.md diff --git a/.nx/version-plans/version-plan-1725146936111.md b/.nx/version-plans/version-plan-1725146936111.md new file mode 100644 index 00000000000..d23a2149398 --- /dev/null +++ b/.nx/version-plans/version-plan-1725146936111.md @@ -0,0 +1,5 @@ +--- +'@mjackson/node-fetch-server': minor +--- + +Initial release diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 1d23e91f0b0..9e5c0cef09e 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/node-fetch-server", - "version": "0.1.0", + "version": "0.0.0", "description": "Build servers for Node.js using the web fetch API", "author": "Michael Jackson ", "repository": { From 665feb5eb9d7f2e013c0c8ace5c77b6b64fe568c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 17:02:01 -0700 Subject: [PATCH 410/730] Add test for default error handling --- .../src/lib/request-listener.spec.ts | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/packages/node-fetch-server/src/lib/request-listener.spec.ts b/packages/node-fetch-server/src/lib/request-listener.spec.ts index ceeeafdd789..84b93fa15fc 100644 --- a/packages/node-fetch-server/src/lib/request-listener.spec.ts +++ b/packages/node-fetch-server/src/lib/request-listener.spec.ts @@ -56,6 +56,37 @@ describe('createRequestListener', () => { }); }); + it('returns a 500 "Internal Server Error" response when an error is thrown in the request handler', async () => { + await new Promise((resolve) => { + let handler: FetchHandler = async () => { + throw new Error('boom!'); + }; + let errorHandler = async () => { + // ignore + }; + + let listener = createRequestListener(handler, { onError: errorHandler }); + assert.ok(listener); + + let req = createIncomingMessage(); + let res = createServerResponse(); + + let chunks: Uint8Array[] = []; + mock.method(res, 'write', (chunk: Uint8Array) => { + chunks.push(chunk); + }); + + mock.method(res, 'end', () => { + assert.equal(res.statusCode, 500); + let body = Buffer.concat(chunks).toString(); + assert.equal(body, 'Internal Server Error'); + resolve(); + }); + + listener(req, res); + }); + }); + it('uses the `Host` header to construct the URL by default', async () => { await new Promise((resolve) => { let handler: FetchHandler = async (request) => { From 051e70fb16805b80a97246e4a5f0143eeb40ad07 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 17:10:43 -0700 Subject: [PATCH 411/730] Allow node to determine status message automatically --- packages/node-fetch-server/src/lib/request-listener.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 16dc272b15d..d19eceaa4d7 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -201,7 +201,6 @@ function createBody(req: http.IncomingMessage): ReadableStream { async function sendResponse(res: http.ServerResponse, response: Response): Promise { res.statusCode = response.status; - res.statusMessage = response.statusText; for (let [name, value] of response.headers.entries()) { res.setHeader(name, value); From 9130938bb177835775cc10103211fc6211687eaa Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 17:41:35 -0700 Subject: [PATCH 412/730] Use res.writeHead --- packages/node-fetch-server/bench/servers/node-http.ts | 3 +-- packages/node-fetch-server/src/lib/request-listener.ts | 9 ++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/node-fetch-server/bench/servers/node-http.ts b/packages/node-fetch-server/bench/servers/node-http.ts index 8da1c473428..41c283f28e1 100644 --- a/packages/node-fetch-server/bench/servers/node-http.ts +++ b/packages/node-fetch-server/bench/servers/node-http.ts @@ -4,8 +4,7 @@ import * as stream from 'node:stream'; const PORT = process.env.PORT || 3000; let server = http.createServer((_req, res) => { - res.setHeader('Content-Type', 'text/html'); - res.flushHeaders(); + res.writeHead(200, { 'Content-Type': 'text/html' }); let body = new stream.Readable({ read() { diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index d19eceaa4d7..743c25c0714 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -200,15 +200,14 @@ function createBody(req: http.IncomingMessage): ReadableStream { } async function sendResponse(res: http.ServerResponse, response: Response): Promise { - res.statusCode = response.status; - + let headers: Record = {}; for (let [name, value] of response.headers.entries()) { - res.setHeader(name, value); + headers[name] = value; } - if (response.body != null) { - res.flushHeaders(); + res.writeHead(response.status, headers); + if (response.body != null) { for await (let chunk of response.body) { res.write(chunk); } From 7339712b4b0e650466debd35a317093801497e9f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 17:49:47 -0700 Subject: [PATCH 413/730] Use Object.fromEntries --- packages/node-fetch-server/README.md | 42 +++++++++---------- .../src/lib/request-listener.ts | 5 +-- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/packages/node-fetch-server/README.md b/packages/node-fetch-server/README.md index 98266d28a19..d5f242e8e62 100644 --- a/packages/node-fetch-server/README.md +++ b/packages/node-fetch-server/README.md @@ -74,48 +74,48 @@ let handler: FetchHandler = (request, client) => { A basic benchmark shows `node-fetch-server` is able to serve more requests per second (and has higher overall throughput) than Express v4. The vanilla `node:http` module is also shown as a baseline for comparison. ``` -> @mjackson/node-fetch-server@0.1.0 bench /Users/michael/Projects/remix-the-web/packages/node-fetch-server +> @mjackson/node-fetch-server@0.0.0 bench /Users/michael/Projects/remix-the-web/packages/node-fetch-server > bash ./bench/runner.sh Platform: Darwin (23.5.0) CPU: Apple M1 Pro -Date: 8/31/2024, 1:55:21 PM +Date: 8/31/2024, 5:43:47 PM Running benchmark for node:http@22.1.0 ... Running 30s test @ http://127.0.0.1:3000/ 12 threads and 400 connections Thread Stats Avg Stdev Max +/- Stdev - Latency 37.16ms 127.85ms 1.93s 97.71% - Req/Sec 1.65k 380.84 4.42k 84.81% - 590123 requests in 30.09s, 121.00MB read - Socket errors: connect 0, read 432, write 224, timeout 0 -Requests/sec: 19612.18 -Transfer/sec: 4.02MB + Latency 22.28ms 71.96ms 1.36s 98.37% + Req/Sec 2.37k 538.29 9.51k 85.30% + 848851 requests in 30.10s, 174.05MB read + Socket errors: connect 0, read 544, write 27, timeout 0 +Requests/sec: 28198.41 +Transfer/sec: 5.78MB -Running benchmark for node-fetch-server@0.1.0 ... +Running benchmark for node-fetch-server@0.0.0 ... Running 30s test @ http://127.0.0.1:3000/ 12 threads and 400 connections Thread Stats Avg Stdev Max +/- Stdev - Latency 44.04ms 103.32ms 1.98s 98.46% - Req/Sec 0.93k 175.11 1.90k 81.25% - 332998 requests in 30.10s, 68.28MB read - Socket errors: connect 0, read 1394, write 115, timeout 152 -Requests/sec: 11062.58 -Transfer/sec: 2.27MB + Latency 42.57ms 109.55ms 2.00s 98.37% + Req/Sec 1.03k 282.58 2.78k 77.37% + 368110 requests in 30.10s, 75.48MB read + Socket errors: connect 0, read 717, write 152, timeout 126 +Requests/sec: 12228.31 +Transfer/sec: 2.51MB Running benchmark for express@4.19.2 ... Running 30s test @ http://127.0.0.1:3000/ 12 threads and 400 connections Thread Stats Avg Stdev Max +/- Stdev - Latency 48.72ms 90.75ms 1.98s 98.88% - Req/Sec 746.08 249.77 4.40k 82.81% - 266534 requests in 30.10s, 64.31MB read - Socket errors: connect 0, read 745, write 60, timeout 186 -Requests/sec: 8854.66 -Transfer/sec: 2.14MB + Latency 48.76ms 87.38ms 2.00s 98.90% + Req/Sec 734.60 190.17 3.03k 79.08% + 261725 requests in 30.09s, 63.15MB read + Socket errors: connect 0, read 1259, write 110, timeout 200 +Requests/sec: 8696.85 +Transfer/sec: 2.10MB ``` I encourage you to run the benchmark yourself. To do so, you'll need to have [`wrk`](https://github.com/wg/wrk) installed. Then run: diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 743c25c0714..95090315adf 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -200,10 +200,7 @@ function createBody(req: http.IncomingMessage): ReadableStream { } async function sendResponse(res: http.ServerResponse, response: Response): Promise { - let headers: Record = {}; - for (let [name, value] of response.headers.entries()) { - headers[name] = value; - } + let headers = Object.fromEntries(response.headers.entries()); res.writeHead(response.status, headers); From bbfc533e4e8dd5da7eb12706c24fe8e9f495b9c6 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 17:55:37 -0700 Subject: [PATCH 414/730] Small tweak --- packages/node-fetch-server/src/lib/request-listener.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 95090315adf..a9563ad4e72 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -200,9 +200,7 @@ function createBody(req: http.IncomingMessage): ReadableStream { } async function sendResponse(res: http.ServerResponse, response: Response): Promise { - let headers = Object.fromEntries(response.headers.entries()); - - res.writeHead(response.status, headers); + res.writeHead(response.status, Object.fromEntries(response.headers.entries())); if (response.body != null) { for await (let chunk of response.body) { From abdda11a0af0899aad63b2b1016a101e1b60f72f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 22:03:27 -0700 Subject: [PATCH 415/730] Formatting tweaks --- packages/lazy-file/README.md | 6 +- packages/lazy-file/src/fs.ts | 8 +- packages/lazy-file/src/lib/byte-range.spec.ts | 14 +- packages/lazy-file/src/lib/byte-range.ts | 11 +- packages/lazy-file/src/lib/lazy-file.spec.ts | 130 +++++++++--------- packages/lazy-file/src/lib/lazy-file.ts | 34 ++--- 6 files changed, 91 insertions(+), 112 deletions(-) diff --git a/packages/lazy-file/README.md b/packages/lazy-file/README.md index 0627489b2a3..7983b562894 100644 --- a/packages/lazy-file/README.md +++ b/packages/lazy-file/README.md @@ -16,7 +16,7 @@ It allows you to easily create [Blob](https://developer.mozilla.org/en-US/docs/W JavaScript's [File API](https://developer.mozilla.org/en-US/docs/Web/API/File) is useful, but it's not a great fit for streaming server environments where you don't want to buffer file contents. In particular, [`the File() constructor`](https://developer.mozilla.org/en-US/docs/Web/API/File/File) requires the contents of a file to be supplied up front when the object is first created, like this: ```ts -let file = new File(["hello world"], "hello.txt", { type: "text/plain" }); +let file = new File(['hello world'], 'hello.txt', { type: 'text/plain' }); ``` A `LazyFile` improves this model by accepting an additional content type in its constructor: `LazyContent`. @@ -25,7 +25,7 @@ A `LazyFile` improves this model by accepting an additional content type in its let lazyContent: LazyContent = { /* See below for usage */ }; -let file = new File(lazyContent, "hello.txt", { type: "text/plain" }); +let file = new File(lazyContent, 'hello.txt', { type: 'text/plain' }); ``` All other `File` functionality works as you'd expect. @@ -43,7 +43,7 @@ npm install @mjackson/lazy-file The low-level API can be used to create a `File` that streams content from anywhere: ```ts -import { type LazyContent, LazyFile } from "@mjackson/lazy-file"; +import { type LazyContent, LazyFile } from '@mjackson/lazy-file'; let content: LazyContent = { // The total length of this file in bytes. diff --git a/packages/lazy-file/src/fs.ts b/packages/lazy-file/src/fs.ts index 75ce978fd14..c58a69dc08c 100644 --- a/packages/lazy-file/src/fs.ts +++ b/packages/lazy-file/src/fs.ts @@ -1,8 +1,8 @@ -import * as fs from "node:fs"; -import * as path from "node:path"; -import { lookup } from "mrmime"; +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { lookup } from 'mrmime'; -import { LazyContent, LazyFile } from "./lib/lazy-file.js"; +import { LazyContent, LazyFile } from './lib/lazy-file.js'; export interface GetFileOptions { /** diff --git a/packages/lazy-file/src/lib/byte-range.spec.ts b/packages/lazy-file/src/lib/byte-range.spec.ts index ccdb66977d4..8bcab887b39 100644 --- a/packages/lazy-file/src/lib/byte-range.spec.ts +++ b/packages/lazy-file/src/lib/byte-range.spec.ts @@ -1,10 +1,10 @@ -import * as assert from "node:assert/strict"; -import { describe, it } from "node:test"; +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; -import { ByteRange, getByteLength, getIndexes } from "./byte-range.js"; +import { ByteRange, getByteLength, getIndexes } from './byte-range.js'; -describe("getByteLength", () => { - it("returns the correct length", () => { +describe('getByteLength', () => { + it('returns the correct length', () => { let size = 100; let range: ByteRange = { start: 10, end: 20 }; @@ -30,8 +30,8 @@ describe("getByteLength", () => { }); }); -describe("getIndexes", () => { - it("returns the correct indexes", () => { +describe('getIndexes', () => { + it('returns the correct indexes', () => { let size = 100; let range: ByteRange = { start: 10, end: 20 }; diff --git a/packages/lazy-file/src/lib/byte-range.ts b/packages/lazy-file/src/lib/byte-range.ts index 741e2afed1b..13d78370d1d 100644 --- a/packages/lazy-file/src/lib/byte-range.ts +++ b/packages/lazy-file/src/lib/byte-range.ts @@ -23,14 +23,7 @@ export function getByteLength(range: ByteRange, size: number): number { * Resolves a byte range to absolute indexes in a buffer of the given `size`. */ export function getIndexes(range: ByteRange, size: number): [number, number] { - let start = Math.min( - Math.max(0, range.start < 0 ? size + range.start : range.start), - size - ); - let end = Math.min( - Math.max(start, range.end < 0 ? size + range.end : range.end), - size - ); - + let start = Math.min(Math.max(0, range.start < 0 ? size + range.start : range.start), size); + let end = Math.min(Math.max(start, range.end < 0 ? size + range.end : range.end), size); return [start, end]; } diff --git a/packages/lazy-file/src/lib/lazy-file.spec.ts b/packages/lazy-file/src/lib/lazy-file.spec.ts index 8228e9328f5..08f5251739e 100644 --- a/packages/lazy-file/src/lib/lazy-file.spec.ts +++ b/packages/lazy-file/src/lib/lazy-file.spec.ts @@ -1,9 +1,9 @@ -import * as assert from "node:assert/strict"; -import { describe, it } from "node:test"; +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; -import { LazyContent, LazyFile } from "./lazy-file.js"; +import { LazyContent, LazyFile } from './lazy-file.js'; -function createLazyContent(value = ""): LazyContent { +function createLazyContent(value = ''): LazyContent { let buffer = new TextEncoder().encode(value); return { byteLength: buffer.byteLength, @@ -12,142 +12,140 @@ function createLazyContent(value = ""): LazyContent { start(controller) { controller.enqueue(buffer); controller.close(); - } + }, }); - } + }, }; } -describe("LazyFile", () => { - it("has the correct name, size, type, and lastModified timestamp", () => { +describe('LazyFile', () => { + it('has the correct name, size, type, and lastModified timestamp', () => { let now = Date.now(); - let file = new LazyFile(createLazyContent("X".repeat(100)), "example.txt", { - type: "text/plain", - lastModified: now + let file = new LazyFile(createLazyContent('X'.repeat(100)), 'example.txt', { + type: 'text/plain', + lastModified: now, }); - assert.equal(file.name, "example.txt"); + assert.equal(file.name, 'example.txt'); assert.equal(file.size, 100); - assert.equal(file.type, "text/plain"); + assert.equal(file.type, 'text/plain'); assert.equal(file.lastModified, now); }); - it("can be initialized with a [Blob] as the content", async () => { - let content = [new Blob(["hello world"], { type: "text/plain" })]; - let file = new LazyFile(content, "hello.txt", { type: "text/plain" }); + it('can be initialized with a [Blob] as the content', async () => { + let content = [new Blob(['hello world'], { type: 'text/plain' })]; + let file = new LazyFile(content, 'hello.txt', { type: 'text/plain' }); assert.equal(file.size, 11); - assert.equal("hello world", await file.text()); + assert.equal('hello world', await file.text()); }); - it("can be initialized with another LazyFile as the content", async () => { - let content = [ - new LazyFile(["hello world"], "hello.txt", { type: "text/plain" }) - ]; - let file = new LazyFile(content, "hello.txt", { type: "text/plain" }); + it('can be initialized with another LazyFile as the content', async () => { + let content = [new LazyFile(['hello world'], 'hello.txt', { type: 'text/plain' })]; + let file = new LazyFile(content, 'hello.txt', { type: 'text/plain' }); assert.equal(file.size, 11); - assert.equal("hello world", await file.text()); + assert.equal('hello world', await file.text()); }); - it("can be initialized with multiple Blobs and strings as the content and can slice them correctly", async () => { + it('can be initialized with multiple Blobs and strings as the content and can slice them correctly', async () => { let parts = [ - new Blob([" hello "], { type: "text/plain" }), - "world", - new Blob(["!", " "], { type: "text/plain" }), - "extra stuff" + new Blob([' hello '], { type: 'text/plain' }), + 'world', + new Blob(['!', ' '], { type: 'text/plain' }), + 'extra stuff', ]; - let file = new LazyFile(parts, "hello.txt", { type: "text/plain" }); + let file = new LazyFile(parts, 'hello.txt', { type: 'text/plain' }); assert.equal(file.size, 27); - assert.equal(await file.slice(2, -13).text(), "hello world!"); + assert.equal(await file.slice(2, -13).text(), 'hello world!'); }); it("returns the file's contents as a stream", async () => { - let content = createLazyContent("hello world"); - let file = new LazyFile(content, "hello.txt", { type: "text/plain" }); + let content = createLazyContent('hello world'); + let file = new LazyFile(content, 'hello.txt', { type: 'text/plain' }); let decoder = new TextDecoder(); - let result = ""; + let result = ''; for await (let chunk of file.stream()) { result += decoder.decode(chunk, { stream: true }); } result += decoder.decode(); - assert.equal(result, "hello world"); + assert.equal(result, 'hello world'); }); it("returns the file's contents as a string", async () => { - let content = createLazyContent("hello world"); - let file = new LazyFile(content, "hello.txt", { - type: "text/plain" + let content = createLazyContent('hello world'); + let file = new LazyFile(content, 'hello.txt', { + type: 'text/plain', }); - assert.equal(await file.text(), "hello world"); + assert.equal(await file.text(), 'hello world'); }); - describe("slice()", () => { - it("returns a file with the same size as the original when slicing from 0 to the end", () => { - let file = new LazyFile(createLazyContent("hello world"), "hello.txt", { - type: "text/plain" + describe('slice()', () => { + it('returns a file with the same size as the original when slicing from 0 to the end', () => { + let file = new LazyFile(createLazyContent('hello world'), 'hello.txt', { + type: 'text/plain', }); let slice = file.slice(0); assert.equal(slice.size, file.size); }); it('returns a file with size 0 when the "start" index is greater than the content length', () => { - let file = new LazyFile(["hello world"], "hello.txt", { - type: "text/plain" + let file = new LazyFile(['hello world'], 'hello.txt', { + type: 'text/plain', }); let slice = file.slice(100); assert.equal(slice.size, 0); }); it('returns a file with size 0 when the "start" index is greater than the "end" index', () => { - let file = new LazyFile(["hello world"], "hello.txt", { - type: "text/plain" + let file = new LazyFile(['hello world'], 'hello.txt', { + type: 'text/plain', }); let slice = file.slice(5, 0); assert.equal(slice.size, 0); }); - it("calls content.stream() with the correct range", t => { - let content = createLazyContent("X".repeat(100)); - let read = t.mock.method(content, "stream"); - let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + it('calls content.stream() with the correct range', (t) => { + let content = createLazyContent('X'.repeat(100)); + let read = t.mock.method(content, 'stream'); + let file = new LazyFile(content, 'example.txt', { type: 'text/plain' }); file.slice(10, 20).stream(); assert.equal(read.mock.calls.length, 1); assert.deepEqual(read.mock.calls[0].arguments, [10, 20]); }); - it('calls content.stream() with the correct range when slicing a file with a negative "start" index', t => { - let content = createLazyContent("X".repeat(100)); - let read = t.mock.method(content, "stream"); - let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + it('calls content.stream() with the correct range when slicing a file with a negative "start" index', (t) => { + let content = createLazyContent('X'.repeat(100)); + let read = t.mock.method(content, 'stream'); + let file = new LazyFile(content, 'example.txt', { type: 'text/plain' }); file.slice(-10).stream(); assert.equal(read.mock.calls.length, 1); assert.deepEqual(read.mock.calls[0].arguments, [90, 100]); }); - it('calls content.stream() with the correct range when slicing a file with a negative "end" index', t => { - let content = createLazyContent("X".repeat(100)); - let read = t.mock.method(content, "stream"); - let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + it('calls content.stream() with the correct range when slicing a file with a negative "end" index', (t) => { + let content = createLazyContent('X'.repeat(100)); + let read = t.mock.method(content, 'stream'); + let file = new LazyFile(content, 'example.txt', { type: 'text/plain' }); file.slice(0, -10).stream(); assert.equal(read.mock.calls.length, 1); assert.deepEqual(read.mock.calls[0].arguments, [0, 90]); }); - it('calls content.stream() with the correct range when slicing a file with negative "start" and "end" indexes', t => { - let content = createLazyContent("X".repeat(100)); - let read = t.mock.method(content, "stream"); - let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + it('calls content.stream() with the correct range when slicing a file with negative "start" and "end" indexes', (t) => { + let content = createLazyContent('X'.repeat(100)); + let read = t.mock.method(content, 'stream'); + let file = new LazyFile(content, 'example.txt', { type: 'text/plain' }); file.slice(-20, -10).stream(); assert.equal(read.mock.calls.length, 1); assert.deepEqual(read.mock.calls[0].arguments, [80, 90]); }); - it('calls content.stream() with the correct range when slicing a file with a "start" index greater than the "end" index', t => { - let content = createLazyContent("X".repeat(100)); - let read = t.mock.method(content, "stream"); - let file = new LazyFile(content, "example.txt", { type: "text/plain" }); + it('calls content.stream() with the correct range when slicing a file with a "start" index greater than the "end" index', (t) => { + let content = createLazyContent('X'.repeat(100)); + let read = t.mock.method(content, 'stream'); + let file = new LazyFile(content, 'example.txt', { type: 'text/plain' }); file.slice(20, 10).stream(); assert.equal(read.mock.calls.length, 1); assert.deepEqual(read.mock.calls[0].arguments, [20, 20]); diff --git a/packages/lazy-file/src/lib/lazy-file.ts b/packages/lazy-file/src/lib/lazy-file.ts index 3664dda0306..91cd8c3e5d9 100644 --- a/packages/lazy-file/src/lib/lazy-file.ts +++ b/packages/lazy-file/src/lib/lazy-file.ts @@ -1,4 +1,4 @@ -import { ByteRange, getByteLength, getIndexes } from "./byte-range.js"; +import { ByteRange, getByteLength, getIndexes } from './byte-range.js'; /** * A streaming interface for blob/file content. @@ -132,11 +132,7 @@ export interface LazyFileOptions extends LazyBlobOptions { export class LazyFile extends File { readonly #content: BlobContent; - constructor( - parts: BlobPart[] | LazyContent, - name: string, - options?: LazyFileOptions - ) { + constructor(parts: BlobPart[] | LazyContent, name: string, options?: LazyFileOptions) { super([], name, options); this.#content = new BlobContent(parts, options); } @@ -213,14 +209,10 @@ class BlobContent { this.totalSize += part.size; } else { let array: Uint8Array; - if (typeof part === "string") { + if (typeof part === 'string') { array = new TextEncoder().encode(part); } else if (ArrayBuffer.isView(part)) { - array = new Uint8Array( - part.buffer, - part.byteOffset, - part.byteLength - ); + array = new Uint8Array(part.buffer, part.byteOffset, part.byteLength); } else { array = new Uint8Array(part); } @@ -235,7 +227,7 @@ class BlobContent { } this.range = options?.range; - this.type = options?.type ?? ""; + this.type = options?.type ?? ''; } async arrayBuffer(): Promise { @@ -255,12 +247,10 @@ class BlobContent { } get size(): number { - return this.range != null - ? getByteLength(this.range, this.totalSize) - : this.totalSize; + return this.range != null ? getByteLength(this.range, this.totalSize) : this.totalSize; } - slice(start = 0, end?: number, contentType = ""): LazyBlob { + slice(start = 0, end?: number, contentType = ''): LazyBlob { let range: ByteRange = this.range != null ? // file.slice().slice() is additive @@ -278,20 +268,18 @@ class BlobContent { : this.source.stream(start, end); } - return Array.isArray(this.source) - ? streamContentArray(this.source) - : this.source.stream(); + return Array.isArray(this.source) ? streamContentArray(this.source) : this.source.stream(); } async text(): Promise { - return new TextDecoder("utf-8").decode(await this.bytes()); + return new TextDecoder('utf-8').decode(await this.bytes()); } } function streamContentArray( content: (Blob | Uint8Array)[], start = 0, - end = Infinity + end = Infinity, ): ReadableStream { let index = 0; let bytesRead = 0; @@ -347,6 +335,6 @@ function streamContentArray( break; } } - } + }, }); } From 3d28d9a7305411b7e285e8e4e91ee1b0b7c2a9d8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 31 Aug 2024 22:05:10 -0700 Subject: [PATCH 416/730] Add writeFile, rename getFile => openFile --- .../version-plan-1725167067278.md | 5 +++ packages/lazy-file/README.md | 22 ++++++----- packages/lazy-file/src/fs.ts | 39 +++++++++++++------ 3 files changed, 46 insertions(+), 20 deletions(-) create mode 100644 .nx/version-plans/version-plan-1725167067278.md diff --git a/.nx/version-plans/version-plan-1725167067278.md b/.nx/version-plans/version-plan-1725167067278.md new file mode 100644 index 00000000000..795622e31cd --- /dev/null +++ b/.nx/version-plans/version-plan-1725167067278.md @@ -0,0 +1,5 @@ +--- +'@mjackson/lazy-file': minor +--- + +Add writeFile method to lazy-file/fs and rename getFile => openFile diff --git a/packages/lazy-file/README.md b/packages/lazy-file/README.md index 7983b562894..51314246712 100644 --- a/packages/lazy-file/README.md +++ b/packages/lazy-file/README.md @@ -54,40 +54,44 @@ let content: LazyContent = { // ... read the file contents from somewhere and return a ReadableStream return new ReadableStream({ start(controller) { - controller.enqueue("X".repeat(100000).slice(start, end)); + controller.enqueue('X'.repeat(100000).slice(start, end)); controller.close(); - } + }, }); - } + }, }; -let file = new LazyFile(content, "example.txt", { type: "text/plain" }); +let file = new LazyFile(content, 'example.txt', { type: 'text/plain' }); await file.arrayBuffer(); // ArrayBuffer of the file's content file.name; // "example.txt" file.type; // "text/plain" ``` -The `lazy-file/fs` export provides a `getFile(filename)` function that allows you to create `File` objects from files on the local filesystem. These objects are lightweight and do not attempt to actually read from the file on disk until contents are requested. +The `lazy-file/fs` export provides functions for reading from and writing to the local filesystem using the `File` API. ```ts -import { getFile } from "@mjackson/lazy-file/fs"; +import { openFile, writeFile } from '@mjackson/lazy-file/fs'; // No data is read at this point, it's just a reference to a // file on the local filesystem. -let file = getFile("./path/to/file.json"); +let file = openFile('./path/to/file.json'); // Data is read when you call file.text() (or any of the // other Blob methods, like file.bytes(), file.stream(), etc.) let json = JSON.parse(await file.text()); -let imageFile = getFile("./path/to/image.jpg"); +// Write the file's contents back to the filesystem at a +// different path. +await writeFile('./path/to/other-file.json', file); + +let imageFile = openFile('./path/to/image.jpg'); // Get a LazyBlob that omits the first 100 bytes of the file. // This could be useful for serving HTTP Range requests. let blob = imageFile.slice(100); ``` -`lazy-file/fs` also serves as a good reference implementation for how to use this library effectively. +All file contents are read on-demand and nothing is ever buffered. ## Related Packages diff --git a/packages/lazy-file/src/fs.ts b/packages/lazy-file/src/fs.ts index c58a69dc08c..9c7378f1574 100644 --- a/packages/lazy-file/src/fs.ts +++ b/packages/lazy-file/src/fs.ts @@ -24,7 +24,7 @@ export interface GetFileOptions { * * [MDN `File` Reference](https://developer.mozilla.org/en-US/docs/Web/API/File) */ -export function getFile(filename: string, options?: GetFileOptions): File { +export function openFile(filename: string, options?: GetFileOptions): File { let stats = fs.statSync(filename); if (!stats.isFile()) { @@ -35,20 +35,16 @@ export function getFile(filename: string, options?: GetFileOptions): File { byteLength: stats.size, stream(start, end) { return streamFile(filename, start, end); - } + }, }; return new LazyFile(content, options?.name ?? path.basename(filename), { type: options?.type ?? lookup(filename), - lastModified: options?.lastModified ?? stats.mtimeMs + lastModified: options?.lastModified ?? stats.mtimeMs, }); } -function streamFile( - filename: string, - start = 0, - end = Infinity -): ReadableStream { +function streamFile(filename: string, start = 0, end = Infinity): ReadableStream { let read = fs.createReadStream(filename, { start, end: end - 1 }).iterator(); return new ReadableStream({ @@ -58,10 +54,31 @@ function streamFile( if (done) { controller.close(); } else { - controller.enqueue( - new Uint8Array(value.buffer, value.byteOffset, value.byteLength) - ); + controller.enqueue(new Uint8Array(value.buffer, value.byteOffset, value.byteLength)); } + }, + }); +} + +// Preserve backwards compat with v3.0 +export { openFile as getFile }; + +/** + * Writes a `File` to the local filesytem with the given `filename` and resolves when the stream is + * finished. + * + * [MDN `File` Reference](https://developer.mozilla.org/en-US/docs/Web/API/File) + */ +export function writeFile(filename: string, file: File): Promise { + return new Promise(async (resolve) => { + let write = fs.createWriteStream(filename); + + for await (let chunk of file.stream()) { + write.write(chunk); } + + write.end(() => { + resolve(); + }); }); } From 596b43b514f72c57226d4e7e4fd56cd85576d2ff Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 1 Sep 2024 16:03:47 -0700 Subject: [PATCH 417/730] Small, internal tweaks --- .../src/lib/request-listener.ts | 39 ++++++++----------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index a9563ad4e72..a2c876ae7b8 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -69,14 +69,14 @@ export interface RequestListenerOptions { } /** - * Wraps a `RequestHandler` function in a Node.js `http.RequestListener` that can be used with + * Wraps a fetch handler in a Node.js `http.RequestListener` that can be used with * `http.createServer()` or `https.createServer()`. * * ```ts * import * as http from 'node:http'; - * import { type RequestHandler, createRequestListener } from '@mjackson/node-fetch-server'; + * import { type FetchHandler, createRequestListener } from '@mjackson/node-fetch-server'; * - * let handler: RequestHandler = async (request) => { + * let handler: FetchHandler = async (request) => { * return new Response('Hello, world!'); * }; * @@ -98,7 +98,13 @@ export function createRequestListener( options?.protocol ?? ('encrypted' in req.socket && req.socket.encrypted ? 'https:' : 'http:'); let host = options?.host ?? req.headers.host ?? 'localhost'; let url = new URL(req.url!, `${protocol}//${host}`); - let request = createRequest(req, res, url); + + let controller = new AbortController(); + res.on('close', () => { + controller.abort(); + }); + + let request = createRequest(req, url, controller.signal); let client: ClientAddr = { address: req.socket.remoteAddress!, family: req.socket.remoteFamily!, @@ -142,16 +148,11 @@ function internalServerError(): Response { ); } -function createRequest(req: http.IncomingMessage, res: http.ServerResponse, url: URL): Request { - let controller = new AbortController(); - res.on('close', () => { - controller.abort(); - }); - +function createRequest(req: http.IncomingMessage, url: URL, signal: AbortSignal): Request { let init: RequestInit = { method: req.method, - headers: createHeaders(req.headers), - signal: controller.signal, + headers: createHeaders(req.rawHeaders), + signal, }; if (req.method !== 'GET' && req.method !== 'HEAD') { @@ -167,19 +168,11 @@ function createRequest(req: http.IncomingMessage, res: http.ServerResponse, url: return new Request(url, init); } -function createHeaders(incoming: http.IncomingHttpHeaders): Headers { +function createHeaders(rawHeaders: string[]): Headers { let headers = new Headers(); - for (let key in incoming) { - let value = incoming[key]; - - if (Array.isArray(value)) { - for (let v of value) { - headers.append(key, v); - } - } else if (value != null) { - headers.set(key, value); - } + for (let i = 0; i < rawHeaders.length; i += 2) { + headers.append(rawHeaders[i], rawHeaders[i + 1]); } return headers; From 571daf9eed0e802eb1f7fff26fb31dd731e2c36d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 1 Sep 2024 17:15:33 -0700 Subject: [PATCH 418/730] Switch back to iterating over req.headers --- packages/node-fetch-server/README.md | 2 +- .../src/lib/request-listener.ts | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/node-fetch-server/README.md b/packages/node-fetch-server/README.md index d5f242e8e62..7cce7b773ee 100644 --- a/packages/node-fetch-server/README.md +++ b/packages/node-fetch-server/README.md @@ -9,7 +9,7 @@ This web standard API is already used in many places across the JavaScript ecosy - [`Deno.serve`](https://docs.deno.com/api/deno/~/Deno.serve) - [Fastly Compute](https://js-compute-reference-docs.edgecompute.app/docs/) -When you write servers using the `Request` and `Response` APIs, you maximize the chances that your code will be portable across all these different JavaScript runtimes. +When you write servers using the `Request` and `Response` APIs, you maximize the chances that your code will be portable across these different JavaScript runtimes. ## Features diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index a2c876ae7b8..f7b34a7ff4f 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -151,7 +151,7 @@ function internalServerError(): Response { function createRequest(req: http.IncomingMessage, url: URL, signal: AbortSignal): Request { let init: RequestInit = { method: req.method, - headers: createHeaders(req.rawHeaders), + headers: createHeaders(req.headers), signal, }; @@ -168,11 +168,19 @@ function createRequest(req: http.IncomingMessage, url: URL, signal: AbortSignal) return new Request(url, init); } -function createHeaders(rawHeaders: string[]): Headers { +function createHeaders(incoming: http.IncomingHttpHeaders): Headers { let headers = new Headers(); - for (let i = 0; i < rawHeaders.length; i += 2) { - headers.append(rawHeaders[i], rawHeaders[i + 1]); + for (let key in incoming) { + let value = incoming[key]; + + if (Array.isArray(value)) { + for (let item of value) { + headers.append(key, item); + } + } else if (value != null) { + headers.append(key, value); + } } return headers; From c6fc9e428b924bb3917d8a642259f92f95dfb663 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 1 Sep 2024 20:19:49 -0700 Subject: [PATCH 419/730] Add test for Set-Cookie special case --- .../src/lib/request-listener.spec.ts | 49 +++++++++++++++++-- .../src/lib/request-listener.ts | 18 +++++-- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.spec.ts b/packages/node-fetch-server/src/lib/request-listener.spec.ts index 84b93fa15fc..7eae03c41f5 100644 --- a/packages/node-fetch-server/src/lib/request-listener.spec.ts +++ b/packages/node-fetch-server/src/lib/request-listener.spec.ts @@ -71,13 +71,18 @@ describe('createRequestListener', () => { let req = createIncomingMessage(); let res = createServerResponse(); + let status: number | undefined; + mock.method(res, 'writeHead', (statusCode: number) => { + status = statusCode; + }); + let chunks: Uint8Array[] = []; mock.method(res, 'write', (chunk: Uint8Array) => { chunks.push(chunk); }); mock.method(res, 'end', () => { - assert.equal(res.statusCode, 500); + assert.equal(status, 500); let body = Buffer.concat(chunks).toString(); assert.equal(body, 'Internal Server Error'); resolve(); @@ -140,6 +145,43 @@ describe('createRequestListener', () => { resolve(); }); }); + + it('sets multiple Set-Cookie headers', async () => { + await new Promise((resolve) => { + let handler: FetchHandler = async () => { + let headers = new Headers(); + headers.set('Content-Type', 'text/plain'); + headers.append('Set-Cookie', 'a=1'); + headers.append('Set-Cookie', 'b=2'); + return new Response('Hello, world!', { headers }); + }; + + let listener = createRequestListener(handler); + assert.ok(listener); + + let req = createIncomingMessage(); + let res = createServerResponse(); + + let headers: string[]; + mock.method(res, 'writeHead', (_status: number, headersArray: string[]) => { + headers = headersArray; + }); + + mock.method(res, 'end', () => { + assert.deepEqual(headers, [ + 'content-type', + 'text/plain', + 'set-cookie', + 'a=1', + 'set-cookie', + 'b=2', + ]); + resolve(); + }); + + listener(req, res); + }); + }); }); function createIncomingMessage({ @@ -176,10 +218,7 @@ function createIncomingMessage({ function createServerResponse(): http.ServerResponse { return Object.assign(new stream.Writable(), { - statusCode: 200, - statusMessage: 'OK', - setHeader() {}, - flushHeaders() {}, + writeHead() {}, write() {}, end() {}, }) as unknown as http.ServerResponse; diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index f7b34a7ff4f..a6bbd75df36 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -8,11 +8,11 @@ export interface ClientAddr { */ address: string; /** - * The family of the client IP address. Either `"IPv4"` or `"IPv6"`. + * The family of the client IP address. * * [Node.js Reference](https://nodejs.org/api/net.html#socketremotefamily) */ - family: string; + family: 'IPv4' | 'IPv6'; /** * The remote port of the client that sent the request. * @@ -105,9 +105,9 @@ export function createRequestListener( }); let request = createRequest(req, url, controller.signal); - let client: ClientAddr = { + let client = { address: req.socket.remoteAddress!, - family: req.socket.remoteFamily!, + family: req.socket.remoteFamily! as ClientAddr['family'], port: req.socket.remotePort!, }; @@ -201,7 +201,15 @@ function createBody(req: http.IncomingMessage): ReadableStream { } async function sendResponse(res: http.ServerResponse, response: Response): Promise { - res.writeHead(response.status, Object.fromEntries(response.headers.entries())); + // Use the rawHeaders API and iterate over response.headers so we are sure to send multiple + // Set-Cookie headers correctly. These would incorrectly be merged into a single header if we + // tried to use `Object.fromEntries(response.headers.entries())`. + let rawHeaders: string[] = []; + for (let [key, value] of response.headers) { + rawHeaders.push(key, value); + } + + res.writeHead(response.status, rawHeaders); if (response.body != null) { for await (let chunk of response.body) { From 2e4820b97eb60576ba1a1c8c4cf60e3c9292226e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 1 Sep 2024 22:55:31 -0700 Subject: [PATCH 420/730] Address feedback from Mark --- packages/node-fetch-server/README.md | 13 +++---------- .../node-fetch-server/src/lib/request-listener.ts | 6 +++--- packages/node-fetch-server/src/node-fetch-server.ts | 2 +- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/packages/node-fetch-server/README.md b/packages/node-fetch-server/README.md index 7cce7b773ee..a14ca1ceea4 100644 --- a/packages/node-fetch-server/README.md +++ b/packages/node-fetch-server/README.md @@ -17,8 +17,7 @@ When you write servers using the `Request` and `Response` APIs, you maximize the - Seamless integration with `node:http` and `node:https` modules - Supports custom hostnames (e.g. using `process.env.HOST` on a VPS to set the host portion of incoming request URLs) - Supports streaming responses using `new Response(stream)` -- Exposes client IP info -- It's [faster than Express](#benchmark) +- Exposes remote client address info ## Installation @@ -41,7 +40,7 @@ let server = http.createServer(createRequestListener(handler)); server.listen(3000); ``` -By default `request.url` is derived from the value of the `Host` HTTP header and the connection protocol being used. To support custom hostnames using e.g. a `$HOST` environment variable, you can use the `host` option: +By default `request.url` is derived from the value of the `Host` HTTP header and the connection protocol being used. To support custom hostnames using e.g. a `HOST` environment variable, you can use the `host` option: ```ts import * as assert from 'node:assert/strict'; @@ -71,7 +70,7 @@ let handler: FetchHandler = (request, client) => { ## Benchmark -A basic benchmark shows `node-fetch-server` is able to serve more requests per second (and has higher overall throughput) than Express v4. The vanilla `node:http` module is also shown as a baseline for comparison. +A basic "hello world" benchmark shows `node-fetch-server` introduces considerable overhead on top of a vanilla `node:http` server. However, it is still able to serve more requests per second (and has higher overall throughput) than Express v4, so the slowdown should be acceptable for most applications. ``` > @mjackson/node-fetch-server@0.0.0 bench /Users/michael/Projects/remix-the-web/packages/node-fetch-server @@ -118,12 +117,6 @@ Requests/sec: 8696.85 Transfer/sec: 2.10MB ``` -I encourage you to run the benchmark yourself. To do so, you'll need to have [`wrk`](https://github.com/wg/wrk) installed. Then run: - -```sh -pnpm run bench -``` - ## License See [LICENSE](https://github.com/mjackson/remix-the-web/blob/main/LICENSE) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index a6bbd75df36..e0fbfa0cc27 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -1,6 +1,6 @@ import * as http from 'node:http'; -export interface ClientAddr { +export interface ClientAddress { /** * The IP address of the client that sent the request. * @@ -39,7 +39,7 @@ export interface ErrorHandler { * [MDN `Response` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Response) */ export interface FetchHandler { - (request: Request, client: ClientAddr): Response | Promise; + (request: Request, client: ClientAddress): Response | Promise; } export interface RequestListenerOptions { @@ -107,7 +107,7 @@ export function createRequestListener( let request = createRequest(req, url, controller.signal); let client = { address: req.socket.remoteAddress!, - family: req.socket.remoteFamily! as ClientAddr['family'], + family: req.socket.remoteFamily! as ClientAddress['family'], port: req.socket.remotePort!, }; diff --git a/packages/node-fetch-server/src/node-fetch-server.ts b/packages/node-fetch-server/src/node-fetch-server.ts index ce7d4d7b7c0..8d2c72acb76 100644 --- a/packages/node-fetch-server/src/node-fetch-server.ts +++ b/packages/node-fetch-server/src/node-fetch-server.ts @@ -1,5 +1,5 @@ export { - type ClientAddr, + type ClientAddress, type ErrorHandler, type FetchHandler, type RequestListenerOptions, From 624213f95cac94d5f8db6bc00fae389d653c2292 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 2 Sep 2024 22:35:19 -0700 Subject: [PATCH 421/730] Inline sendResponse logic --- .../src/lib/request-listener.ts | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index e0fbfa0cc27..e8f6e534075 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -123,7 +123,23 @@ export function createRequestListener( } } - sendResponse(res, response); + // Use the rawHeaders API and iterate over response.headers so we are sure to send multiple + // Set-Cookie headers correctly. These would incorrectly be merged into a single header if we + // tried to use `Object.fromEntries(response.headers.entries())`. + let rawHeaders: string[] = []; + for (let [key, value] of response.headers) { + rawHeaders.push(key, value); + } + + res.writeHead(response.status, rawHeaders); + + if (response.body != null) { + for await (let chunk of response.body) { + res.write(chunk); + } + } + + res.end(); }; } @@ -199,23 +215,3 @@ function createBody(req: http.IncomingMessage): ReadableStream { }, }); } - -async function sendResponse(res: http.ServerResponse, response: Response): Promise { - // Use the rawHeaders API and iterate over response.headers so we are sure to send multiple - // Set-Cookie headers correctly. These would incorrectly be merged into a single header if we - // tried to use `Object.fromEntries(response.headers.entries())`. - let rawHeaders: string[] = []; - for (let [key, value] of response.headers) { - rawHeaders.push(key, value); - } - - res.writeHead(response.status, rawHeaders); - - if (response.body != null) { - for await (let chunk of response.body) { - res.write(chunk); - } - } - - res.end(); -} From 21d866ef932bc14220f7659cecba695f33fea823 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 3 Sep 2024 00:24:44 -0700 Subject: [PATCH 422/730] Automatically truncate the response body on HEAD requests --- .../src/lib/request-listener.spec.ts | 26 +++++++++++++++++++ .../src/lib/request-listener.ts | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.spec.ts b/packages/node-fetch-server/src/lib/request-listener.spec.ts index 7eae03c41f5..fb40de2f8e9 100644 --- a/packages/node-fetch-server/src/lib/request-listener.spec.ts +++ b/packages/node-fetch-server/src/lib/request-listener.spec.ts @@ -182,6 +182,32 @@ describe('createRequestListener', () => { listener(req, res); }); }); + + it('truncates the response body when the request method is HEAD', async () => { + await new Promise((resolve) => { + let handler: FetchHandler = async () => { + return new Response('Hello, world!'); + }; + + let listener = createRequestListener(handler); + assert.ok(listener); + + let req = createIncomingMessage({ method: 'HEAD' }); + let res = createServerResponse(); + + let chunks: Uint8Array[] = []; + mock.method(res, 'write', (chunk: Uint8Array) => { + chunks.push(chunk); + }); + + mock.method(res, 'end', () => { + assert.equal(chunks.length, 0); + resolve(); + }); + + listener(req, res); + }); + }); }); function createIncomingMessage({ diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index e8f6e534075..d3cd7cd449a 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -133,7 +133,7 @@ export function createRequestListener( res.writeHead(response.status, rawHeaders); - if (response.body != null) { + if (response.body != null && req.method !== 'HEAD') { for await (let chunk of response.body) { res.write(chunk); } From e01cbfa9b30fd39b9052cdbc1156dd88de811046 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 4 Sep 2024 10:42:25 -0700 Subject: [PATCH 423/730] Update nx --- package.json | 4 +- pnpm-lock.yaml | 162 ++++++++++++++++++++++++------------------------- 2 files changed, 83 insertions(+), 83 deletions(-) diff --git a/package.json b/package.json index 5947108b51f..73fa03fe14d 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,11 @@ "packageManager": "pnpm@9.9.0", "type": "module", "devDependencies": { - "@nx/js": "19.6.4", + "@nx/js": "19.6.5", "@swc-node/register": "^1.10.9", "@swc/core": "~1.5.7", "@swc/helpers": "~0.5.11", - "nx": "19.6.4", + "nx": "19.6.5", "prettier": "^3.3.3", "typescript": "^5.5.4" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e34d758fc36..92511d14b2f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: devDependencies: '@nx/js': - specifier: 19.6.4 - version: 19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + specifier: 19.6.5 + version: 19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) '@swc-node/register': specifier: ^1.10.9 version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) @@ -21,8 +21,8 @@ importers: specifier: ~0.5.11 version: 0.5.12 nx: - specifier: 19.6.4 - version: 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + specifier: 19.6.5 + version: 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) prettier: specifier: ^3.3.3 version: 3.3.3 @@ -1050,94 +1050,94 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@nrwl/devkit@19.6.4': - resolution: {integrity: sha512-jpr+T5/+21W/fwAMB6zDLZKO+ReYAfOOMIeM8CpeBi/r9nWmjGXaXN9YKwEOYS1fath62Y5ldGK4yZUttv1tkw==} + '@nrwl/devkit@19.6.5': + resolution: {integrity: sha512-KaQeVyYaWBQwQSITtumPvx+P7IpKFReETx4gLTcOpQ/a3QD/AZFGbNjiG+xDLbgo1FDh9dRt9k7eWhGk6oPWKQ==} - '@nrwl/js@19.6.4': - resolution: {integrity: sha512-yjxxSRST/lWylw4SO1qILg9oiKlBbcVst1nVFZzneTFo2oNuFVSEhluVh5tZ0bz3GZ1RPtHxjiBuWDwQ/QmmAA==} + '@nrwl/js@19.6.5': + resolution: {integrity: sha512-Ybm+wuCjaujvq8QIJgDM45yqpx675tqGEHnCuyaCwETF+OhgufEIGMwV/ASk+Bcle3btPY7iKUp3YuCjTexnEw==} - '@nrwl/tao@19.6.4': - resolution: {integrity: sha512-1J8cD+MFzsmboiGe03VlQZ8gt64k/TaYYPZivnnhOJolPPs75nz1JyJX55uWcKKRy/b7FZNKWIu/6Wp9JDhJrQ==} + '@nrwl/tao@19.6.5': + resolution: {integrity: sha512-EoUN/kE6CMWJ4ZZgcXAyiOzn8BSshG2DhC5PNwzLTAxRBus8FgXR/9c0XOzchaP46Kq3hoBGFgeyW434tfuv5w==} hasBin: true - '@nrwl/workspace@19.6.4': - resolution: {integrity: sha512-jjqtRjm5AP39s8oPUEehA6O0Zew6BeTi+Uhjb+ggqbFKH9R9hoSITnbJY670WlO4W8yWYxT8isPf1TNdSHkmBw==} + '@nrwl/workspace@19.6.5': + resolution: {integrity: sha512-4oufH1plJjUy8g9kG7yRL/gQgoEUFc8Lmk1ibwUj2FrnkXJ0oE7DDtE5N9f/wCUg+uGSIgmrYyG4DGM9xGGQzg==} - '@nx/devkit@19.6.4': - resolution: {integrity: sha512-mBitFwb/gcz8MR7STt7KQG0vf+QcsasDXiSYcf3OWpc6lGE5wn1q5jg6Iabp49Bd/mdHXVLQnP1aV5A+QqFIOQ==} + '@nx/devkit@19.6.5': + resolution: {integrity: sha512-AEaMSr55Ar48QHU8TBi/gzLtjeT100zdyfLmk0RoiLzjjC8pWmm3Xfvqxyt1WsUUf4oQhlHlolJuoM41qKsdZw==} peerDependencies: nx: '>= 17 <= 20' - '@nx/js@19.6.4': - resolution: {integrity: sha512-Z09whMis90on3/5V0RIG1On5bRlNI4q2SGZQmj530+BqRTNdKNqxuYdpGf3oNbw5cgLVGiHcWtHzZROaAzpc4g==} + '@nx/js@19.6.5': + resolution: {integrity: sha512-nKK3fAJnFZZZF3hWRec64k+3JqcD0c9uZWXsXXEwZXmfB3TitPy+zczM2SSVvC50+AoIXGCCiFBUYesdxeReoQ==} peerDependencies: verdaccio: ^5.0.4 peerDependenciesMeta: verdaccio: optional: true - '@nx/nx-darwin-arm64@19.6.4': - resolution: {integrity: sha512-kRn2FLvhwJA/TJrNlsCSqqQTrguNZLmiRsiXhvjkfUMbUKwyQfVMgJlvkZ+KoqraUSG+Qyb0FmrGur1I/Mld0Q==} + '@nx/nx-darwin-arm64@19.6.5': + resolution: {integrity: sha512-sFU2k0BaklM17206F2E5C3866y0SICb0xyuPeD6D07a6hB4IstjIUkldUJJN70wEsJ5I3VP4yZ2oJcwnb1TTRQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@nx/nx-darwin-x64@19.6.4': - resolution: {integrity: sha512-3uABBUhxVk+SdRwpUu30iuBlgRWm3tA/G9seG+wt7oN2R+fOu8zzRCYa+Blvoh1Ef+D9743Ir4rDc9Mhzl2B2g==} + '@nx/nx-darwin-x64@19.6.5': + resolution: {integrity: sha512-EJmTbUPmlksgOap6xkQl89+zXwHpaAnZLsyLHUd7i00eVRa21FRhdKFnVsRxtwPDZp/YCG84IzMUye/IrwDFTQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@nx/nx-freebsd-x64@19.6.4': - resolution: {integrity: sha512-OG83MiEk5L54/vAldmwZJBKEvZaM+DEIDqn2yZLTToBRj5Z9jwKJX3jKP60xbHiaT/hzsb1xPlwhOHJnYd80EQ==} + '@nx/nx-freebsd-x64@19.6.5': + resolution: {integrity: sha512-rR8NJCskoEmIbK96uxaevHm146WDTA0V3jId+X1joITqjj3E2DMm0U4r5v/OgI5+iqbhFV4S83LrMxP6gBLTsQ==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@nx/nx-linux-arm-gnueabihf@19.6.4': - resolution: {integrity: sha512-hQ9x4qSKUh9mIVDuD270ULrBnmYfDTjXq7LnIwECw1AuP4LkKzKxULhsbqVnFQ/k3xxyFkwyGTIu2mfDcw16Gw==} + '@nx/nx-linux-arm-gnueabihf@19.6.5': + resolution: {integrity: sha512-OUHFV6iLlJN7b7qFnqLfa0Yj/aoylEiRXcEhV1bhPm0Ryt1bOeGDmLYScVN8n5t+AVmrwwYHk+ajXMzCOLLeZw==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@nx/nx-linux-arm64-gnu@19.6.4': - resolution: {integrity: sha512-OFKpAHiaVg3YGFIMBmi/JshciP9buwtOPiHDXcQdzQgE22jyYzKEiFxfcpG0nCT8PlMYAbHPAda15WfWkfVGVQ==} + '@nx/nx-linux-arm64-gnu@19.6.5': + resolution: {integrity: sha512-CzbJfb24poaJgBHt4aKLaL8a7bO9KXCLls+TX0SZfmzA9AWX6YuiX9lhxwBv6cqsViXTDB4KnXndMDB/H0Gk4g==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@nx/nx-linux-arm64-musl@19.6.4': - resolution: {integrity: sha512-ZIR9u+mN0A7SmNd6vDxmPV1QVTgYPTdfBSM5TEnKl3q2fHw2Nkui81QBxA4d7VopJoJUz/pRHiUV+dlgEEZ6nA==} + '@nx/nx-linux-arm64-musl@19.6.5': + resolution: {integrity: sha512-MgidKilQ0KWxQbTnaqXGjASu7wtAC9q6zAwFNKFENkwJq3nThaQH6jQVlnINE4lL9NSgyyg0AS/ix31hiqAgvA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@nx/nx-linux-x64-gnu@19.6.4': - resolution: {integrity: sha512-AUMPvLs9KeCUuWD5DdlpbP3VfVsiD0IlptS2b3ul336rsQ7LwwdvE7jTVO5CixFOsiRZxP72fKJhaEargMn5Aw==} + '@nx/nx-linux-x64-gnu@19.6.5': + resolution: {integrity: sha512-rGDylAoslIlk5TDbEJ6YoQOYxxYP9gCpi6FLke2mFgXVzOmVlLKHfVsegIHYVMYYF26h3NJh0NLGGzGdoBjWgQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@nx/nx-linux-x64-musl@19.6.4': - resolution: {integrity: sha512-PU7AaBlrgnJnDxTiV/PNCu0pHUCzaogm6uNcbzCyFJLGn7DoQK9rkqUMPJjb3CnJkAj9XrrhuZwmOdbrhvHAvA==} + '@nx/nx-linux-x64-musl@19.6.5': + resolution: {integrity: sha512-C/pNjDL/bDEcrDypgBo4r1AOiPTk8gWJwBsFE1QHIvg7//5WFSreqRj34rJu/GZ95eLYJH5tje1VW6z+atEGkQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@nx/nx-win32-arm64-msvc@19.6.4': - resolution: {integrity: sha512-6CCmGWwH/J2k+Uxeci48w4QVhtcQ3hRZ5Z2jh26HI8YzH4wqZyA7QPgLBE6sNCPVLoGW5cBgTsfnyEdr+xarQA==} + '@nx/nx-win32-arm64-msvc@19.6.5': + resolution: {integrity: sha512-mMi8i16OFux17xed2iLPWwUdCbS1mYA9Ny/gnoNUCosmihmXX9wrzaGBkNAMsHA28huYQtPhGormsEs+zuiVFg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@nx/nx-win32-x64-msvc@19.6.4': - resolution: {integrity: sha512-jTNrlaFaKtbL2mYOcfPAiljtpF5CI7vbHIqYqBFYLUQXOwW9lOHlO+SeQnft6JYZs0FIr1IdHaCfdOw/hpnCiQ==} + '@nx/nx-win32-x64-msvc@19.6.5': + resolution: {integrity: sha512-jjhbDYNBkyz9Fg1jf0KZTrgdf/yx4v+k0ifukDIHZjva+jko0Ve5WzdkQ2K07M9ZxxYibDtTDqX9uX6+eFZtoA==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@nx/workspace@19.6.4': - resolution: {integrity: sha512-SMrI03OmjYm93XpDTlIWgAyIaEhToN4LNu4cxOXW9ygpzPe8HJlqR18aTaCqu1T+BY8XeaZ8BQ7qYS1kEjM9YA==} + '@nx/workspace@19.6.5': + resolution: {integrity: sha512-1r5Vgk1Y5+y1K20O9d59ALjlyLYOU4XcybIiN4Wonw+oYrg6ZXSeA3R+lLSuTA4dHtfxcNsCIigzcSEUwchNwg==} '@oxc-resolver/binding-darwin-arm64@1.11.0': resolution: {integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==} @@ -2158,8 +2158,8 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} - nx@19.6.4: - resolution: {integrity: sha512-yudYlBd3cMchRd8c0ZNan1SfT19AYK2zYOp77XVqVVwgqb6rJVxz6StFGFluUQ7Q7uSpkeT/8PsjwPVLt85EoQ==} + nx@19.6.5: + resolution: {integrity: sha512-igPYPsBF1BM1YxEiGDvaLOz0CWWoEvxzR7yQg3iULjGG9zKgDFNHHIHJwkyHsCBTtMhhkgeUl16PsTVgDuil3A==} hasBin: true peerDependencies: '@swc-node/register': ^1.8.0 @@ -3637,15 +3637,15 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 - '@nrwl/devkit@19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': + '@nrwl/devkit@19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': dependencies: - '@nx/devkit': 19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nx/devkit': 19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) transitivePeerDependencies: - nx - '@nrwl/js@19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': + '@nrwl/js@19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': dependencies: - '@nx/js': 19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + '@nx/js': 19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -3658,37 +3658,37 @@ snapshots: - typescript - verdaccio - '@nrwl/tao@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nrwl/tao@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - nx: 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) tslib: 2.7.0 transitivePeerDependencies: - '@swc-node/register' - '@swc/core' - debug - '@nrwl/workspace@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nrwl/workspace@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - '@nx/workspace': 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nx/workspace': 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) transitivePeerDependencies: - '@swc-node/register' - '@swc/core' - debug - '@nx/devkit@19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': + '@nx/devkit@19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': dependencies: - '@nrwl/devkit': 19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nrwl/devkit': 19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) ejs: 3.1.10 enquirer: 2.3.6 ignore: 5.3.2 minimatch: 9.0.3 - nx: 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) semver: 7.6.3 tmp: 0.2.3 tslib: 2.7.0 yargs-parser: 21.1.1 - '@nx/js@19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': + '@nx/js@19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': dependencies: '@babel/core': 7.25.2 '@babel/plugin-proposal-decorators': 7.24.7(@babel/core@7.25.2) @@ -3697,9 +3697,9 @@ snapshots: '@babel/preset-env': 7.25.4(@babel/core@7.25.2) '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) '@babel/runtime': 7.25.4 - '@nrwl/js': 19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) - '@nx/devkit': 19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) - '@nx/workspace': 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nrwl/js': 19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + '@nx/devkit': 19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nx/workspace': 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) babel-plugin-const-enum: 1.2.0(@babel/core@7.25.2) babel-plugin-macros: 2.8.0 babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.25.2)(@babel/traverse@7.25.4) @@ -3731,43 +3731,43 @@ snapshots: - supports-color - typescript - '@nx/nx-darwin-arm64@19.6.4': + '@nx/nx-darwin-arm64@19.6.5': optional: true - '@nx/nx-darwin-x64@19.6.4': + '@nx/nx-darwin-x64@19.6.5': optional: true - '@nx/nx-freebsd-x64@19.6.4': + '@nx/nx-freebsd-x64@19.6.5': optional: true - '@nx/nx-linux-arm-gnueabihf@19.6.4': + '@nx/nx-linux-arm-gnueabihf@19.6.5': optional: true - '@nx/nx-linux-arm64-gnu@19.6.4': + '@nx/nx-linux-arm64-gnu@19.6.5': optional: true - '@nx/nx-linux-arm64-musl@19.6.4': + '@nx/nx-linux-arm64-musl@19.6.5': optional: true - '@nx/nx-linux-x64-gnu@19.6.4': + '@nx/nx-linux-x64-gnu@19.6.5': optional: true - '@nx/nx-linux-x64-musl@19.6.4': + '@nx/nx-linux-x64-musl@19.6.5': optional: true - '@nx/nx-win32-arm64-msvc@19.6.4': + '@nx/nx-win32-arm64-msvc@19.6.5': optional: true - '@nx/nx-win32-x64-msvc@19.6.4': + '@nx/nx-win32-x64-msvc@19.6.5': optional: true - '@nx/workspace@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nx/workspace@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - '@nrwl/workspace': 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) - '@nx/devkit': 19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nrwl/workspace': 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nx/devkit': 19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) chalk: 4.1.2 enquirer: 2.3.6 - nx: 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) tslib: 2.7.0 yargs-parser: 21.1.1 transitivePeerDependencies: @@ -4765,10 +4765,10 @@ snapshots: dependencies: path-key: 3.1.1 - nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)): + nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)): dependencies: '@napi-rs/wasm-runtime': 0.2.4 - '@nrwl/tao': 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nrwl/tao': 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.0-rc.46 '@zkochan/js-yaml': 0.0.7 @@ -4803,16 +4803,16 @@ snapshots: yargs: 17.7.2 yargs-parser: 21.1.1 optionalDependencies: - '@nx/nx-darwin-arm64': 19.6.4 - '@nx/nx-darwin-x64': 19.6.4 - '@nx/nx-freebsd-x64': 19.6.4 - '@nx/nx-linux-arm-gnueabihf': 19.6.4 - '@nx/nx-linux-arm64-gnu': 19.6.4 - '@nx/nx-linux-arm64-musl': 19.6.4 - '@nx/nx-linux-x64-gnu': 19.6.4 - '@nx/nx-linux-x64-musl': 19.6.4 - '@nx/nx-win32-arm64-msvc': 19.6.4 - '@nx/nx-win32-x64-msvc': 19.6.4 + '@nx/nx-darwin-arm64': 19.6.5 + '@nx/nx-darwin-x64': 19.6.5 + '@nx/nx-freebsd-x64': 19.6.5 + '@nx/nx-linux-arm-gnueabihf': 19.6.5 + '@nx/nx-linux-arm64-gnu': 19.6.5 + '@nx/nx-linux-arm64-musl': 19.6.5 + '@nx/nx-linux-x64-gnu': 19.6.5 + '@nx/nx-linux-x64-musl': 19.6.5 + '@nx/nx-win32-arm64-msvc': 19.6.5 + '@nx/nx-win32-x64-msvc': 19.6.5 '@swc-node/register': 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) '@swc/core': 1.5.29(@swc/helpers@0.5.12) transitivePeerDependencies: From cd3ff63efc98364ef758d7c61fb7a26af7541581 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 4 Sep 2024 10:45:40 -0700 Subject: [PATCH 424/730] Ran prettier --- packages/file-storage/README.md | 10 +-- packages/file-storage/src/file-storage.ts | 2 +- .../src/lib/local-file-storage.spec.ts | 42 ++++----- .../src/lib/local-file-storage.ts | 32 +++---- .../src/lib/memory-file-storage.spec.ts | 30 +++---- .../src/lib/memory-file-storage.ts | 2 +- packages/file-storage/src/local.ts | 2 +- packages/file-storage/src/memory.ts | 2 +- packages/form-data-parser/README.md | 10 +-- .../src/lib/form-data.spec.ts | 86 +++++++++---------- .../form-data-parser/src/lib/form-data.ts | 16 ++-- .../src/lib/content-disposition.spec.ts | 10 +-- packages/headers/src/lib/param-values.spec.ts | 10 +-- packages/headers/src/lib/set-cookie.spec.ts | 6 +- packages/lazy-file/src/lazy-file.ts | 6 +- packages/multipart-parser/README.md | 32 +++---- .../cf-workers/worker-configuration.d.ts | 2 +- 17 files changed, 140 insertions(+), 160 deletions(-) diff --git a/packages/file-storage/README.md b/packages/file-storage/README.md index 14ffb5182d0..00fb9b370d5 100644 --- a/packages/file-storage/README.md +++ b/packages/file-storage/README.md @@ -20,12 +20,12 @@ npm install @mjackson/file-storage ## Usage ```ts -import { LocalFileStorage } from "@mjackson/file-storage/local"; +import { LocalFileStorage } from '@mjackson/file-storage/local'; -let storage = new LocalFileStorage("./user/files"); +let storage = new LocalFileStorage('./user/files'); -let file = new File(["hello world"], "hello.txt", { type: "text/plain" }); -let key = "hello-key"; +let file = new File(['hello world'], 'hello.txt', { type: 'text/plain' }); +let key = 'hello-key'; // Put the file in storage. await storage.set(key, file); @@ -43,7 +43,7 @@ await storage.remove(key); The `FileStorage` interface allows you to implement your own file storage for custom storage backends: ```ts -import { type FileStorage } from "@mjackson/file-storage"; +import { type FileStorage } from '@mjackson/file-storage'; class CustomFileStorage implements FileStorage { /** diff --git a/packages/file-storage/src/file-storage.ts b/packages/file-storage/src/file-storage.ts index d558de6cddc..7647353f727 100644 --- a/packages/file-storage/src/file-storage.ts +++ b/packages/file-storage/src/file-storage.ts @@ -1 +1 @@ -export { type FileStorage } from "./lib/file-storage.js"; +export { type FileStorage } from './lib/file-storage.js'; diff --git a/packages/file-storage/src/lib/local-file-storage.spec.ts b/packages/file-storage/src/lib/local-file-storage.spec.ts index 7543cba07ac..5ca4c61d0c5 100644 --- a/packages/file-storage/src/lib/local-file-storage.spec.ts +++ b/packages/file-storage/src/lib/local-file-storage.spec.ts @@ -1,46 +1,46 @@ -import * as assert from "node:assert/strict"; -import { after, describe, it } from "node:test"; -import * as fs from "node:fs"; -import * as path from "node:path"; +import * as assert from 'node:assert/strict'; +import { after, describe, it } from 'node:test'; +import * as fs from 'node:fs'; +import * as path from 'node:path'; -import { LocalFileStorage } from "./local-file-storage.js"; +import { LocalFileStorage } from './local-file-storage.js'; -const __dirname = new URL(".", import.meta.url).pathname; +const __dirname = new URL('.', import.meta.url).pathname; -describe("LocalFileStorage", () => { - let directory = path.resolve(__dirname, "../../test-local-file-storage"); +describe('LocalFileStorage', () => { + let directory = path.resolve(__dirname, '../../test-local-file-storage'); after(() => { fs.rmSync(directory, { recursive: true }); }); - it("stores and retrieves files", async () => { + it('stores and retrieves files', async () => { let storage = new LocalFileStorage(directory); let lastModified = Date.now(); - let file = new File(["Hello, world!"], "hello.txt", { - type: "text/plain", - lastModified + let file = new File(['Hello, world!'], 'hello.txt', { + type: 'text/plain', + lastModified, }); - await storage.set("hello", file); + await storage.set('hello', file); - assert.ok(await storage.has("hello")); + assert.ok(await storage.has('hello')); - let retrieved = await storage.get("hello"); + let retrieved = await storage.get('hello'); assert.ok(retrieved); - assert.equal(retrieved.name, "hello.txt"); - assert.equal(retrieved.type, "text/plain"); + assert.equal(retrieved.name, 'hello.txt'); + assert.equal(retrieved.type, 'text/plain'); assert.equal(retrieved.lastModified, lastModified); assert.equal(retrieved.size, 13); let text = await retrieved.text(); - assert.equal(text, "Hello, world!"); + assert.equal(text, 'Hello, world!'); - await storage.remove("hello"); + await storage.remove('hello'); - assert.ok(!(await storage.has("hello"))); - assert.equal(await storage.get("hello"), null); + assert.ok(!(await storage.has('hello'))); + assert.equal(await storage.get('hello'), null); }); }); diff --git a/packages/file-storage/src/lib/local-file-storage.ts b/packages/file-storage/src/lib/local-file-storage.ts index 9b480acf362..b2291cbf051 100644 --- a/packages/file-storage/src/lib/local-file-storage.ts +++ b/packages/file-storage/src/lib/local-file-storage.ts @@ -1,9 +1,9 @@ -import * as fs from "node:fs"; -import * as fsp from "node:fs/promises"; -import * as path from "node:path"; -import { getFile } from "@mjackson/lazy-file/fs"; +import * as fs from 'node:fs'; +import * as fsp from 'node:fs/promises'; +import * as path from 'node:path'; +import { getFile } from '@mjackson/lazy-file/fs'; -import { FileStorage } from "./file-storage.js"; +import { FileStorage } from './file-storage.js'; /** * A `FileStorage` that is backed by the local filesystem. @@ -37,9 +37,7 @@ export class LocalFileStorage implements FileStorage { fs.mkdirSync(this.#dirname, { recursive: true }); } - this.#metadata = new FileMetadataIndex( - path.join(directory, ".metadata.json") - ); + this.#metadata = new FileMetadataIndex(path.join(directory, '.metadata.json')); } has(key: string): Promise { @@ -53,7 +51,7 @@ export class LocalFileStorage implements FileStorage { file: storedFile, name: file.name, type: file.type, - mtime: file.lastModified + mtime: file.lastModified, }); } @@ -66,7 +64,7 @@ export class LocalFileStorage implements FileStorage { return getFile(filename, { name: metadata.name, type: metadata.type, - lastModified: metadata.mtime + lastModified: metadata.mtime, }); } @@ -93,9 +91,9 @@ async function storeFile(dirname: string, file: File): Promise { let handle: fsp.FileHandle; try { - handle = await fsp.open(path.join(dirname, filename), "w"); + handle = await fsp.open(path.join(dirname, filename), 'w'); } catch (error) { - if ((error as NodeJS.ErrnoException).code === "EEXIST") { + if ((error as NodeJS.ErrnoException).code === 'EEXIST') { // Try again with a different filename return storeFile(dirname, file); } else { @@ -169,12 +167,6 @@ class FileMetadataIndex { } } -function isNoEntityError( - obj: unknown -): obj is NodeJS.ErrnoException & { code: "ENOENT" } { - return ( - obj instanceof Error && - "code" in obj && - (obj as NodeJS.ErrnoException).code === "ENOENT" - ); +function isNoEntityError(obj: unknown): obj is NodeJS.ErrnoException & { code: 'ENOENT' } { + return obj instanceof Error && 'code' in obj && (obj as NodeJS.ErrnoException).code === 'ENOENT'; } diff --git a/packages/file-storage/src/lib/memory-file-storage.spec.ts b/packages/file-storage/src/lib/memory-file-storage.spec.ts index 6e1073277e2..fdf094b3965 100644 --- a/packages/file-storage/src/lib/memory-file-storage.spec.ts +++ b/packages/file-storage/src/lib/memory-file-storage.spec.ts @@ -1,31 +1,31 @@ -import * as assert from "node:assert/strict"; -import { describe, it } from "node:test"; +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; -import { MemoryFileStorage } from "./memory-file-storage.js"; +import { MemoryFileStorage } from './memory-file-storage.js'; -describe("MemoryFileStorage", () => { - it("stores and retrieves files", async () => { +describe('MemoryFileStorage', () => { + it('stores and retrieves files', async () => { let storage = new MemoryFileStorage(); - let file = new File(["Hello, world!"], "hello.txt", { type: "text/plain" }); + let file = new File(['Hello, world!'], 'hello.txt', { type: 'text/plain' }); - storage.set("hello", file); + storage.set('hello', file); - assert.ok(storage.has("hello")); + assert.ok(storage.has('hello')); - let retrieved = storage.get("hello"); + let retrieved = storage.get('hello'); assert.ok(retrieved); - assert.equal(retrieved.name, "hello.txt"); - assert.equal(retrieved.type, "text/plain"); + assert.equal(retrieved.name, 'hello.txt'); + assert.equal(retrieved.type, 'text/plain'); assert.equal(retrieved.size, 13); let text = await retrieved.text(); - assert.equal(text, "Hello, world!"); + assert.equal(text, 'Hello, world!'); - storage.remove("hello"); + storage.remove('hello'); - assert.ok(!storage.has("hello")); - assert.equal(storage.get("hello"), null); + assert.ok(!storage.has('hello')); + assert.equal(storage.get('hello'), null); }); }); diff --git a/packages/file-storage/src/lib/memory-file-storage.ts b/packages/file-storage/src/lib/memory-file-storage.ts index 8a30578f827..eeb5a5ebeb9 100644 --- a/packages/file-storage/src/lib/memory-file-storage.ts +++ b/packages/file-storage/src/lib/memory-file-storage.ts @@ -1,4 +1,4 @@ -import { FileStorage } from "./file-storage.js"; +import { FileStorage } from './file-storage.js'; /** * A simple, in-memory implementation of the `FileStorage` interface. diff --git a/packages/file-storage/src/local.ts b/packages/file-storage/src/local.ts index 6370d3aaa7e..3d4d690ab11 100644 --- a/packages/file-storage/src/local.ts +++ b/packages/file-storage/src/local.ts @@ -1 +1 @@ -export { LocalFileStorage } from "./lib/local-file-storage.js"; +export { LocalFileStorage } from './lib/local-file-storage.js'; diff --git a/packages/file-storage/src/memory.ts b/packages/file-storage/src/memory.ts index c0724d15b45..364cbccbd9c 100644 --- a/packages/file-storage/src/memory.ts +++ b/packages/file-storage/src/memory.ts @@ -1 +1 @@ -export { MemoryFileStorage } from "./lib/memory-file-storage.js"; +export { MemoryFileStorage } from './lib/memory-file-storage.js'; diff --git a/packages/form-data-parser/README.md b/packages/form-data-parser/README.md index c87f40a868f..2d0f32857bf 100644 --- a/packages/form-data-parser/README.md +++ b/packages/form-data-parser/README.md @@ -26,14 +26,14 @@ npm install @mjackson/form-data-parser ## Usage ```ts -import { LocalFileStorage } from "@mjackson/file-storage/local"; -import { type FileUpload, parseFormData } from "@mjackson/form-data-parser"; +import { LocalFileStorage } from '@mjackson/file-storage/local'; +import { type FileUpload, parseFormData } from '@mjackson/form-data-parser'; -const fileStorage = new LocalFileStorage("/uploads/user-avatars"); +const fileStorage = new LocalFileStorage('/uploads/user-avatars'); async function uploadHandler(fileUpload: FileUpload) { // Is this file upload from the field? - if (fileUpload.fieldName === "user-avatar") { + if (fileUpload.fieldName === 'user-avatar') { let storageKey = `user-${user.id}-avatar`; // FileUpload objects are not meant to stick around for very long (they are @@ -53,7 +53,7 @@ async function uploadHandler(fileUpload: FileUpload) { async function requestHandler(request: Request) { let formData = await parseFormData(request, uploadHandler); - let file = formData.get("user-avatar"); // File (LazyFile) + let file = formData.get('user-avatar'); // File (LazyFile) file.name; // "my-avatar.jpg" (name of the file on the user's computer) file.size; // number file.type; // "image/jpeg" diff --git a/packages/form-data-parser/src/lib/form-data.spec.ts b/packages/form-data-parser/src/lib/form-data.spec.ts index 06b9367e1cc..a2591d3aee6 100644 --- a/packages/form-data-parser/src/lib/form-data.spec.ts +++ b/packages/form-data-parser/src/lib/form-data.spec.ts @@ -1,75 +1,73 @@ -import * as assert from "node:assert/strict"; -import { describe, it, mock } from "node:test"; +import * as assert from 'node:assert/strict'; +import { describe, it, mock } from 'node:test'; -import { type FileUploadHandler, parseFormData } from "./form-data.js"; +import { type FileUploadHandler, parseFormData } from './form-data.js'; -describe("parseFormData", () => { - it("parses a application/x-www-form-urlencoded request", async () => { - let request = new Request("http://localhost:8080", { - method: "POST", +describe('parseFormData', () => { + it('parses a application/x-www-form-urlencoded request', async () => { + let request = new Request('http://localhost:8080', { + method: 'POST', headers: { - "Content-Type": "application/x-www-form-urlencoded" + 'Content-Type': 'application/x-www-form-urlencoded', }, - body: "text=Hello%2C%20World!" + body: 'text=Hello%2C%20World!', }); let formData = await parseFormData(request); - assert.equal(formData.get("text"), "Hello, World!"); + assert.equal(formData.get('text'), 'Hello, World!'); }); - it("parses a multipart/form-data request", async () => { - let request = new Request("http://localhost:8080", { - method: "POST", + it('parses a multipart/form-data request', async () => { + let request = new Request('http://localhost:8080', { + method: 'POST', headers: { - "Content-Type": - "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" + 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW', }, body: [ - "------WebKitFormBoundary7MA4YWxkTrZu0gW", + '------WebKitFormBoundary7MA4YWxkTrZu0gW', 'Content-Disposition: form-data; name="text"', - "", - "Hello, World!", - "------WebKitFormBoundary7MA4YWxkTrZu0gW", + '', + 'Hello, World!', + '------WebKitFormBoundary7MA4YWxkTrZu0gW', 'Content-Disposition: form-data; name="file"; filename="example.txt"', - "Content-Type: text/plain", - "", - "This is an example file.", - "------WebKitFormBoundary7MA4YWxkTrZu0gW--" - ].join("\r\n") + 'Content-Type: text/plain', + '', + 'This is an example file.', + '------WebKitFormBoundary7MA4YWxkTrZu0gW--', + ].join('\r\n'), }); let formData = await parseFormData(request); - assert.equal(formData.get("text"), "Hello, World!"); + assert.equal(formData.get('text'), 'Hello, World!'); - let file = formData.get("file"); + let file = formData.get('file'); assert.ok(file instanceof File); - assert.equal(file.name, "example.txt"); - assert.equal(file.type, "text/plain"); - assert.equal(await file.text(), "This is an example file."); + assert.equal(file.name, 'example.txt'); + assert.equal(file.type, 'text/plain'); + assert.equal(await file.text(), 'This is an example file.'); }); - it("calls the file upload handler for each file part", async () => { - let request = new Request("http://localhost:8080", { - method: "POST", + it('calls the file upload handler for each file part', async () => { + let request = new Request('http://localhost:8080', { + method: 'POST', headers: { - "Content-Type": - "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" + 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW', }, body: [ - "------WebKitFormBoundary7MA4YWxkTrZu0gW", + '------WebKitFormBoundary7MA4YWxkTrZu0gW', 'Content-Disposition: form-data; name="file1"; filename="example.txt"', - "Content-Type: text/plain", - "", - "This is an example file.", - "------WebKitFormBoundary7MA4YWxkTrZu0gW", + 'Content-Type: text/plain', + '', + 'This is an example file.', + '------WebKitFormBoundary7MA4YWxkTrZu0gW', 'Content-Disposition: form-data; name="file2"; filename="example.txt"', - "Content-Type: text/plain", - "", - "This is another example file.", - "------WebKitFormBoundary7MA4YWxkTrZu0gW--" - ].join("\r\n") + 'Content-Type: text/plain', + '', + 'This is another example file.', + '------WebKitFormBoundary7MA4YWxkTrZu0gW--', + ].join('\r\n'), }); let fileUploadHandler = mock.fn(); diff --git a/packages/form-data-parser/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts index b457aa37d5d..42fdf73b477 100644 --- a/packages/form-data-parser/src/lib/form-data.ts +++ b/packages/form-data-parser/src/lib/form-data.ts @@ -1,8 +1,8 @@ import { isMultipartRequest, parseMultipartRequest, - MultipartPart -} from "@mjackson/multipart-parser"; + MultipartPart, +} from '@mjackson/multipart-parser'; /** * A `File` that was uploaded as part of a `multipart/form-data` request. @@ -18,7 +18,7 @@ export class FileUpload extends File { #part: MultipartPart; constructor(part: MultipartPart) { - super([], part.filename ?? "", { type: part.mediaType }); + super([], part.filename ?? '', { type: part.mediaType }); this.#part = part; } @@ -38,15 +38,11 @@ export class FileUpload extends File { } get size(): number { - throw new Error( - "Cannot get the size of a file upload without buffering the entire file" - ); + throw new Error('Cannot get the size of a file upload without buffering the entire file'); } slice(): Blob { - throw new Error( - "Cannot slice a file upload without buffering the entire file" - ); + throw new Error('Cannot slice a file upload without buffering the entire file'); } stream(): ReadableStream { @@ -81,7 +77,7 @@ async function defaultFileUploadHandler(file: FileUpload): Promise { */ export async function parseFormData( request: Request, - uploadHandler: FileUploadHandler = defaultFileUploadHandler + uploadHandler: FileUploadHandler = defaultFileUploadHandler, ): Promise { if (isMultipartRequest(request)) { let formData = new FormData(); diff --git a/packages/headers/src/lib/content-disposition.spec.ts b/packages/headers/src/lib/content-disposition.spec.ts index 8aca67022bc..c4a561029df 100644 --- a/packages/headers/src/lib/content-disposition.spec.ts +++ b/packages/headers/src/lib/content-disposition.spec.ts @@ -24,7 +24,7 @@ describe('ContentDisposition', () => { it('initializes with another ContentDisposition', () => { let header = new ContentDisposition( - new ContentDisposition('attachment; filename="example.txt"') + new ContentDisposition('attachment; filename="example.txt"'), ); assert.equal(header.type, 'attachment'); assert.equal(header.filename, 'example.txt'); @@ -90,7 +90,7 @@ describe('ContentDisposition', () => { it('handles attribute values with special characters', () => { let header = new ContentDisposition( - 'attachment; filename="file with spaces and (parentheses).txt"' + 'attachment; filename="file with spaces and (parentheses).txt"', ); assert.equal(header.filename, 'file with spaces and (parentheses).txt'); }); @@ -123,7 +123,7 @@ describe('ContentDisposition', () => { it('prioritizes filename* over filename when both are present', () => { let header = new ContentDisposition( - 'attachment; filename="fallback.txt"; filename*=UTF-8\'\'%E6%96%87%E4%BB%B6.txt' + 'attachment; filename="fallback.txt"; filename*=UTF-8\'\'%E6%96%87%E4%BB%B6.txt', ); assert.equal(header.filename, 'fallback.txt'); assert.equal(header.filenameSplat, "UTF-8''%E6%96%87%E4%BB%B6.txt"); @@ -139,7 +139,7 @@ describe('ContentDisposition', () => { describe('preferredFilename', () => { it('returns filename* when both filename and filename* are present', () => { let header = new ContentDisposition( - 'attachment; filename="old.txt"; filename*=UTF-8\'\'new.txt' + 'attachment; filename="old.txt"; filename*=UTF-8\'\'new.txt', ); assert.equal(header.preferredFilename, 'new.txt'); }); @@ -166,7 +166,7 @@ describe('ContentDisposition', () => { it('handles filename* with spaces and other special characters', () => { let header = new ContentDisposition( - "attachment; filename*=UTF-8''hello%20world%21%20%26%20goodbye.txt" + "attachment; filename*=UTF-8''hello%20world%21%20%26%20goodbye.txt", ); assert.equal(header.preferredFilename, 'hello world! & goodbye.txt'); }); diff --git a/packages/headers/src/lib/param-values.spec.ts b/packages/headers/src/lib/param-values.spec.ts index 569d33c1e35..9286c65470a 100644 --- a/packages/headers/src/lib/param-values.spec.ts +++ b/packages/headers/src/lib/param-values.spec.ts @@ -32,7 +32,7 @@ describe('parseParams', () => { ['attachment', undefined], ['filename', 'photo.jpg'], ['filename*', "UTF-8''%E7%85%A7%E7%89%87.jpg"], - ] + ], ); assert.deepEqual( parseParams('attachment; filename="photo.jpg"; filename*="UTF-8\'\'%E7%85%A7%E7%89%87.jpg"'), @@ -40,7 +40,7 @@ describe('parseParams', () => { ['attachment', undefined], ['filename', 'photo.jpg'], ['filename*', "UTF-8''%E7%85%A7%E7%89%87.jpg"], - ] + ], ); }); @@ -58,12 +58,12 @@ describe('parseParams', () => { ]); assert.deepEqual( parseParams( - 'preferences={"font":"Arial","size":"12pt"}; Expires=Fri, 31 Dec 2023 23:59:59 GMT' + 'preferences={"font":"Arial","size":"12pt"}; Expires=Fri, 31 Dec 2023 23:59:59 GMT', ), [ ['preferences', '{"font":"Arial","size":"12pt"}'], ['Expires', 'Fri, 31 Dec 2023 23:59:59 GMT'], - ] + ], ); assert.deepEqual(parseParams('cart_items="[\\"item1\\",\\"item2\\"]"; Path=/cart; HttpOnly'), [ ['cart_items', '["item1","item2"]'], @@ -84,7 +84,7 @@ describe('parseParams', () => { ['HttpOnly', undefined], ['SameSite', 'Strict'], ['Max-Age', '300'], - ] + ], ); }); }); diff --git a/packages/headers/src/lib/set-cookie.spec.ts b/packages/headers/src/lib/set-cookie.spec.ts index 346645a5b7a..fd96f2b655c 100644 --- a/packages/headers/src/lib/set-cookie.spec.ts +++ b/packages/headers/src/lib/set-cookie.spec.ts @@ -12,7 +12,7 @@ describe('SetCookie', () => { it('initializes with a string', () => { let header = new SetCookie( - 'session=abc123; Domain=example.com; Path=/; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly' + 'session=abc123; Domain=example.com; Path=/; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly', ); assert.equal(header.name, 'session'); assert.equal(header.value, 'abc123'); @@ -44,7 +44,7 @@ describe('SetCookie', () => { it('initializes with another SetCookie', () => { let header = new SetCookie( - new SetCookie('session=abc123; Domain=example.com; Path=/; Secure; HttpOnly') + new SetCookie('session=abc123; Domain=example.com; Path=/; Secure; HttpOnly'), ); assert.equal(header.name, 'session'); assert.equal(header.value, 'abc123'); @@ -108,7 +108,7 @@ describe('SetCookie', () => { assert.equal( header.toString(), - 'session=abc123; Domain=example.com; Path=/; Secure; HttpOnly; SameSite=Lax' + 'session=abc123; Domain=example.com; Path=/; Secure; HttpOnly; SameSite=Lax', ); }); diff --git a/packages/lazy-file/src/lazy-file.ts b/packages/lazy-file/src/lazy-file.ts index 458db31e53a..8b85430c825 100644 --- a/packages/lazy-file/src/lazy-file.ts +++ b/packages/lazy-file/src/lazy-file.ts @@ -1,8 +1,8 @@ -export { type ByteRange, getByteLength, getIndexes } from "./lib/byte-range.js"; +export { type ByteRange, getByteLength, getIndexes } from './lib/byte-range.js'; export { type LazyContent, type LazyBlobOptions, LazyBlob, type LazyFileOptions, - LazyFile -} from "./lib/lazy-file.js"; + LazyFile, +} from './lib/lazy-file.js'; diff --git a/packages/multipart-parser/README.md b/packages/multipart-parser/README.md index 412d6c239ea..2b2edcb7f5b 100644 --- a/packages/multipart-parser/README.md +++ b/packages/multipart-parser/README.md @@ -33,10 +33,7 @@ deno add @mjackson/multipart-parser The most common use case for `multipart-parser` is handling file uploads when you're building a web server. For this case, the `parseMultipartRequest` function is your friend. It will automatically validate the request is `multipart/form-data`, extract the multipart boundary from the `Content-Type` header, parse all fields and files in the `request.body` stream, and `yield` each one to you as a `MultipartPart` object so you can save it to disk or upload it somewhere. ```typescript -import { - MultipartParseError, - parseMultipartRequest -} from "@mjackson/multipart-parser"; +import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser'; async function handleMultipartRequest(request: Request): void { try { @@ -53,9 +50,9 @@ async function handleMultipartRequest(request: Request): void { } } catch (error) { if (error instanceof MultipartParseError) { - console.error("Failed to parse multipart request:", error.message); + console.error('Failed to parse multipart request:', error.message); } else { - console.error("An unexpected error occurred:", error); + console.error('An unexpected error occurred:', error); } } } @@ -66,11 +63,11 @@ The main module (`import from "@mjackson/multipart-parser"`) assumes you're work If however you're building a server for Node.js that relies on node-specific APIs like `http.IncomingMessage`, `stream.Readable`, and `buffer.Buffer` (ala Express or `http.createServer`), `multipart-parser` ships with an additional module that works directly with these APIs. ```typescript -import * as http from "node:http"; +import * as http from 'node:http'; -import { MultipartParseError } from "@mjackson/multipart-parser"; +import { MultipartParseError } from '@mjackson/multipart-parser'; // Note: Import from multipart-parser/node for node-specific APIs -import { parseMultipartRequest } from "@mjackson/multipart-parser/node"; +import { parseMultipartRequest } from '@mjackson/multipart-parser/node'; const server = http.createServer(async (req, res) => { try { @@ -83,9 +80,9 @@ const server = http.createServer(async (req, res) => { } } catch (error) { if (error instanceof MultipartParseError) { - console.error("Failed to parse multipart request:", error.message); + console.error('Failed to parse multipart request:', error.message); } else { - console.error("An unexpected error occurred:", error); + console.error('An unexpected error occurred:', error); } } }); @@ -98,7 +95,7 @@ server.listen(8080); If you're working directly with multipart boundaries and buffers/streams of multipart data that are not necessarily part of a request, `multipart-parser` provides a lower-level API that you can use directly: ```typescript -import { parseMultipart } from "@mjackson/multipart-parser"; +import { parseMultipart } from '@mjackson/multipart-parser'; // Get the multipart data from some API, filesystem, etc. let multipartMessage = new Uint8Array(); @@ -106,7 +103,7 @@ let multipartMessage = new Uint8Array(); // let multipartMessage = new ReadableStream(...); // let multipartMessage = [new Uint8Array(...), new Uint8Array(...)]; -let boundary = "----WebKitFormBoundary56eac3x"; +let boundary = '----WebKitFormBoundary56eac3x'; for await (let part of parseMultipart(multipartMessage, boundary)) { // Do whatever you want with the part... @@ -116,19 +113,16 @@ for await (let part of parseMultipart(multipartMessage, boundary)) { If you'd prefer a callback-based API, instantiate your own `MultipartParser` and go for it: ```typescript -import { - MultipartParseError, - MultipartParser -} from "@mjackson/multipart-parser"; +import { MultipartParseError, MultipartParser } from '@mjackson/multipart-parser'; let multipartMessage = new Uint8Array(); // or ReadableStream, etc. -let boundary = "..."; +let boundary = '...'; let parser = new MultipartParser(boundary); try { // parse() resolves once the parse is finished and all your callbacks are done - await parser.parse(multipartMessage, async part => { + await parser.parse(multipartMessage, async (part) => { // Do whatever you need... }); } catch (error) { diff --git a/packages/multipart-parser/examples/cf-workers/worker-configuration.d.ts b/packages/multipart-parser/examples/cf-workers/worker-configuration.d.ts index 34721071f5c..45b9130582a 100644 --- a/packages/multipart-parser/examples/cf-workers/worker-configuration.d.ts +++ b/packages/multipart-parser/examples/cf-workers/worker-configuration.d.ts @@ -2,5 +2,5 @@ // by running `wrangler types` interface Env { - MULTIPART_UPLOADS: R2Bucket; + MULTIPART_UPLOADS: R2Bucket; } From 269ebce58439504571ed47f360da65466924b9e1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 4 Sep 2024 11:21:52 -0700 Subject: [PATCH 425/730] Clean up old files on disk --- .nx/version-plans/version-plan-1725471973201.md | 5 +++++ packages/file-storage/src/lib/local-file-storage.ts | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 .nx/version-plans/version-plan-1725471973201.md diff --git a/.nx/version-plans/version-plan-1725471973201.md b/.nx/version-plans/version-plan-1725471973201.md new file mode 100644 index 00000000000..4e55a5e5bbd --- /dev/null +++ b/.nx/version-plans/version-plan-1725471973201.md @@ -0,0 +1,5 @@ +--- +'@mjackson/file-storage': patch +--- + +Clean up old files on disk when they are replaced by new ones with the same key diff --git a/packages/file-storage/src/lib/local-file-storage.ts b/packages/file-storage/src/lib/local-file-storage.ts index b2291cbf051..bcedcb36f83 100644 --- a/packages/file-storage/src/lib/local-file-storage.ts +++ b/packages/file-storage/src/lib/local-file-storage.ts @@ -45,6 +45,9 @@ export class LocalFileStorage implements FileStorage { } async set(key: string, file: File): Promise { + // Remove any existing file with the same key. + await this.remove(key); + let storedFile = await storeFile(this.#dirname, file); await this.#metadata.set(key, { From a9eb0e0377bee4cd3f6b15389984ae5e7e5ccbde Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 4 Sep 2024 11:23:04 -0700 Subject: [PATCH 426/730] Accept an open file descriptor in writeFile --- .../version-plan-1725474145080.md | 5 +++++ packages/lazy-file/src/fs.ts | 22 ++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 .nx/version-plans/version-plan-1725474145080.md diff --git a/.nx/version-plans/version-plan-1725474145080.md b/.nx/version-plans/version-plan-1725474145080.md new file mode 100644 index 00000000000..7f38d93be9a --- /dev/null +++ b/.nx/version-plans/version-plan-1725474145080.md @@ -0,0 +1,5 @@ +--- +'@mjackson/lazy-file': minor +--- + +Accept an open file descriptor or file handle in `writeFile(fd)` diff --git a/packages/lazy-file/src/fs.ts b/packages/lazy-file/src/fs.ts index 9c7378f1574..eebdb537b4a 100644 --- a/packages/lazy-file/src/fs.ts +++ b/packages/lazy-file/src/fs.ts @@ -23,6 +23,10 @@ export interface GetFileOptions { * Returns a `File` from the local filesytem. * * [MDN `File` Reference](https://developer.mozilla.org/en-US/docs/Web/API/File) + * + * @param filename The path to the file + * @param options Options to override the file's metadata + * @returns A `File` object */ export function openFile(filename: string, options?: GetFileOptions): File { let stats = fs.statSync(filename); @@ -64,20 +68,26 @@ function streamFile(filename: string, start = 0, end = Infinity): ReadableStream export { openFile as getFile }; /** - * Writes a `File` to the local filesytem with the given `filename` and resolves when the stream is - * finished. + * Writes a `File` to the local filesytem and resolves when the stream is finished. * * [MDN `File` Reference](https://developer.mozilla.org/en-US/docs/Web/API/File) + * + * @param to The path to write the file to, or an open file descriptor + * @param file The file to write + * @returns A promise that resolves when the file is written */ -export function writeFile(filename: string, file: File): Promise { +export function writeFile(to: string | number | fs.promises.FileHandle, file: File): Promise { return new Promise(async (resolve) => { - let write = fs.createWriteStream(filename); + let writeStream = + typeof to === 'string' + ? fs.createWriteStream(to) + : fs.createWriteStream('ignored', { fd: to }); for await (let chunk of file.stream()) { - write.write(chunk); + writeStream.write(chunk); } - write.end(() => { + writeStream.end(() => { resolve(); }); }); From a765ab95605a63292ff328fb56ff549b32424175 Mon Sep 17 00:00:00 2001 From: JamesHenry Date: Wed, 4 Sep 2024 23:33:16 +0400 Subject: [PATCH 427/730] chore: bump to latest nx, custom changelog renderer --- nx.json | 3 +- package.json | 4 +- pnpm-lock.yaml | 162 ++++++++++++++++----------------- scripts/changelog-renderer.cjs | 30 ++++++ 4 files changed, 115 insertions(+), 84 deletions(-) create mode 100644 scripts/changelog-renderer.cjs diff --git a/nx.json b/nx.json index 29af13c1886..0e73362afd4 100644 --- a/nx.json +++ b/nx.json @@ -21,7 +21,8 @@ }, "changelog": { "projectChangelogs": { - "createRelease": "github" + "createRelease": "github", + "renderer": "{workspaceRoot}/scripts/changelog-renderer.cjs" } } } diff --git a/package.json b/package.json index 5947108b51f..73fa03fe14d 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,11 @@ "packageManager": "pnpm@9.9.0", "type": "module", "devDependencies": { - "@nx/js": "19.6.4", + "@nx/js": "19.6.5", "@swc-node/register": "^1.10.9", "@swc/core": "~1.5.7", "@swc/helpers": "~0.5.11", - "nx": "19.6.4", + "nx": "19.6.5", "prettier": "^3.3.3", "typescript": "^5.5.4" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e34d758fc36..92511d14b2f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: devDependencies: '@nx/js': - specifier: 19.6.4 - version: 19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + specifier: 19.6.5 + version: 19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) '@swc-node/register': specifier: ^1.10.9 version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) @@ -21,8 +21,8 @@ importers: specifier: ~0.5.11 version: 0.5.12 nx: - specifier: 19.6.4 - version: 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + specifier: 19.6.5 + version: 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) prettier: specifier: ^3.3.3 version: 3.3.3 @@ -1050,94 +1050,94 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@nrwl/devkit@19.6.4': - resolution: {integrity: sha512-jpr+T5/+21W/fwAMB6zDLZKO+ReYAfOOMIeM8CpeBi/r9nWmjGXaXN9YKwEOYS1fath62Y5ldGK4yZUttv1tkw==} + '@nrwl/devkit@19.6.5': + resolution: {integrity: sha512-KaQeVyYaWBQwQSITtumPvx+P7IpKFReETx4gLTcOpQ/a3QD/AZFGbNjiG+xDLbgo1FDh9dRt9k7eWhGk6oPWKQ==} - '@nrwl/js@19.6.4': - resolution: {integrity: sha512-yjxxSRST/lWylw4SO1qILg9oiKlBbcVst1nVFZzneTFo2oNuFVSEhluVh5tZ0bz3GZ1RPtHxjiBuWDwQ/QmmAA==} + '@nrwl/js@19.6.5': + resolution: {integrity: sha512-Ybm+wuCjaujvq8QIJgDM45yqpx675tqGEHnCuyaCwETF+OhgufEIGMwV/ASk+Bcle3btPY7iKUp3YuCjTexnEw==} - '@nrwl/tao@19.6.4': - resolution: {integrity: sha512-1J8cD+MFzsmboiGe03VlQZ8gt64k/TaYYPZivnnhOJolPPs75nz1JyJX55uWcKKRy/b7FZNKWIu/6Wp9JDhJrQ==} + '@nrwl/tao@19.6.5': + resolution: {integrity: sha512-EoUN/kE6CMWJ4ZZgcXAyiOzn8BSshG2DhC5PNwzLTAxRBus8FgXR/9c0XOzchaP46Kq3hoBGFgeyW434tfuv5w==} hasBin: true - '@nrwl/workspace@19.6.4': - resolution: {integrity: sha512-jjqtRjm5AP39s8oPUEehA6O0Zew6BeTi+Uhjb+ggqbFKH9R9hoSITnbJY670WlO4W8yWYxT8isPf1TNdSHkmBw==} + '@nrwl/workspace@19.6.5': + resolution: {integrity: sha512-4oufH1plJjUy8g9kG7yRL/gQgoEUFc8Lmk1ibwUj2FrnkXJ0oE7DDtE5N9f/wCUg+uGSIgmrYyG4DGM9xGGQzg==} - '@nx/devkit@19.6.4': - resolution: {integrity: sha512-mBitFwb/gcz8MR7STt7KQG0vf+QcsasDXiSYcf3OWpc6lGE5wn1q5jg6Iabp49Bd/mdHXVLQnP1aV5A+QqFIOQ==} + '@nx/devkit@19.6.5': + resolution: {integrity: sha512-AEaMSr55Ar48QHU8TBi/gzLtjeT100zdyfLmk0RoiLzjjC8pWmm3Xfvqxyt1WsUUf4oQhlHlolJuoM41qKsdZw==} peerDependencies: nx: '>= 17 <= 20' - '@nx/js@19.6.4': - resolution: {integrity: sha512-Z09whMis90on3/5V0RIG1On5bRlNI4q2SGZQmj530+BqRTNdKNqxuYdpGf3oNbw5cgLVGiHcWtHzZROaAzpc4g==} + '@nx/js@19.6.5': + resolution: {integrity: sha512-nKK3fAJnFZZZF3hWRec64k+3JqcD0c9uZWXsXXEwZXmfB3TitPy+zczM2SSVvC50+AoIXGCCiFBUYesdxeReoQ==} peerDependencies: verdaccio: ^5.0.4 peerDependenciesMeta: verdaccio: optional: true - '@nx/nx-darwin-arm64@19.6.4': - resolution: {integrity: sha512-kRn2FLvhwJA/TJrNlsCSqqQTrguNZLmiRsiXhvjkfUMbUKwyQfVMgJlvkZ+KoqraUSG+Qyb0FmrGur1I/Mld0Q==} + '@nx/nx-darwin-arm64@19.6.5': + resolution: {integrity: sha512-sFU2k0BaklM17206F2E5C3866y0SICb0xyuPeD6D07a6hB4IstjIUkldUJJN70wEsJ5I3VP4yZ2oJcwnb1TTRQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@nx/nx-darwin-x64@19.6.4': - resolution: {integrity: sha512-3uABBUhxVk+SdRwpUu30iuBlgRWm3tA/G9seG+wt7oN2R+fOu8zzRCYa+Blvoh1Ef+D9743Ir4rDc9Mhzl2B2g==} + '@nx/nx-darwin-x64@19.6.5': + resolution: {integrity: sha512-EJmTbUPmlksgOap6xkQl89+zXwHpaAnZLsyLHUd7i00eVRa21FRhdKFnVsRxtwPDZp/YCG84IzMUye/IrwDFTQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@nx/nx-freebsd-x64@19.6.4': - resolution: {integrity: sha512-OG83MiEk5L54/vAldmwZJBKEvZaM+DEIDqn2yZLTToBRj5Z9jwKJX3jKP60xbHiaT/hzsb1xPlwhOHJnYd80EQ==} + '@nx/nx-freebsd-x64@19.6.5': + resolution: {integrity: sha512-rR8NJCskoEmIbK96uxaevHm146WDTA0V3jId+X1joITqjj3E2DMm0U4r5v/OgI5+iqbhFV4S83LrMxP6gBLTsQ==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@nx/nx-linux-arm-gnueabihf@19.6.4': - resolution: {integrity: sha512-hQ9x4qSKUh9mIVDuD270ULrBnmYfDTjXq7LnIwECw1AuP4LkKzKxULhsbqVnFQ/k3xxyFkwyGTIu2mfDcw16Gw==} + '@nx/nx-linux-arm-gnueabihf@19.6.5': + resolution: {integrity: sha512-OUHFV6iLlJN7b7qFnqLfa0Yj/aoylEiRXcEhV1bhPm0Ryt1bOeGDmLYScVN8n5t+AVmrwwYHk+ajXMzCOLLeZw==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@nx/nx-linux-arm64-gnu@19.6.4': - resolution: {integrity: sha512-OFKpAHiaVg3YGFIMBmi/JshciP9buwtOPiHDXcQdzQgE22jyYzKEiFxfcpG0nCT8PlMYAbHPAda15WfWkfVGVQ==} + '@nx/nx-linux-arm64-gnu@19.6.5': + resolution: {integrity: sha512-CzbJfb24poaJgBHt4aKLaL8a7bO9KXCLls+TX0SZfmzA9AWX6YuiX9lhxwBv6cqsViXTDB4KnXndMDB/H0Gk4g==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@nx/nx-linux-arm64-musl@19.6.4': - resolution: {integrity: sha512-ZIR9u+mN0A7SmNd6vDxmPV1QVTgYPTdfBSM5TEnKl3q2fHw2Nkui81QBxA4d7VopJoJUz/pRHiUV+dlgEEZ6nA==} + '@nx/nx-linux-arm64-musl@19.6.5': + resolution: {integrity: sha512-MgidKilQ0KWxQbTnaqXGjASu7wtAC9q6zAwFNKFENkwJq3nThaQH6jQVlnINE4lL9NSgyyg0AS/ix31hiqAgvA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@nx/nx-linux-x64-gnu@19.6.4': - resolution: {integrity: sha512-AUMPvLs9KeCUuWD5DdlpbP3VfVsiD0IlptS2b3ul336rsQ7LwwdvE7jTVO5CixFOsiRZxP72fKJhaEargMn5Aw==} + '@nx/nx-linux-x64-gnu@19.6.5': + resolution: {integrity: sha512-rGDylAoslIlk5TDbEJ6YoQOYxxYP9gCpi6FLke2mFgXVzOmVlLKHfVsegIHYVMYYF26h3NJh0NLGGzGdoBjWgQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@nx/nx-linux-x64-musl@19.6.4': - resolution: {integrity: sha512-PU7AaBlrgnJnDxTiV/PNCu0pHUCzaogm6uNcbzCyFJLGn7DoQK9rkqUMPJjb3CnJkAj9XrrhuZwmOdbrhvHAvA==} + '@nx/nx-linux-x64-musl@19.6.5': + resolution: {integrity: sha512-C/pNjDL/bDEcrDypgBo4r1AOiPTk8gWJwBsFE1QHIvg7//5WFSreqRj34rJu/GZ95eLYJH5tje1VW6z+atEGkQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@nx/nx-win32-arm64-msvc@19.6.4': - resolution: {integrity: sha512-6CCmGWwH/J2k+Uxeci48w4QVhtcQ3hRZ5Z2jh26HI8YzH4wqZyA7QPgLBE6sNCPVLoGW5cBgTsfnyEdr+xarQA==} + '@nx/nx-win32-arm64-msvc@19.6.5': + resolution: {integrity: sha512-mMi8i16OFux17xed2iLPWwUdCbS1mYA9Ny/gnoNUCosmihmXX9wrzaGBkNAMsHA28huYQtPhGormsEs+zuiVFg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@nx/nx-win32-x64-msvc@19.6.4': - resolution: {integrity: sha512-jTNrlaFaKtbL2mYOcfPAiljtpF5CI7vbHIqYqBFYLUQXOwW9lOHlO+SeQnft6JYZs0FIr1IdHaCfdOw/hpnCiQ==} + '@nx/nx-win32-x64-msvc@19.6.5': + resolution: {integrity: sha512-jjhbDYNBkyz9Fg1jf0KZTrgdf/yx4v+k0ifukDIHZjva+jko0Ve5WzdkQ2K07M9ZxxYibDtTDqX9uX6+eFZtoA==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@nx/workspace@19.6.4': - resolution: {integrity: sha512-SMrI03OmjYm93XpDTlIWgAyIaEhToN4LNu4cxOXW9ygpzPe8HJlqR18aTaCqu1T+BY8XeaZ8BQ7qYS1kEjM9YA==} + '@nx/workspace@19.6.5': + resolution: {integrity: sha512-1r5Vgk1Y5+y1K20O9d59ALjlyLYOU4XcybIiN4Wonw+oYrg6ZXSeA3R+lLSuTA4dHtfxcNsCIigzcSEUwchNwg==} '@oxc-resolver/binding-darwin-arm64@1.11.0': resolution: {integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==} @@ -2158,8 +2158,8 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} - nx@19.6.4: - resolution: {integrity: sha512-yudYlBd3cMchRd8c0ZNan1SfT19AYK2zYOp77XVqVVwgqb6rJVxz6StFGFluUQ7Q7uSpkeT/8PsjwPVLt85EoQ==} + nx@19.6.5: + resolution: {integrity: sha512-igPYPsBF1BM1YxEiGDvaLOz0CWWoEvxzR7yQg3iULjGG9zKgDFNHHIHJwkyHsCBTtMhhkgeUl16PsTVgDuil3A==} hasBin: true peerDependencies: '@swc-node/register': ^1.8.0 @@ -3637,15 +3637,15 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 - '@nrwl/devkit@19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': + '@nrwl/devkit@19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': dependencies: - '@nx/devkit': 19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nx/devkit': 19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) transitivePeerDependencies: - nx - '@nrwl/js@19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': + '@nrwl/js@19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': dependencies: - '@nx/js': 19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + '@nx/js': 19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -3658,37 +3658,37 @@ snapshots: - typescript - verdaccio - '@nrwl/tao@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nrwl/tao@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - nx: 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) tslib: 2.7.0 transitivePeerDependencies: - '@swc-node/register' - '@swc/core' - debug - '@nrwl/workspace@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nrwl/workspace@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - '@nx/workspace': 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nx/workspace': 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) transitivePeerDependencies: - '@swc-node/register' - '@swc/core' - debug - '@nx/devkit@19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': + '@nx/devkit@19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': dependencies: - '@nrwl/devkit': 19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nrwl/devkit': 19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) ejs: 3.1.10 enquirer: 2.3.6 ignore: 5.3.2 minimatch: 9.0.3 - nx: 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) semver: 7.6.3 tmp: 0.2.3 tslib: 2.7.0 yargs-parser: 21.1.1 - '@nx/js@19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': + '@nx/js@19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': dependencies: '@babel/core': 7.25.2 '@babel/plugin-proposal-decorators': 7.24.7(@babel/core@7.25.2) @@ -3697,9 +3697,9 @@ snapshots: '@babel/preset-env': 7.25.4(@babel/core@7.25.2) '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) '@babel/runtime': 7.25.4 - '@nrwl/js': 19.6.4(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) - '@nx/devkit': 19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) - '@nx/workspace': 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nrwl/js': 19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + '@nx/devkit': 19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nx/workspace': 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) babel-plugin-const-enum: 1.2.0(@babel/core@7.25.2) babel-plugin-macros: 2.8.0 babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.25.2)(@babel/traverse@7.25.4) @@ -3731,43 +3731,43 @@ snapshots: - supports-color - typescript - '@nx/nx-darwin-arm64@19.6.4': + '@nx/nx-darwin-arm64@19.6.5': optional: true - '@nx/nx-darwin-x64@19.6.4': + '@nx/nx-darwin-x64@19.6.5': optional: true - '@nx/nx-freebsd-x64@19.6.4': + '@nx/nx-freebsd-x64@19.6.5': optional: true - '@nx/nx-linux-arm-gnueabihf@19.6.4': + '@nx/nx-linux-arm-gnueabihf@19.6.5': optional: true - '@nx/nx-linux-arm64-gnu@19.6.4': + '@nx/nx-linux-arm64-gnu@19.6.5': optional: true - '@nx/nx-linux-arm64-musl@19.6.4': + '@nx/nx-linux-arm64-musl@19.6.5': optional: true - '@nx/nx-linux-x64-gnu@19.6.4': + '@nx/nx-linux-x64-gnu@19.6.5': optional: true - '@nx/nx-linux-x64-musl@19.6.4': + '@nx/nx-linux-x64-musl@19.6.5': optional: true - '@nx/nx-win32-arm64-msvc@19.6.4': + '@nx/nx-win32-arm64-msvc@19.6.5': optional: true - '@nx/nx-win32-x64-msvc@19.6.4': + '@nx/nx-win32-x64-msvc@19.6.5': optional: true - '@nx/workspace@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nx/workspace@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - '@nrwl/workspace': 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) - '@nx/devkit': 19.6.4(nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nrwl/workspace': 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nx/devkit': 19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) chalk: 4.1.2 enquirer: 2.3.6 - nx: 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) tslib: 2.7.0 yargs-parser: 21.1.1 transitivePeerDependencies: @@ -4765,10 +4765,10 @@ snapshots: dependencies: path-key: 3.1.1 - nx@19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)): + nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)): dependencies: '@napi-rs/wasm-runtime': 0.2.4 - '@nrwl/tao': 19.6.4(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nrwl/tao': 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.0-rc.46 '@zkochan/js-yaml': 0.0.7 @@ -4803,16 +4803,16 @@ snapshots: yargs: 17.7.2 yargs-parser: 21.1.1 optionalDependencies: - '@nx/nx-darwin-arm64': 19.6.4 - '@nx/nx-darwin-x64': 19.6.4 - '@nx/nx-freebsd-x64': 19.6.4 - '@nx/nx-linux-arm-gnueabihf': 19.6.4 - '@nx/nx-linux-arm64-gnu': 19.6.4 - '@nx/nx-linux-arm64-musl': 19.6.4 - '@nx/nx-linux-x64-gnu': 19.6.4 - '@nx/nx-linux-x64-musl': 19.6.4 - '@nx/nx-win32-arm64-msvc': 19.6.4 - '@nx/nx-win32-x64-msvc': 19.6.4 + '@nx/nx-darwin-arm64': 19.6.5 + '@nx/nx-darwin-x64': 19.6.5 + '@nx/nx-freebsd-x64': 19.6.5 + '@nx/nx-linux-arm-gnueabihf': 19.6.5 + '@nx/nx-linux-arm64-gnu': 19.6.5 + '@nx/nx-linux-arm64-musl': 19.6.5 + '@nx/nx-linux-x64-gnu': 19.6.5 + '@nx/nx-linux-x64-musl': 19.6.5 + '@nx/nx-win32-arm64-msvc': 19.6.5 + '@nx/nx-win32-x64-msvc': 19.6.5 '@swc-node/register': 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) '@swc/core': 1.5.29(@swc/helpers@0.5.12) transitivePeerDependencies: diff --git a/scripts/changelog-renderer.cjs b/scripts/changelog-renderer.cjs new file mode 100644 index 00000000000..a9513bf9e4b --- /dev/null +++ b/scripts/changelog-renderer.cjs @@ -0,0 +1,30 @@ +// @ts-check +const { default: defaultChangelogRenderer } = require('nx/release/changelog-renderer'); + +const changelogRenderer = async ({ + projectGraph, + commits, + releaseVersion, + project, + entryWhenNoChanges, + changelogRenderOptions, + repoSlug, + conventionalCommitsConfig, + changes, +}) => { + const defaultChangelog = await defaultChangelogRenderer({ + projectGraph, + commits, + releaseVersion, + project, + entryWhenNoChanges, + changelogRenderOptions, + repoSlug, + conventionalCommitsConfig, + changes, + }); + // Rename the authors section title + return defaultChangelog.replace('❤️ Thank You', 'Contributors'); +}; + +module.exports = changelogRenderer; From dfd3a1f7f2d77bbb373d3026542ff841fb7189fd Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 4 Sep 2024 15:42:26 -0700 Subject: [PATCH 428/730] Update README --- packages/lazy-file/README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/lazy-file/README.md b/packages/lazy-file/README.md index 51314246712..b04189370e4 100644 --- a/packages/lazy-file/README.md +++ b/packages/lazy-file/README.md @@ -73,7 +73,7 @@ The `lazy-file/fs` export provides functions for reading from and writing to the import { openFile, writeFile } from '@mjackson/lazy-file/fs'; // No data is read at this point, it's just a reference to a -// file on the local filesystem. +// file on the local filesystem let file = openFile('./path/to/file.json'); // Data is read when you call file.text() (or any of the @@ -81,13 +81,18 @@ let file = openFile('./path/to/file.json'); let json = JSON.parse(await file.text()); // Write the file's contents back to the filesystem at a -// different path. +// different path await writeFile('./path/to/other-file.json', file); +// Or write to an open file handle/descriptor +import * as fsp from 'node:fs/promises'; +let handle = await fsp.open('./path/to/other-file.json'); +await writeFile(handle, file); + let imageFile = openFile('./path/to/image.jpg'); // Get a LazyBlob that omits the first 100 bytes of the file. -// This could be useful for serving HTTP Range requests. +// This could be useful e.g. when serving HTTP Range requests let blob = imageFile.slice(100); ``` From ea7769918fe14b95783de787780665758158985e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 4 Sep 2024 16:09:53 -0700 Subject: [PATCH 429/730] Release lazy-file 3.1.0 --- .nx/version-plans/version-plan-1725167067278.md | 5 ----- .nx/version-plans/version-plan-1725474145080.md | 5 ----- packages/lazy-file/CHANGELOG.md | 14 ++++++++++++++ packages/lazy-file/package.json | 2 +- 4 files changed, 15 insertions(+), 11 deletions(-) delete mode 100644 .nx/version-plans/version-plan-1725167067278.md delete mode 100644 .nx/version-plans/version-plan-1725474145080.md diff --git a/.nx/version-plans/version-plan-1725167067278.md b/.nx/version-plans/version-plan-1725167067278.md deleted file mode 100644 index 795622e31cd..00000000000 --- a/.nx/version-plans/version-plan-1725167067278.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@mjackson/lazy-file': minor ---- - -Add writeFile method to lazy-file/fs and rename getFile => openFile diff --git a/.nx/version-plans/version-plan-1725474145080.md b/.nx/version-plans/version-plan-1725474145080.md deleted file mode 100644 index 7f38d93be9a..00000000000 --- a/.nx/version-plans/version-plan-1725474145080.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@mjackson/lazy-file': minor ---- - -Accept an open file descriptor or file handle in `writeFile(fd)` diff --git a/packages/lazy-file/CHANGELOG.md b/packages/lazy-file/CHANGELOG.md index 4fab38f7dc4..5185ec2e9dc 100644 --- a/packages/lazy-file/CHANGELOG.md +++ b/packages/lazy-file/CHANGELOG.md @@ -1,3 +1,17 @@ +## 3.1.0 (2024-09-04) + + +### 🚀 Features + +- Add writeFile method to lazy-file/fs and rename getFile => openFile ([f7233a8](https://github.com/mjackson/remix-the-web/commit/f7233a8)) + +- Accept an open file descriptor or file handle in `writeFile(fd)` ([d5087ba](https://github.com/mjackson/remix-the-web/commit/d5087ba)) + + +### ❤️ Thank You + +- Michael Jackson @mjackson + ## v3.0.0 (2024-08-25) - BREAKING: Do not accept regular string argument to `LazyFile`. This more closely matches `File` behavior diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index e8ecc708994..fe517735e3f 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/lazy-file", - "version": "3.0.0", + "version": "3.1.0", "description": "Lazy, streaming files for JavaScript", "author": "Michael Jackson ", "repository": { From 1bb76f39e14b56e3763069890f0fe58a9a874810 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 4 Sep 2024 17:39:47 -0700 Subject: [PATCH 430/730] Release file-storage@0.2.1 --- .nx/version-plans/version-plan-1725471973201.md | 5 ----- packages/file-storage/CHANGELOG.md | 4 ++++ packages/file-storage/package.json | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 .nx/version-plans/version-plan-1725471973201.md diff --git a/.nx/version-plans/version-plan-1725471973201.md b/.nx/version-plans/version-plan-1725471973201.md deleted file mode 100644 index 4e55a5e5bbd..00000000000 --- a/.nx/version-plans/version-plan-1725471973201.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@mjackson/file-storage': patch ---- - -Clean up old files on disk when they are replaced by new ones with the same key diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 704eb35196b..38620bddeb9 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -1,3 +1,7 @@ +## v0.2.1 (2024-09-04) + +- Automatically clean up old files in `LocalFileStorage` when new files are stored with the same key + ## v0.2.0 (2024-08-26) - Moved `LocalFileStorage` to `file-storage/local` export diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index ac2bf1f81ec..43e80ca5de9 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/file-storage", - "version": "0.2.0", + "version": "0.2.1", "description": "Key/value storage for JavaScript File objects", "author": "Michael Jackson ", "repository": { From 5462331f0f7d834d8fdc630f5d3a081b267b2923 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 4 Sep 2024 22:16:11 -0700 Subject: [PATCH 431/730] Upgrade to lazy-file@3.1.0 --- packages/file-storage/CHANGELOG.md | 4 ++++ packages/file-storage/package.json | 2 +- .../file-storage/src/lib/local-file-storage.ts | 14 ++++---------- pnpm-lock.yaml | 10 +++++----- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 38620bddeb9..308cbf33ae5 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -1,3 +1,7 @@ +## HEAD + +- Upgrade to lazy-file@3.1.0 + ## v0.2.1 (2024-09-04) - Automatically clean up old files in `LocalFileStorage` when new files are stored with the same key diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index 43e80ca5de9..a92ac3e4ea3 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -22,7 +22,7 @@ "./package.json": "./package.json" }, "dependencies": { - "@mjackson/lazy-file": "^2.2.0" + "@mjackson/lazy-file": "^3.1.0" }, "devDependencies": { "@types/node": "^20.14.10" diff --git a/packages/file-storage/src/lib/local-file-storage.ts b/packages/file-storage/src/lib/local-file-storage.ts index bcedcb36f83..355555df644 100644 --- a/packages/file-storage/src/lib/local-file-storage.ts +++ b/packages/file-storage/src/lib/local-file-storage.ts @@ -1,7 +1,7 @@ import * as fs from 'node:fs'; import * as fsp from 'node:fs/promises'; import * as path from 'node:path'; -import { getFile } from '@mjackson/lazy-file/fs'; +import { openFile, writeFile } from '@mjackson/lazy-file/fs'; import { FileStorage } from './file-storage.js'; @@ -64,7 +64,7 @@ export class LocalFileStorage implements FileStorage { let filename = path.join(this.#dirname, metadata.file); - return getFile(filename, { + return openFile(filename, { name: metadata.name, type: metadata.type, lastModified: metadata.mtime, @@ -104,13 +104,7 @@ async function storeFile(dirname: string, file: File): Promise { } } - try { - for await (let chunk of file.stream()) { - await handle.write(chunk); - } - } finally { - await handle.close(); - } + await writeFile(handle, file); return filename; } @@ -135,7 +129,7 @@ class FileMetadataIndex { async #getAll(): Promise> { try { - return JSON.parse(await getFile(this.#path).text()); + return JSON.parse(await openFile(this.#path).text()); } catch (error) { if (!isNoEntityError(error)) { throw error; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 92511d14b2f..192d58943d9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,8 +33,8 @@ importers: packages/file-storage: dependencies: '@mjackson/lazy-file': - specifier: ^2.2.0 - version: 2.2.0 + specifier: ^3.1.0 + version: 3.1.0 devDependencies: '@types/node': specifier: ^20.14.10 @@ -1029,8 +1029,8 @@ packages: '@mjackson/headers@0.5.1': resolution: {integrity: sha512-sJpFgecPT/zJvwk3GRNVWNs8EkwaJoUNU2D0VMlp+gDJs6cuSTm1q/aCZi3ZtuV6CgDEQ4l2ZjUG3A9JrQlbNA==} - '@mjackson/lazy-file@2.2.0': - resolution: {integrity: sha512-51M2TAL5eMZj5mh1e22/qBl4C5udViZqSBEqwiHSi1lTAixCp4YiAOV62VaTSqVp771OkmgNCPsh8/LpJ/A/Yw==} + '@mjackson/lazy-file@3.1.0': + resolution: {integrity: sha512-YdlmPLtRjQotP/It1hxVsz6tBJh63e/xD40s6eBLfgFr8tQ5zE+gJtpz+t/4vbTXv4axRulDfXG2XJtVpXmkUw==} '@mjackson/multipart-parser@0.6.2': resolution: {integrity: sha512-xG3mINK6gFVposxu83x3n4ueJfjWoxOl3UaBADXNjh/NL84L+Zc/kmz2mTQA9GHvHFPAMlXqPSLTocIDkmhemQ==} @@ -3611,7 +3611,7 @@ snapshots: '@mjackson/headers@0.5.1': {} - '@mjackson/lazy-file@2.2.0': + '@mjackson/lazy-file@3.1.0': dependencies: mrmime: 2.0.0 From b464a1339cb40f575b9cc6542736fa8b5040baf8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 4 Sep 2024 23:30:21 -0700 Subject: [PATCH 432/730] Fix console.log(fileUpload) Fixes https://github.com/mjackson/form-data-parser/issues/4 --- packages/form-data-parser/CHANGELOG.md | 4 ++++ .../form-data-parser/src/lib/form-data.spec.ts | 2 +- packages/form-data-parser/src/lib/form-data.ts | 17 ++++++++++++----- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index d0cd4c1db8b..03c3eef3bdd 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -1,3 +1,7 @@ +## HEAD + +- Make `FileUpload` implement the `File` interface instead of extending `File` (fixes https://github.com/mjackson/form-data-parser/issues/4) + ## v0.2.0 (2024-08-28) - Add missing `FileUpload` export 🤦‍♂️ diff --git a/packages/form-data-parser/src/lib/form-data.spec.ts b/packages/form-data-parser/src/lib/form-data.spec.ts index a2591d3aee6..d68c2d235d6 100644 --- a/packages/form-data-parser/src/lib/form-data.spec.ts +++ b/packages/form-data-parser/src/lib/form-data.spec.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it, mock } from 'node:test'; -import { type FileUploadHandler, parseFormData } from './form-data.js'; +import { FileUploadHandler, parseFormData } from './form-data.js'; describe('parseFormData', () => { it('parses a application/x-www-form-urlencoded request', async () => { diff --git a/packages/form-data-parser/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts index 42fdf73b477..2dc0865395d 100644 --- a/packages/form-data-parser/src/lib/form-data.ts +++ b/packages/form-data-parser/src/lib/form-data.ts @@ -5,20 +5,27 @@ import { } from '@mjackson/multipart-parser'; /** - * A `File` that was uploaded as part of a `multipart/form-data` request. + * A file that was uploaded as part of a `multipart/form-data` request. * * This object is intended to be used as an intermediary for handling file uploads. The file should * be saved to disk or a cloud storage service as quickly as possible to avoid buffering and * backpressure building up in the input stream. * - * Note: Although this is a `File` object its `size` is unknown, so any attempt to access - * `file.size` or use `file.slice()` will throw an error. + * Note: Although `FileUpload` implements the `File` interface, its `size` is unknown, so any + * attempt to access `file.size` or use `file.slice()` will throw an error. */ -export class FileUpload extends File { +export class FileUpload implements File { + readonly name: string; + readonly type: string; + readonly lastModified: number; + readonly webkitRelativePath = ''; + #part: MultipartPart; constructor(part: MultipartPart) { - super([], part.filename ?? '', { type: part.mediaType }); + this.name = part.filename ?? ''; + this.type = part.mediaType ?? ''; + this.lastModified = Date.now(); this.#part = part; } From c62c90d615d9c288b836a0eac351a7b9a8c170b5 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 4 Sep 2024 23:41:19 -0700 Subject: [PATCH 433/730] Update README --- packages/form-data-parser/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/form-data-parser/README.md b/packages/form-data-parser/README.md index 2d0f32857bf..4864416e0a5 100644 --- a/packages/form-data-parser/README.md +++ b/packages/form-data-parser/README.md @@ -39,7 +39,7 @@ async function uploadHandler(fileUpload: FileUpload) { // FileUpload objects are not meant to stick around for very long (they are // streaming data from the request.body!) so we should store them as soon as // possible. - await fileStorage.put(storageKey, fileUpload); + await fileStorage.set(storageKey, fileUpload); // Return a File for the FormData object. This is a LazyFile that knows how // to access the file's content if needed (using e.g. file.stream()) but @@ -53,7 +53,7 @@ async function uploadHandler(fileUpload: FileUpload) { async function requestHandler(request: Request) { let formData = await parseFormData(request, uploadHandler); - let file = formData.get('user-avatar'); // File (LazyFile) + let file = formData.get('user-avatar'); // File file.name; // "my-avatar.jpg" (name of the file on the user's computer) file.size; // number file.type; // "image/jpeg" @@ -63,7 +63,7 @@ async function requestHandler(request: Request) { ## Related Packages - [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser) - The parser used internally for parsing `multipart/form-data` HTTP messages -- [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage) - A simple interface for storing `FileUpload` objects you get from the parser +- [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage) - A simple key/value interface for storing `FileUpload` objects you get from the parser ## License From e1510314c077c8770a970285286bd3f58d630871 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 4 Sep 2024 23:43:56 -0700 Subject: [PATCH 434/730] Allow returning null from upload handlers --- packages/form-data-parser/CHANGELOG.md | 1 + .../src/lib/form-data.spec.ts | 23 +++++++++++++++++++ .../form-data-parser/src/lib/form-data.ts | 6 ++--- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index 03c3eef3bdd..dabca3ddf63 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -1,6 +1,7 @@ ## HEAD - Make `FileUpload` implement the `File` interface instead of extending `File` (fixes https://github.com/mjackson/form-data-parser/issues/4) +- Allow returning `null` from an upload handler, so it allows `return fileStorage.get(key)` without type errors ## v0.2.0 (2024-08-28) diff --git a/packages/form-data-parser/src/lib/form-data.spec.ts b/packages/form-data-parser/src/lib/form-data.spec.ts index d68c2d235d6..49b60490795 100644 --- a/packages/form-data-parser/src/lib/form-data.spec.ts +++ b/packages/form-data-parser/src/lib/form-data.spec.ts @@ -76,4 +76,27 @@ describe('parseFormData', () => { assert.equal(fileUploadHandler.mock.calls.length, 2); }); + + it('allows returning `null` from the upload handler', async () => { + let request = new Request('http://localhost:8080', { + method: 'POST', + headers: { + 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW', + }, + body: [ + '------WebKitFormBoundary7MA4YWxkTrZu0gW', + 'Content-Disposition: form-data; name="file"; filename="example.txt"', + 'Content-Type: text/plain', + '', + 'This is an example file.', + '------WebKitFormBoundary7MA4YWxkTrZu0gW--', + ].join('\r\n'), + }); + + let formData = await parseFormData(request, (fileUpload) => { + return null; + }); + + assert.equal(formData.get('file'), null); + }); }); diff --git a/packages/form-data-parser/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts index 2dc0865395d..138677bc308 100644 --- a/packages/form-data-parser/src/lib/form-data.ts +++ b/packages/form-data-parser/src/lib/form-data.ts @@ -65,13 +65,13 @@ export class FileUpload implements File { * A function used for handling file uploads. */ export interface FileUploadHandler { - (file: FileUpload): File | void | Promise; + (file: FileUpload): void | null | File | Promise; } async function defaultFileUploadHandler(file: FileUpload): Promise { // Do the slow thing and buffer the entire file in memory. let buffer = await file.arrayBuffer(); - return new File([buffer], file.name, { type: file.type }); + return new File([buffer], file.name, { type: file.type, lastModified: file.lastModified }); } /** @@ -94,7 +94,7 @@ export async function parseFormData( if (part.isFile) { let file = await uploadHandler(new FileUpload(part)); - if (file) { + if (file != null) { formData.append(part.name, file); } } else { From 3febdaccb267077890e65f6baad636f64f6911af Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 5 Sep 2024 00:04:13 -0700 Subject: [PATCH 435/730] Release form-data-parser@0.3.0 --- packages/form-data-parser/CHANGELOG.md | 2 +- packages/form-data-parser/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index dabca3ddf63..1f743c3bc65 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -1,4 +1,4 @@ -## HEAD +## v0.3.0 (2024-09-05) - Make `FileUpload` implement the `File` interface instead of extending `File` (fixes https://github.com/mjackson/form-data-parser/issues/4) - Allow returning `null` from an upload handler, so it allows `return fileStorage.get(key)` without type errors diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index 5d671d0a4c4..6aac6aab3ad 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/form-data-parser", - "version": "0.2.0", + "version": "0.3.0", "description": "A request.formData() wrapper with streaming file upload handling", "author": "Michael Jackson ", "repository": { From c4e3524d7db71191ae92ab48b958a9729426eb00 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 5 Sep 2024 09:41:36 -0700 Subject: [PATCH 436/730] Update README --- packages/form-data-parser/README.md | 2 +- packages/multipart-parser/README.md | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/form-data-parser/README.md b/packages/form-data-parser/README.md index 4864416e0a5..a355da7c850 100644 --- a/packages/form-data-parser/README.md +++ b/packages/form-data-parser/README.md @@ -62,8 +62,8 @@ async function requestHandler(request: Request) { ## Related Packages -- [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser) - The parser used internally for parsing `multipart/form-data` HTTP messages - [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage) - A simple key/value interface for storing `FileUpload` objects you get from the parser +- [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser) - The parser used internally for parsing `multipart/form-data` HTTP messages ## License diff --git a/packages/multipart-parser/README.md b/packages/multipart-parser/README.md index 2b2edcb7f5b..1a24d18e885 100644 --- a/packages/multipart-parser/README.md +++ b/packages/multipart-parser/README.md @@ -209,10 +209,8 @@ pnpm run bench ## Related Packages -- [`headers`](https://github.com/mjackson/remix-the-web/tree/main/packages/headers) - Used internally to parse HTTP headers and get - metadata (filename, content type) for each `MultipartPart` -- [`form-data-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser) - Uses `multipart-parser` - internally to parse multipart requests and generate `FileUpload`s for storage +- [`form-data-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser) - Uses `multipart-parser` internally to parse multipart requests and generate `FileUpload`s for storage +- [`headers`](https://github.com/mjackson/remix-the-web/tree/main/packages/headers) - Used internally to parse HTTP headers and get metadata (filename, content type) for each `MultipartPart` ## Credits From c6eb0095670d98746c380b6f57f31d726c85eb40 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 5 Sep 2024 09:53:48 -0700 Subject: [PATCH 437/730] Release node-fetch-server@0.1.0 --- packages/node-fetch-server/CHANGELOG.md | 3 +++ packages/node-fetch-server/package.json | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index e69de29bb2d..747b95f0d4d 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -0,0 +1,3 @@ +## v0.1.0 (2024-09-05) + +- Initial release diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 9e5c0cef09e..39cd4e0757d 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/node-fetch-server", - "version": "0.0.0", + "version": "0.1.0", "description": "Build servers for Node.js using the web fetch API", "author": "Michael Jackson ", "repository": { @@ -8,6 +8,7 @@ "url": "git+https://github.com/mjackson/remix-the-web.git", "directory": "packages/node-fetch-server" }, + "homepage": "https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server#readme", "license": "MIT", "files": [ "dist", From 8c59219f2dee9f44c7cfd08a2cc7f7c7e095e818 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 5 Sep 2024 09:55:59 -0700 Subject: [PATCH 438/730] Add homepage URL --- packages/file-storage/package.json | 1 + packages/form-data-parser/package.json | 1 + packages/headers/package.json | 1 + packages/lazy-file/package.json | 1 + packages/multipart-parser/package.json | 1 + 5 files changed, 5 insertions(+) diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index a92ac3e4ea3..7cab69fdac5 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -8,6 +8,7 @@ "url": "git+https://github.com/mjackson/remix-the-web.git", "directory": "packages/file-storage" }, + "homepage": "https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage#readme", "license": "MIT", "files": [ "dist", diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index 6aac6aab3ad..504357b87b4 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -8,6 +8,7 @@ "url": "git+https://github.com/mjackson/remix-the-web.git", "directory": "packages/form-data-parser" }, + "homepage": "https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser#readme", "license": "MIT", "files": [ "dist", diff --git a/packages/headers/package.json b/packages/headers/package.json index 9c2d22bf569..f284bba1461 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -9,6 +9,7 @@ "url": "git+https://github.com/mjackson/remix-the-web.git", "directory": "packages/headers" }, + "homepage": "https://github.com/mjackson/remix-the-web/tree/main/packages/headers#readme", "files": [ "dist", "LICENSE", diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index fe517735e3f..ad618562b34 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -8,6 +8,7 @@ "url": "git+https://github.com/mjackson/remix-the-web.git", "directory": "packages/lazy-file" }, + "homepage": "https://github.com/mjackson/remix-the-web/tree/main/packages/lazy-file#readme", "license": "MIT", "files": [ "dist", diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 5d041fe03b5..852dc662f31 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -8,6 +8,7 @@ "url": "git+https://github.com/mjackson/remix-the-web.git", "directory": "packages/multipart-parser" }, + "homepage": "https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser#readme", "license": "MIT", "files": [ "dist", From 2685900a837f3b073bad4e787614412f7bf84f4d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 5 Sep 2024 09:56:54 -0700 Subject: [PATCH 439/730] Update README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 231e027624b..0b9cf8f04d8 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ We currently publish the following packages: - [headers](packages/headers): A toolkit for working with HTTP headers in JavaScript - [lazy-file](packages/lazy-file): Lazy, streaming `Blob`s and `File`s for JavaScript - [multipart-parser](packages/multipart-parser): Fast, efficient parser for multipart streams +- [node-fetch-server](packages/node-fetch-server): Build HTTP servers for Node.js using the web fetch API ## License From 979e22544011595557fd275764f9815a6f95b8b3 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 5 Sep 2024 13:12:24 -0700 Subject: [PATCH 440/730] Update README --- packages/node-fetch-server/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/node-fetch-server/README.md b/packages/node-fetch-server/README.md index a14ca1ceea4..3771c05f78d 100644 --- a/packages/node-fetch-server/README.md +++ b/packages/node-fetch-server/README.md @@ -29,9 +29,9 @@ npm install @mjackson/node-fetch-server ```ts import * as http from 'node:http'; -import { type FetchHandler, createRequestListener } from '@mjackson/node-fetch-server'; +import { createRequestListener } from '@mjackson/node-fetch-server'; -let handler: FetchHandler = (request) => { +let handler = (request: Request) => { return new Response('Hello, world!'); }; @@ -45,9 +45,9 @@ By default `request.url` is derived from the value of the `Host` HTTP header and ```ts import * as assert from 'node:assert/strict'; import * as http from 'node:http'; -import { type FetchHandler, createRequestListener } from '@mjackson/node-fetch-server'; +import { createRequestListener } from '@mjackson/node-fetch-server'; -let handler: FetchHandler = (request) => { +let handler = (request: Request) => { // This is now true assert.equal(new URL(request.url).host, process.env.HOST); return new Response('Hello, world!'); From f172821da82c6c6b20a2e4b08ca6b701569ef5e8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 5 Sep 2024 13:13:15 -0700 Subject: [PATCH 441/730] Small style tweak --- packages/multipart-parser/src/lib/multipart.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/multipart-parser/src/lib/multipart.ts b/packages/multipart-parser/src/lib/multipart.ts index eafb05bb1c3..a5ad3c91f18 100644 --- a/packages/multipart-parser/src/lib/multipart.ts +++ b/packages/multipart-parser/src/lib/multipart.ts @@ -144,16 +144,10 @@ export class MultipartParser { #bodyController: ReadableStreamDefaultController | null = null; #bodyLength = 0; - constructor( - boundary: string, - { - maxHeaderSize = 8 * 1024, // 8 KB - maxFileSize = Infinity, - }: MultipartParserOptions = {}, - ) { + constructor(boundary: string, options?: MultipartParserOptions) { this.boundary = boundary; - this.maxHeaderSize = maxHeaderSize; - this.maxFileSize = maxFileSize; + this.maxHeaderSize = options?.maxHeaderSize ?? 8 * 1024; + this.maxFileSize = options?.maxFileSize ?? Infinity; this.#findOpeningBoundary = createSearch(`--${boundary}`); this.#openingBoundaryLength = 2 + boundary.length; // length of '--' + boundary From 02ced7726f286414bebb027be6113c07b73e196e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 5 Sep 2024 13:13:57 -0700 Subject: [PATCH 442/730] Prep for release --- packages/multipart-parser/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index 6990936f3d2..db57f25102a 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -1,3 +1,7 @@ +## HEAD + +- Moved to a new monorepo + ## v0.6.2 (2024-08-19) - Provide correct type for `part.arrayBuffer()` From ea036556ef67f04804b1d18b8193f886e3df6a35 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 5 Sep 2024 13:14:56 -0700 Subject: [PATCH 443/730] Release multipart-parser@0.6.3 --- packages/multipart-parser/CHANGELOG.md | 2 +- packages/multipart-parser/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index db57f25102a..e4cf8128dc5 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -1,4 +1,4 @@ -## HEAD +## v0.6.3 (2024-09-05) - Moved to a new monorepo diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 852dc662f31..aee877cc784 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.6.2", + "version": "0.6.3", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "repository": { From bcfb1bda4ddb508419e5f209f5afb4ed89572b79 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 5 Sep 2024 13:16:44 -0700 Subject: [PATCH 444/730] Allow passing multipart parser options through --- packages/form-data-parser/CHANGELOG.md | 4 ++++ packages/form-data-parser/src/lib/form-data.ts | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index 1f743c3bc65..1eec08b2928 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -1,3 +1,7 @@ +## HEAD + +- Allow passing `MultipartParserOptions` as optional 3rd arg to `parseFormData()` + ## v0.3.0 (2024-09-05) - Make `FileUpload` implement the `File` interface instead of extending `File` (fixes https://github.com/mjackson/form-data-parser/issues/4) diff --git a/packages/form-data-parser/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts index 138677bc308..560d83e7162 100644 --- a/packages/form-data-parser/src/lib/form-data.ts +++ b/packages/form-data-parser/src/lib/form-data.ts @@ -1,6 +1,7 @@ import { isMultipartRequest, parseMultipartRequest, + MultipartParserOptions, MultipartPart, } from '@mjackson/multipart-parser'; @@ -85,11 +86,12 @@ async function defaultFileUploadHandler(file: FileUpload): Promise { export async function parseFormData( request: Request, uploadHandler: FileUploadHandler = defaultFileUploadHandler, + parserOptions?: MultipartParserOptions, ): Promise { if (isMultipartRequest(request)) { let formData = new FormData(); - for await (let part of parseMultipartRequest(request)) { + for await (let part of parseMultipartRequest(request, parserOptions)) { if (!part.name) continue; if (part.isFile) { From 111bb8e8ba89e2c44f0d9385a943d0ce2540a389 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 5 Sep 2024 13:17:56 -0700 Subject: [PATCH 445/730] Release form-data-parser@0.4.0 --- packages/form-data-parser/CHANGELOG.md | 2 +- packages/form-data-parser/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index 1eec08b2928..1aa4f883771 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -1,4 +1,4 @@ -## HEAD +## v0.4.0 (2024-09-05) - Allow passing `MultipartParserOptions` as optional 3rd arg to `parseFormData()` diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index 504357b87b4..e45df2caa9a 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/form-data-parser", - "version": "0.3.0", + "version": "0.4.0", "description": "A request.formData() wrapper with streaming file upload handling", "author": "Michael Jackson ", "repository": { From 75efc3981d438b8109f502fec733debbc956861a Mon Sep 17 00:00:00 2001 From: skratchdot Date: Fri, 6 Sep 2024 09:38:36 -0400 Subject: [PATCH 446/730] Update README.md changing `File` -> `LazyFile` --- packages/lazy-file/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/lazy-file/README.md b/packages/lazy-file/README.md index b04189370e4..8cf96e45a43 100644 --- a/packages/lazy-file/README.md +++ b/packages/lazy-file/README.md @@ -25,7 +25,7 @@ A `LazyFile` improves this model by accepting an additional content type in its let lazyContent: LazyContent = { /* See below for usage */ }; -let file = new File(lazyContent, 'hello.txt', { type: 'text/plain' }); +let file = new LazyFile(lazyContent, 'hello.txt', { type: 'text/plain' }); ``` All other `File` functionality works as you'd expect. From 7333facf89d1a32d6c20cdb619ce035c28ed2e55 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 9 Sep 2024 14:23:31 -0700 Subject: [PATCH 447/730] Small refactoring --- .../src/lib/fetch-handler.ts | 41 ++++++++++++++++++ .../src/lib/request-listener.ts | 42 +------------------ .../src/node-fetch-server.ts | 9 +--- 3 files changed, 44 insertions(+), 48 deletions(-) create mode 100644 packages/node-fetch-server/src/lib/fetch-handler.ts diff --git a/packages/node-fetch-server/src/lib/fetch-handler.ts b/packages/node-fetch-server/src/lib/fetch-handler.ts new file mode 100644 index 00000000000..a85fc003d36 --- /dev/null +++ b/packages/node-fetch-server/src/lib/fetch-handler.ts @@ -0,0 +1,41 @@ +export interface ClientAddress { + /** + * The IP address of the client that sent the request. + * + * [Node.js Reference](https://nodejs.org/api/net.html#socketremoteaddress) + */ + address: string; + /** + * The family of the client IP address. + * + * [Node.js Reference](https://nodejs.org/api/net.html#socketremotefamily) + */ + family: 'IPv4' | 'IPv6'; + /** + * The remote port of the client that sent the request. + * + * [Node.js Reference](https://nodejs.org/api/net.html#socketremoteport) + */ + port: number; +} + +/** + * A function that handles an error that occurred during request handling. May return a response to + * send to the client, or `undefined` to allow the server to send a default error response. + * + * [MDN `Response` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Response) + */ +export interface ErrorHandler { + (error: unknown): void | Response | Promise; +} + +/** + * A function that handles an incoming request and returns a response. + * + * [MDN `Request` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Request) + * + * [MDN `Response` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Response) + */ +export interface FetchHandler { + (request: Request, client: ClientAddress): Response | Promise; +} diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index d3cd7cd449a..b02f2bae4c1 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -1,46 +1,6 @@ import * as http from 'node:http'; -export interface ClientAddress { - /** - * The IP address of the client that sent the request. - * - * [Node.js Reference](https://nodejs.org/api/net.html#socketremoteaddress) - */ - address: string; - /** - * The family of the client IP address. - * - * [Node.js Reference](https://nodejs.org/api/net.html#socketremotefamily) - */ - family: 'IPv4' | 'IPv6'; - /** - * The remote port of the client that sent the request. - * - * [Node.js Reference](https://nodejs.org/api/net.html#socketremoteport) - */ - port: number; -} - -/** - * A function that handles an error that occurred during request handling. May return a response to - * send to the client, or `undefined` to allow the server to send a default error response. - * - * [MDN `Response` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Response) - */ -export interface ErrorHandler { - (error: unknown): void | Response | Promise; -} - -/** - * A function that handles an incoming request and returns a response. - * - * [MDN `Request` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Request) - * - * [MDN `Response` Reference](https://developer.mozilla.org/en-US/docs/Web/API/Response) - */ -export interface FetchHandler { - (request: Request, client: ClientAddress): Response | Promise; -} +import { ClientAddress, ErrorHandler, FetchHandler } from './fetch-handler.js'; export interface RequestListenerOptions { /** diff --git a/packages/node-fetch-server/src/node-fetch-server.ts b/packages/node-fetch-server/src/node-fetch-server.ts index 8d2c72acb76..ed50b9ca84a 100644 --- a/packages/node-fetch-server/src/node-fetch-server.ts +++ b/packages/node-fetch-server/src/node-fetch-server.ts @@ -1,7 +1,2 @@ -export { - type ClientAddress, - type ErrorHandler, - type FetchHandler, - type RequestListenerOptions, - createRequestListener, -} from './lib/request-listener.js'; +export { type ClientAddress, type ErrorHandler, type FetchHandler } from './lib/fetch-handler.js'; +export { type RequestListenerOptions, createRequestListener } from './lib/request-listener.js'; From d9a168e8f26924d2aa6cfc25a8f77f8089f8f2a9 Mon Sep 17 00:00:00 2001 From: JamesHenry Date: Tue, 10 Sep 2024 14:43:19 +0400 Subject: [PATCH 448/730] chore: strip scope from package name for nx project name --- .../version-plan-1725146936111.md | 2 +- package.json | 4 +- packages/file-storage/package.json | 5 +- packages/form-data-parser/package.json | 5 +- packages/headers/package.json | 5 +- packages/lazy-file/package.json | 5 +- packages/multipart-parser/package.json | 5 +- packages/node-fetch-server/package.json | 5 +- pnpm-lock.yaml | 170 +++++++++--------- 9 files changed, 112 insertions(+), 94 deletions(-) diff --git a/.nx/version-plans/version-plan-1725146936111.md b/.nx/version-plans/version-plan-1725146936111.md index d23a2149398..a0569dda059 100644 --- a/.nx/version-plans/version-plan-1725146936111.md +++ b/.nx/version-plans/version-plan-1725146936111.md @@ -1,5 +1,5 @@ --- -'@mjackson/node-fetch-server': minor +node-fetch-server: minor --- Initial release diff --git a/package.json b/package.json index 73fa03fe14d..b1eb414f3be 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,11 @@ "packageManager": "pnpm@9.9.0", "type": "module", "devDependencies": { - "@nx/js": "19.6.5", + "@nx/js": "19.7.0", "@swc-node/register": "^1.10.9", "@swc/core": "~1.5.7", "@swc/helpers": "~0.5.11", - "nx": "19.6.5", + "nx": "19.7.0", "prettier": "^3.3.3", "typescript": "^5.5.4" }, diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index 7cab69fdac5..01e835a5ec5 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -38,5 +38,8 @@ "storage", "stream", "fs" - ] + ], + "nx": { + "name": "file-storage" + } } diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index e45df2caa9a..b204b483a62 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -36,5 +36,8 @@ "FormData", "multipart", "parser" - ] + ], + "nx": { + "name": "form-data-parser" + } } diff --git a/packages/headers/package.json b/packages/headers/package.json index f284bba1461..7605e9463a1 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -33,5 +33,8 @@ "http", "header", "headers" - ] + ], + "nx": { + "name": "headers" + } } diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index ad618562b34..a713c318955 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -36,5 +36,8 @@ "file", "buffer", "blob" - ] + ], + "nx": { + "name": "lazy-file" + } } diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index aee877cc784..771d542395c 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -41,5 +41,8 @@ "parser", "stream", "http" - ] + ], + "nx": { + "name": "multipart-parser" + } } diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 39cd4e0757d..3cc3f61c72c 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -36,5 +36,8 @@ "response", "fetch", "web" - ] + ], + "nx": { + "name": "node-fetch-server" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 192d58943d9..665367db6f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: devDependencies: '@nx/js': - specifier: 19.6.5 - version: 19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + specifier: 19.7.0 + version: 19.7.0(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) '@swc-node/register': specifier: ^1.10.9 version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) @@ -21,8 +21,8 @@ importers: specifier: ~0.5.11 version: 0.5.12 nx: - specifier: 19.6.5 - version: 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + specifier: 19.7.0 + version: 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) prettier: specifier: ^3.3.3 version: 3.3.3 @@ -1050,94 +1050,94 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@nrwl/devkit@19.6.5': - resolution: {integrity: sha512-KaQeVyYaWBQwQSITtumPvx+P7IpKFReETx4gLTcOpQ/a3QD/AZFGbNjiG+xDLbgo1FDh9dRt9k7eWhGk6oPWKQ==} + '@nrwl/devkit@19.7.0': + resolution: {integrity: sha512-6c/lapm4o9xQLF1MFeHkbScDIUwgBmPAWHYBtg7qlCba6dv9o4xLj41689hLorq3TyT1d66FTdJ91J+u/s//Ow==} - '@nrwl/js@19.6.5': - resolution: {integrity: sha512-Ybm+wuCjaujvq8QIJgDM45yqpx675tqGEHnCuyaCwETF+OhgufEIGMwV/ASk+Bcle3btPY7iKUp3YuCjTexnEw==} + '@nrwl/js@19.7.0': + resolution: {integrity: sha512-RwetapXpRYsI3dwbXSVeahmf7ZLf2Tq9pH/91c9E0zAgvC1EwBCEpc7IC7N1HJejEQt9nA3ZcWxhAM+wo4EDuA==} - '@nrwl/tao@19.6.5': - resolution: {integrity: sha512-EoUN/kE6CMWJ4ZZgcXAyiOzn8BSshG2DhC5PNwzLTAxRBus8FgXR/9c0XOzchaP46Kq3hoBGFgeyW434tfuv5w==} + '@nrwl/tao@19.7.0': + resolution: {integrity: sha512-Y7LwFAq6U38U486eL9L1G6D32Z2e+f6bJRqhbAqX7j4eAHPv0ALpQuum5uGms2yywL25qwXZPKWtAHi6nbC6Ag==} hasBin: true - '@nrwl/workspace@19.6.5': - resolution: {integrity: sha512-4oufH1plJjUy8g9kG7yRL/gQgoEUFc8Lmk1ibwUj2FrnkXJ0oE7DDtE5N9f/wCUg+uGSIgmrYyG4DGM9xGGQzg==} + '@nrwl/workspace@19.7.0': + resolution: {integrity: sha512-z0vqA+a9iuAmkvSa4Bw4Ushvy8zAyOqKwQnfYDT6ue4LCTo4c1ll+q2RPgKj1kbFt5iJ1lsnDxXj+6xnmCwozQ==} - '@nx/devkit@19.6.5': - resolution: {integrity: sha512-AEaMSr55Ar48QHU8TBi/gzLtjeT100zdyfLmk0RoiLzjjC8pWmm3Xfvqxyt1WsUUf4oQhlHlolJuoM41qKsdZw==} + '@nx/devkit@19.7.0': + resolution: {integrity: sha512-/COQC55ADJ1y3bJJrgacswrZ/EmuMGpPbnz8T9oilmqNXZWLli0ViKs+J4QMCXTDPV1kpJNkJqyzV8TR/AfCsw==} peerDependencies: nx: '>= 17 <= 20' - '@nx/js@19.6.5': - resolution: {integrity: sha512-nKK3fAJnFZZZF3hWRec64k+3JqcD0c9uZWXsXXEwZXmfB3TitPy+zczM2SSVvC50+AoIXGCCiFBUYesdxeReoQ==} + '@nx/js@19.7.0': + resolution: {integrity: sha512-DDRcg6cxJF3amVzRMEtoGqcpeZyXi6rX/ASyADJPgoDdSx1k97dyjzfEEoELMP0YRxRWSPZfzD2y0q0BolQvjA==} peerDependencies: verdaccio: ^5.0.4 peerDependenciesMeta: verdaccio: optional: true - '@nx/nx-darwin-arm64@19.6.5': - resolution: {integrity: sha512-sFU2k0BaklM17206F2E5C3866y0SICb0xyuPeD6D07a6hB4IstjIUkldUJJN70wEsJ5I3VP4yZ2oJcwnb1TTRQ==} + '@nx/nx-darwin-arm64@19.7.0': + resolution: {integrity: sha512-xlgTO3QZVM+DnKM5j3vZrXqKqFkf9XPDLnh+LtMx6GKjkVdnz2TCDo/wwwBB2IjBE+nSK3Fvl15CmWLnI2GGWg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@nx/nx-darwin-x64@19.6.5': - resolution: {integrity: sha512-EJmTbUPmlksgOap6xkQl89+zXwHpaAnZLsyLHUd7i00eVRa21FRhdKFnVsRxtwPDZp/YCG84IzMUye/IrwDFTQ==} + '@nx/nx-darwin-x64@19.7.0': + resolution: {integrity: sha512-tDT5Dk65+F+KWIybhT1IU5i+uBdlS3pa3SPvPIEvW0sJ+vgugCxDN7iKlrJgYdxYFDx9g+WHRRguLe9gKpVA2Q==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@nx/nx-freebsd-x64@19.6.5': - resolution: {integrity: sha512-rR8NJCskoEmIbK96uxaevHm146WDTA0V3jId+X1joITqjj3E2DMm0U4r5v/OgI5+iqbhFV4S83LrMxP6gBLTsQ==} + '@nx/nx-freebsd-x64@19.7.0': + resolution: {integrity: sha512-7dg7zMQ56F53Fw107dMmNcnD5SPW+gd2aJAkE9hrG0byz9oC5TpXNDpL0/eUSrrAESqF7xYclpfCzLzkMN2Iaw==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@nx/nx-linux-arm-gnueabihf@19.6.5': - resolution: {integrity: sha512-OUHFV6iLlJN7b7qFnqLfa0Yj/aoylEiRXcEhV1bhPm0Ryt1bOeGDmLYScVN8n5t+AVmrwwYHk+ajXMzCOLLeZw==} + '@nx/nx-linux-arm-gnueabihf@19.7.0': + resolution: {integrity: sha512-Qc315NapRWvlasVWsncV1v4f6hL+QLHxM/8WPMbkvKNCdOjiaFgNFfjrFMbzevGqAIx3X5X5T6XKXHRblDPwXw==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@nx/nx-linux-arm64-gnu@19.6.5': - resolution: {integrity: sha512-CzbJfb24poaJgBHt4aKLaL8a7bO9KXCLls+TX0SZfmzA9AWX6YuiX9lhxwBv6cqsViXTDB4KnXndMDB/H0Gk4g==} + '@nx/nx-linux-arm64-gnu@19.7.0': + resolution: {integrity: sha512-nyxVymloy6DrSAIJDVBf3PkOoz4lXzZxj1AHgj4zdETllY/T2WXODzzy4PyN0sqF5ljX68FODVXbxpkIcS0EQQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@nx/nx-linux-arm64-musl@19.6.5': - resolution: {integrity: sha512-MgidKilQ0KWxQbTnaqXGjASu7wtAC9q6zAwFNKFENkwJq3nThaQH6jQVlnINE4lL9NSgyyg0AS/ix31hiqAgvA==} + '@nx/nx-linux-arm64-musl@19.7.0': + resolution: {integrity: sha512-BN/mwZGaVgcHJhuGbu1W6EcFPbtDc8pY0cTIYkqKLzHlFfWLdRvLLJVeUGmc9ubvU3lqQLWX/lRi6Nd8RZINjg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@nx/nx-linux-x64-gnu@19.6.5': - resolution: {integrity: sha512-rGDylAoslIlk5TDbEJ6YoQOYxxYP9gCpi6FLke2mFgXVzOmVlLKHfVsegIHYVMYYF26h3NJh0NLGGzGdoBjWgQ==} + '@nx/nx-linux-x64-gnu@19.7.0': + resolution: {integrity: sha512-ATcIPJdLQRYIMmbMQzbZzYVEo/unmSVq+9+/fah3okv+/5je+/tJcnf777WS4qP6ysBv2InE+wk2F/g6TNpJvg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@nx/nx-linux-x64-musl@19.6.5': - resolution: {integrity: sha512-C/pNjDL/bDEcrDypgBo4r1AOiPTk8gWJwBsFE1QHIvg7//5WFSreqRj34rJu/GZ95eLYJH5tje1VW6z+atEGkQ==} + '@nx/nx-linux-x64-musl@19.7.0': + resolution: {integrity: sha512-IwP5Are8N2nBWnPygA0AS8xRl7+Wn3oTBkIPESjWs5WzfyMGTlVL/R2/8GB1hc8fdr2dd+3R7LuMZpZ/d1G7xg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@nx/nx-win32-arm64-msvc@19.6.5': - resolution: {integrity: sha512-mMi8i16OFux17xed2iLPWwUdCbS1mYA9Ny/gnoNUCosmihmXX9wrzaGBkNAMsHA28huYQtPhGormsEs+zuiVFg==} + '@nx/nx-win32-arm64-msvc@19.7.0': + resolution: {integrity: sha512-+8EfLC760GzaZ4wvcWdYnoO1kw4xOrVnBTuijgkZeTPvBPPrKOi7y2bv9tG2LklE5GTt8mkmxCSEkQfSxsGIhw==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@nx/nx-win32-x64-msvc@19.6.5': - resolution: {integrity: sha512-jjhbDYNBkyz9Fg1jf0KZTrgdf/yx4v+k0ifukDIHZjva+jko0Ve5WzdkQ2K07M9ZxxYibDtTDqX9uX6+eFZtoA==} + '@nx/nx-win32-x64-msvc@19.7.0': + resolution: {integrity: sha512-h6d3zBSjhJlGxjBXKGgLqrgxMrkobdyU5KO0zjrQ3+PWrdrtw4jrIhKxW3KoFOzjbDPMmwNH/Bd7aYwZ/RMlEw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@nx/workspace@19.6.5': - resolution: {integrity: sha512-1r5Vgk1Y5+y1K20O9d59ALjlyLYOU4XcybIiN4Wonw+oYrg6ZXSeA3R+lLSuTA4dHtfxcNsCIigzcSEUwchNwg==} + '@nx/workspace@19.7.0': + resolution: {integrity: sha512-ZN6SL+ImNlr2b5ibpbAGfm+yiDmm2Q/mgNuX58YnwKq4u8xr9AWERzGmzkb1dwFB8EXMhjNdYwVWBWl1nC7+Hw==} '@oxc-resolver/binding-darwin-arm64@1.11.0': resolution: {integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==} @@ -2021,8 +2021,8 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lines-and-columns@2.0.4: - resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} + lines-and-columns@2.0.3: + resolution: {integrity: sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} lodash.debounce@4.0.8: @@ -2158,8 +2158,8 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} - nx@19.6.5: - resolution: {integrity: sha512-igPYPsBF1BM1YxEiGDvaLOz0CWWoEvxzR7yQg3iULjGG9zKgDFNHHIHJwkyHsCBTtMhhkgeUl16PsTVgDuil3A==} + nx@19.7.0: + resolution: {integrity: sha512-SZOnoCqPl8yJyPWt721INotFcgRlmBmGKUvXJ+wwnLidNKoUbX1RICIAceWkpZwaVZ2c/fqKYqjXLtGEblyZng==} hasBin: true peerDependencies: '@swc-node/register': ^1.8.0 @@ -3637,15 +3637,15 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 - '@nrwl/devkit@19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': + '@nrwl/devkit@19.7.0(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': dependencies: - '@nx/devkit': 19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nx/devkit': 19.7.0(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) transitivePeerDependencies: - nx - '@nrwl/js@19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': + '@nrwl/js@19.7.0(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': dependencies: - '@nx/js': 19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + '@nx/js': 19.7.0(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -3658,37 +3658,37 @@ snapshots: - typescript - verdaccio - '@nrwl/tao@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nrwl/tao@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - nx: 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) tslib: 2.7.0 transitivePeerDependencies: - '@swc-node/register' - '@swc/core' - debug - '@nrwl/workspace@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nrwl/workspace@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - '@nx/workspace': 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nx/workspace': 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) transitivePeerDependencies: - '@swc-node/register' - '@swc/core' - debug - '@nx/devkit@19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': + '@nx/devkit@19.7.0(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': dependencies: - '@nrwl/devkit': 19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nrwl/devkit': 19.7.0(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) ejs: 3.1.10 enquirer: 2.3.6 ignore: 5.3.2 minimatch: 9.0.3 - nx: 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) semver: 7.6.3 tmp: 0.2.3 tslib: 2.7.0 yargs-parser: 21.1.1 - '@nx/js@19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': + '@nx/js@19.7.0(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': dependencies: '@babel/core': 7.25.2 '@babel/plugin-proposal-decorators': 7.24.7(@babel/core@7.25.2) @@ -3697,9 +3697,9 @@ snapshots: '@babel/preset-env': 7.25.4(@babel/core@7.25.2) '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) '@babel/runtime': 7.25.4 - '@nrwl/js': 19.6.5(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) - '@nx/devkit': 19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) - '@nx/workspace': 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nrwl/js': 19.7.0(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + '@nx/devkit': 19.7.0(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nx/workspace': 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) babel-plugin-const-enum: 1.2.0(@babel/core@7.25.2) babel-plugin-macros: 2.8.0 babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.25.2)(@babel/traverse@7.25.4) @@ -3731,43 +3731,43 @@ snapshots: - supports-color - typescript - '@nx/nx-darwin-arm64@19.6.5': + '@nx/nx-darwin-arm64@19.7.0': optional: true - '@nx/nx-darwin-x64@19.6.5': + '@nx/nx-darwin-x64@19.7.0': optional: true - '@nx/nx-freebsd-x64@19.6.5': + '@nx/nx-freebsd-x64@19.7.0': optional: true - '@nx/nx-linux-arm-gnueabihf@19.6.5': + '@nx/nx-linux-arm-gnueabihf@19.7.0': optional: true - '@nx/nx-linux-arm64-gnu@19.6.5': + '@nx/nx-linux-arm64-gnu@19.7.0': optional: true - '@nx/nx-linux-arm64-musl@19.6.5': + '@nx/nx-linux-arm64-musl@19.7.0': optional: true - '@nx/nx-linux-x64-gnu@19.6.5': + '@nx/nx-linux-x64-gnu@19.7.0': optional: true - '@nx/nx-linux-x64-musl@19.6.5': + '@nx/nx-linux-x64-musl@19.7.0': optional: true - '@nx/nx-win32-arm64-msvc@19.6.5': + '@nx/nx-win32-arm64-msvc@19.7.0': optional: true - '@nx/nx-win32-x64-msvc@19.6.5': + '@nx/nx-win32-x64-msvc@19.7.0': optional: true - '@nx/workspace@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nx/workspace@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - '@nrwl/workspace': 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) - '@nx/devkit': 19.6.5(nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nrwl/workspace': 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nx/devkit': 19.7.0(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) chalk: 4.1.2 enquirer: 2.3.6 - nx: 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) tslib: 2.7.0 yargs-parser: 21.1.1 transitivePeerDependencies: @@ -4649,7 +4649,7 @@ snapshots: lines-and-columns@1.2.4: {} - lines-and-columns@2.0.4: {} + lines-and-columns@2.0.3: {} lodash.debounce@4.0.8: {} @@ -4765,10 +4765,10 @@ snapshots: dependencies: path-key: 3.1.1 - nx@19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)): + nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)): dependencies: '@napi-rs/wasm-runtime': 0.2.4 - '@nrwl/tao': 19.6.5(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nrwl/tao': 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.0-rc.46 '@zkochan/js-yaml': 0.0.7 @@ -4787,7 +4787,7 @@ snapshots: ignore: 5.3.2 jest-diff: 29.7.0 jsonc-parser: 3.2.0 - lines-and-columns: 2.0.4 + lines-and-columns: 2.0.3 minimatch: 9.0.3 node-machine-id: 1.1.12 npm-run-path: 4.0.1 @@ -4803,16 +4803,16 @@ snapshots: yargs: 17.7.2 yargs-parser: 21.1.1 optionalDependencies: - '@nx/nx-darwin-arm64': 19.6.5 - '@nx/nx-darwin-x64': 19.6.5 - '@nx/nx-freebsd-x64': 19.6.5 - '@nx/nx-linux-arm-gnueabihf': 19.6.5 - '@nx/nx-linux-arm64-gnu': 19.6.5 - '@nx/nx-linux-arm64-musl': 19.6.5 - '@nx/nx-linux-x64-gnu': 19.6.5 - '@nx/nx-linux-x64-musl': 19.6.5 - '@nx/nx-win32-arm64-msvc': 19.6.5 - '@nx/nx-win32-x64-msvc': 19.6.5 + '@nx/nx-darwin-arm64': 19.7.0 + '@nx/nx-darwin-x64': 19.7.0 + '@nx/nx-freebsd-x64': 19.7.0 + '@nx/nx-linux-arm-gnueabihf': 19.7.0 + '@nx/nx-linux-arm64-gnu': 19.7.0 + '@nx/nx-linux-arm64-musl': 19.7.0 + '@nx/nx-linux-x64-gnu': 19.7.0 + '@nx/nx-linux-x64-musl': 19.7.0 + '@nx/nx-win32-arm64-msvc': 19.7.0 + '@nx/nx-win32-x64-msvc': 19.7.0 '@swc-node/register': 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) '@swc/core': 1.5.29(@swc/helpers@0.5.12) transitivePeerDependencies: From 32356b97206223f8ae81f4dc1c00a7b4bc8a6676 Mon Sep 17 00:00:00 2001 From: JamesHenry Date: Tue, 10 Sep 2024 22:38:34 +0400 Subject: [PATCH 449/730] chore: use workspace protocol between local dependencies --- nx.json | 3 +- package.json | 4 +- packages/file-storage/package.json | 2 +- packages/form-data-parser/package.json | 2 +- packages/multipart-parser/package.json | 2 +- pnpm-lock.yaml | 193 +++++++++++-------------- 6 files changed, 94 insertions(+), 112 deletions(-) diff --git a/nx.json b/nx.json index 0e73362afd4..fe9ec4b6696 100644 --- a/nx.json +++ b/nx.json @@ -16,7 +16,8 @@ "versionPlans": true, "version": { "generatorOptions": { - "updateDependents": "auto" + "updateDependents": "auto", + "preserveLocalDependencyProtocols": true } }, "changelog": { diff --git a/package.json b/package.json index b1eb414f3be..ddf825fb6db 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,11 @@ "packageManager": "pnpm@9.9.0", "type": "module", "devDependencies": { - "@nx/js": "19.7.0", + "@nx/js": "19.7.2", "@swc-node/register": "^1.10.9", "@swc/core": "~1.5.7", "@swc/helpers": "~0.5.11", - "nx": "19.7.0", + "nx": "19.7.2", "prettier": "^3.3.3", "typescript": "^5.5.4" }, diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index 01e835a5ec5..58ab7b68868 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -23,7 +23,7 @@ "./package.json": "./package.json" }, "dependencies": { - "@mjackson/lazy-file": "^3.1.0" + "@mjackson/lazy-file": "workspace:^" }, "devDependencies": { "@types/node": "^20.14.10" diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index b204b483a62..bf4a63a32ea 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -21,7 +21,7 @@ "./package.json": "./package.json" }, "dependencies": { - "@mjackson/multipart-parser": "^0.6.1" + "@mjackson/multipart-parser": "workspace:^" }, "devDependencies": { "@types/node": "^22.4.1" diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 771d542395c..bfbcf6047c5 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -22,7 +22,7 @@ "./package.json": "./package.json" }, "dependencies": { - "@mjackson/headers": "^0.5.0" + "@mjackson/headers": "workspace:^" }, "devDependencies": { "@types/node": "^20.14.10" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 665367db6f6..41eeabc008d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: devDependencies: '@nx/js': - specifier: 19.7.0 - version: 19.7.0(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + specifier: 19.7.2 + version: 19.7.2(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) '@swc-node/register': specifier: ^1.10.9 version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) @@ -21,8 +21,8 @@ importers: specifier: ~0.5.11 version: 0.5.12 nx: - specifier: 19.7.0 - version: 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + specifier: 19.7.2 + version: 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) prettier: specifier: ^3.3.3 version: 3.3.3 @@ -33,8 +33,8 @@ importers: packages/file-storage: dependencies: '@mjackson/lazy-file': - specifier: ^3.1.0 - version: 3.1.0 + specifier: workspace:^ + version: link:../lazy-file devDependencies: '@types/node': specifier: ^20.14.10 @@ -43,8 +43,8 @@ importers: packages/form-data-parser: dependencies: '@mjackson/multipart-parser': - specifier: ^0.6.1 - version: 0.6.2 + specifier: workspace:^ + version: link:../multipart-parser devDependencies: '@types/node': specifier: ^22.4.1 @@ -69,8 +69,8 @@ importers: packages/multipart-parser: dependencies: '@mjackson/headers': - specifier: ^0.5.0 - version: 0.5.1 + specifier: workspace:^ + version: link:../headers devDependencies: '@types/node': specifier: ^20.14.10 @@ -1026,15 +1026,6 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@mjackson/headers@0.5.1': - resolution: {integrity: sha512-sJpFgecPT/zJvwk3GRNVWNs8EkwaJoUNU2D0VMlp+gDJs6cuSTm1q/aCZi3ZtuV6CgDEQ4l2ZjUG3A9JrQlbNA==} - - '@mjackson/lazy-file@3.1.0': - resolution: {integrity: sha512-YdlmPLtRjQotP/It1hxVsz6tBJh63e/xD40s6eBLfgFr8tQ5zE+gJtpz+t/4vbTXv4axRulDfXG2XJtVpXmkUw==} - - '@mjackson/multipart-parser@0.6.2': - resolution: {integrity: sha512-xG3mINK6gFVposxu83x3n4ueJfjWoxOl3UaBADXNjh/NL84L+Zc/kmz2mTQA9GHvHFPAMlXqPSLTocIDkmhemQ==} - '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} @@ -1050,94 +1041,94 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@nrwl/devkit@19.7.0': - resolution: {integrity: sha512-6c/lapm4o9xQLF1MFeHkbScDIUwgBmPAWHYBtg7qlCba6dv9o4xLj41689hLorq3TyT1d66FTdJ91J+u/s//Ow==} + '@nrwl/devkit@19.7.2': + resolution: {integrity: sha512-cn1eTxSVh7RQeEsPLe++vIBKXKaeFvsqJFUgyYH2u9LH1ib6gTex6Ywa2QPHoVU9fvTTwOv7ZsZk4+usfwmsMg==} - '@nrwl/js@19.7.0': - resolution: {integrity: sha512-RwetapXpRYsI3dwbXSVeahmf7ZLf2Tq9pH/91c9E0zAgvC1EwBCEpc7IC7N1HJejEQt9nA3ZcWxhAM+wo4EDuA==} + '@nrwl/js@19.7.2': + resolution: {integrity: sha512-Md2EWHbLrVhsB3KeI+EzgQPMCPwcGGAFZ17f9WnxzMHi5Wr219f7a72vD+6qIc3gwd+2EDMdvSHm10+oup+Rzg==} - '@nrwl/tao@19.7.0': - resolution: {integrity: sha512-Y7LwFAq6U38U486eL9L1G6D32Z2e+f6bJRqhbAqX7j4eAHPv0ALpQuum5uGms2yywL25qwXZPKWtAHi6nbC6Ag==} + '@nrwl/tao@19.7.2': + resolution: {integrity: sha512-sGaJWgR2F9i64BAULzCG3D5Kmf96wg3hyEAICpZe0VNnJV/DuXoNKFW+uhy7/l4Z6thgBV3dvoPhN5YTN47ggA==} hasBin: true - '@nrwl/workspace@19.7.0': - resolution: {integrity: sha512-z0vqA+a9iuAmkvSa4Bw4Ushvy8zAyOqKwQnfYDT6ue4LCTo4c1ll+q2RPgKj1kbFt5iJ1lsnDxXj+6xnmCwozQ==} + '@nrwl/workspace@19.7.2': + resolution: {integrity: sha512-a6DojKBDdbAe85gV0Rxo92P8yhuXK1C2jWCIAZEaa6Am5gpfyezxIIKPcvKqucgtDg1aaU6zyP03GcMS9J6HuQ==} - '@nx/devkit@19.7.0': - resolution: {integrity: sha512-/COQC55ADJ1y3bJJrgacswrZ/EmuMGpPbnz8T9oilmqNXZWLli0ViKs+J4QMCXTDPV1kpJNkJqyzV8TR/AfCsw==} + '@nx/devkit@19.7.2': + resolution: {integrity: sha512-WYffA5fXhXguy2/QphPCi8aZy39c14R2N1MkuNkOSVznZTgWbuHGiaP4BwD+/XAfbZhqnrEJvMHpmYcSm90DkQ==} peerDependencies: nx: '>= 17 <= 20' - '@nx/js@19.7.0': - resolution: {integrity: sha512-DDRcg6cxJF3amVzRMEtoGqcpeZyXi6rX/ASyADJPgoDdSx1k97dyjzfEEoELMP0YRxRWSPZfzD2y0q0BolQvjA==} + '@nx/js@19.7.2': + resolution: {integrity: sha512-lpMJVHerDdTPkfDnK/6wPnV6yoYq8x4/1nqfyH4OuX5V/oQIe2fKaqEGurvFvcn0f3zNopuyr6E1+w1rmYpODA==} peerDependencies: verdaccio: ^5.0.4 peerDependenciesMeta: verdaccio: optional: true - '@nx/nx-darwin-arm64@19.7.0': - resolution: {integrity: sha512-xlgTO3QZVM+DnKM5j3vZrXqKqFkf9XPDLnh+LtMx6GKjkVdnz2TCDo/wwwBB2IjBE+nSK3Fvl15CmWLnI2GGWg==} + '@nx/nx-darwin-arm64@19.7.2': + resolution: {integrity: sha512-pKLhQSdbg9oIovQrzpJqzQk8vS2V1t8vPniRLpH3YGziAlo+wTESDkgE2ZNmv/NqLti45fjZZ6I/7r2jdF6z4A==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@nx/nx-darwin-x64@19.7.0': - resolution: {integrity: sha512-tDT5Dk65+F+KWIybhT1IU5i+uBdlS3pa3SPvPIEvW0sJ+vgugCxDN7iKlrJgYdxYFDx9g+WHRRguLe9gKpVA2Q==} + '@nx/nx-darwin-x64@19.7.2': + resolution: {integrity: sha512-PdQFp4Zo+Ero5tTh8d+mae0Fo64vWLLBcTh4zPmskjaU5PiY6/4xOzdaAjtbHiak7h1mCGB/31/efFzKf5EvKA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@nx/nx-freebsd-x64@19.7.0': - resolution: {integrity: sha512-7dg7zMQ56F53Fw107dMmNcnD5SPW+gd2aJAkE9hrG0byz9oC5TpXNDpL0/eUSrrAESqF7xYclpfCzLzkMN2Iaw==} + '@nx/nx-freebsd-x64@19.7.2': + resolution: {integrity: sha512-ORedNKXCbH4DQ4lX+YoHsHwGNGWxeU/8OpiWRcZzpF5vYVoTR3m93szemdJ3U5V6IXFI7r6/qz/FRltnx+VT8g==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@nx/nx-linux-arm-gnueabihf@19.7.0': - resolution: {integrity: sha512-Qc315NapRWvlasVWsncV1v4f6hL+QLHxM/8WPMbkvKNCdOjiaFgNFfjrFMbzevGqAIx3X5X5T6XKXHRblDPwXw==} + '@nx/nx-linux-arm-gnueabihf@19.7.2': + resolution: {integrity: sha512-KxCfE9qFwmtTBqcYGKs3uYkxsuAhItf1xyMK07uhdY6igI1cuhVBYNLtVd0t25lb4SU4RFtwQu69A328FVc11w==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@nx/nx-linux-arm64-gnu@19.7.0': - resolution: {integrity: sha512-nyxVymloy6DrSAIJDVBf3PkOoz4lXzZxj1AHgj4zdETllY/T2WXODzzy4PyN0sqF5ljX68FODVXbxpkIcS0EQQ==} + '@nx/nx-linux-arm64-gnu@19.7.2': + resolution: {integrity: sha512-ljiDNBPwL+aGnqZw9fAygNj4c2FRUDqGypli0gjWNZjri+JJqqtPwdYLYsUVBCs8chcgwvsHYP0AVKZaPf2K1A==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@nx/nx-linux-arm64-musl@19.7.0': - resolution: {integrity: sha512-BN/mwZGaVgcHJhuGbu1W6EcFPbtDc8pY0cTIYkqKLzHlFfWLdRvLLJVeUGmc9ubvU3lqQLWX/lRi6Nd8RZINjg==} + '@nx/nx-linux-arm64-musl@19.7.2': + resolution: {integrity: sha512-G9IBIfCFknbVd+ZNn22BC80pu6JgToslEZyl2qRKRgq6D4Xsfm8zwKlKJNQDWY3I//f26u+wiA83yEFOaQcqyQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@nx/nx-linux-x64-gnu@19.7.0': - resolution: {integrity: sha512-ATcIPJdLQRYIMmbMQzbZzYVEo/unmSVq+9+/fah3okv+/5je+/tJcnf777WS4qP6ysBv2InE+wk2F/g6TNpJvg==} + '@nx/nx-linux-x64-gnu@19.7.2': + resolution: {integrity: sha512-P5HQhLoxLodpbhF5Col+ygScXfcVnk0gqXPxbc7kOnhdCwwIISZxHPsrgm0jbWaB5TufBuZNlo+ST8Evtnzojg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@nx/nx-linux-x64-musl@19.7.0': - resolution: {integrity: sha512-IwP5Are8N2nBWnPygA0AS8xRl7+Wn3oTBkIPESjWs5WzfyMGTlVL/R2/8GB1hc8fdr2dd+3R7LuMZpZ/d1G7xg==} + '@nx/nx-linux-x64-musl@19.7.2': + resolution: {integrity: sha512-b08iqgz4Z2jKRJ66rf7ci/n0LFZ3CnaxdpXnOpb1FM/ZBLn3BuNah36K03UWamBlkrVEmAORZtPKZ5OuQHnlMg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@nx/nx-win32-arm64-msvc@19.7.0': - resolution: {integrity: sha512-+8EfLC760GzaZ4wvcWdYnoO1kw4xOrVnBTuijgkZeTPvBPPrKOi7y2bv9tG2LklE5GTt8mkmxCSEkQfSxsGIhw==} + '@nx/nx-win32-arm64-msvc@19.7.2': + resolution: {integrity: sha512-hn8Qm/iGiOpyP/34M/aKFYDStLzudX1dYPC62RnXU0/WI29JTdnT420rYjwXkQTaPMZsvi5xkQmBphowfGlHww==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@nx/nx-win32-x64-msvc@19.7.0': - resolution: {integrity: sha512-h6d3zBSjhJlGxjBXKGgLqrgxMrkobdyU5KO0zjrQ3+PWrdrtw4jrIhKxW3KoFOzjbDPMmwNH/Bd7aYwZ/RMlEw==} + '@nx/nx-win32-x64-msvc@19.7.2': + resolution: {integrity: sha512-gK5XnkeiVbjs9+dkukGmZedXrxSL845t/ntlA8wp4joOnb7xUED/xvwhIP7DRjL6VefFbFIzhxgPaSaKfzaiiA==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@nx/workspace@19.7.0': - resolution: {integrity: sha512-ZN6SL+ImNlr2b5ibpbAGfm+yiDmm2Q/mgNuX58YnwKq4u8xr9AWERzGmzkb1dwFB8EXMhjNdYwVWBWl1nC7+Hw==} + '@nx/workspace@19.7.2': + resolution: {integrity: sha512-Nj7OSY0jBtz5S2U5SC9HoUlaRyzUseQNwfVTvLb9yTByhcR/XkJZW+iWXYcG4VHF7fRhJjH1IdX8HaXkbN74KA==} '@oxc-resolver/binding-darwin-arm64@1.11.0': resolution: {integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==} @@ -2158,8 +2149,8 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} - nx@19.7.0: - resolution: {integrity: sha512-SZOnoCqPl8yJyPWt721INotFcgRlmBmGKUvXJ+wwnLidNKoUbX1RICIAceWkpZwaVZ2c/fqKYqjXLtGEblyZng==} + nx@19.7.2: + resolution: {integrity: sha512-mHwRk6UdTkGrLwyYq4Via30kiG2he3d3z1ny0DFlkTQVHZPKpNOf0iROfyZOe31mcjSaTt/eHo7LgEQf1GaXvQ==} hasBin: true peerDependencies: '@swc-node/register': ^1.8.0 @@ -3609,16 +3600,6 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@mjackson/headers@0.5.1': {} - - '@mjackson/lazy-file@3.1.0': - dependencies: - mrmime: 2.0.0 - - '@mjackson/multipart-parser@0.6.2': - dependencies: - '@mjackson/headers': 0.5.1 - '@napi-rs/wasm-runtime@0.2.4': dependencies: '@emnapi/core': 1.2.0 @@ -3637,15 +3618,15 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 - '@nrwl/devkit@19.7.0(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': + '@nrwl/devkit@19.7.2(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': dependencies: - '@nx/devkit': 19.7.0(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nx/devkit': 19.7.2(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) transitivePeerDependencies: - nx - '@nrwl/js@19.7.0(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': + '@nrwl/js@19.7.2(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': dependencies: - '@nx/js': 19.7.0(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + '@nx/js': 19.7.2(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -3658,37 +3639,37 @@ snapshots: - typescript - verdaccio - '@nrwl/tao@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nrwl/tao@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - nx: 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) tslib: 2.7.0 transitivePeerDependencies: - '@swc-node/register' - '@swc/core' - debug - '@nrwl/workspace@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nrwl/workspace@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - '@nx/workspace': 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nx/workspace': 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) transitivePeerDependencies: - '@swc-node/register' - '@swc/core' - debug - '@nx/devkit@19.7.0(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': + '@nx/devkit@19.7.2(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': dependencies: - '@nrwl/devkit': 19.7.0(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nrwl/devkit': 19.7.2(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) ejs: 3.1.10 enquirer: 2.3.6 ignore: 5.3.2 minimatch: 9.0.3 - nx: 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) semver: 7.6.3 tmp: 0.2.3 tslib: 2.7.0 yargs-parser: 21.1.1 - '@nx/js@19.7.0(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': + '@nx/js@19.7.2(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': dependencies: '@babel/core': 7.25.2 '@babel/plugin-proposal-decorators': 7.24.7(@babel/core@7.25.2) @@ -3697,9 +3678,9 @@ snapshots: '@babel/preset-env': 7.25.4(@babel/core@7.25.2) '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) '@babel/runtime': 7.25.4 - '@nrwl/js': 19.7.0(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) - '@nx/devkit': 19.7.0(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) - '@nx/workspace': 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nrwl/js': 19.7.2(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) + '@nx/devkit': 19.7.2(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nx/workspace': 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) babel-plugin-const-enum: 1.2.0(@babel/core@7.25.2) babel-plugin-macros: 2.8.0 babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.25.2)(@babel/traverse@7.25.4) @@ -3731,43 +3712,43 @@ snapshots: - supports-color - typescript - '@nx/nx-darwin-arm64@19.7.0': + '@nx/nx-darwin-arm64@19.7.2': optional: true - '@nx/nx-darwin-x64@19.7.0': + '@nx/nx-darwin-x64@19.7.2': optional: true - '@nx/nx-freebsd-x64@19.7.0': + '@nx/nx-freebsd-x64@19.7.2': optional: true - '@nx/nx-linux-arm-gnueabihf@19.7.0': + '@nx/nx-linux-arm-gnueabihf@19.7.2': optional: true - '@nx/nx-linux-arm64-gnu@19.7.0': + '@nx/nx-linux-arm64-gnu@19.7.2': optional: true - '@nx/nx-linux-arm64-musl@19.7.0': + '@nx/nx-linux-arm64-musl@19.7.2': optional: true - '@nx/nx-linux-x64-gnu@19.7.0': + '@nx/nx-linux-x64-gnu@19.7.2': optional: true - '@nx/nx-linux-x64-musl@19.7.0': + '@nx/nx-linux-x64-musl@19.7.2': optional: true - '@nx/nx-win32-arm64-msvc@19.7.0': + '@nx/nx-win32-arm64-msvc@19.7.2': optional: true - '@nx/nx-win32-x64-msvc@19.7.0': + '@nx/nx-win32-x64-msvc@19.7.2': optional: true - '@nx/workspace@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': + '@nx/workspace@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': dependencies: - '@nrwl/workspace': 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) - '@nx/devkit': 19.7.0(nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) + '@nrwl/workspace': 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nx/devkit': 19.7.2(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) chalk: 4.1.2 enquirer: 2.3.6 - nx: 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + nx: 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) tslib: 2.7.0 yargs-parser: 21.1.1 transitivePeerDependencies: @@ -4765,10 +4746,10 @@ snapshots: dependencies: path-key: 3.1.1 - nx@19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)): + nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)): dependencies: '@napi-rs/wasm-runtime': 0.2.4 - '@nrwl/tao': 19.7.0(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) + '@nrwl/tao': 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.0-rc.46 '@zkochan/js-yaml': 0.0.7 @@ -4803,16 +4784,16 @@ snapshots: yargs: 17.7.2 yargs-parser: 21.1.1 optionalDependencies: - '@nx/nx-darwin-arm64': 19.7.0 - '@nx/nx-darwin-x64': 19.7.0 - '@nx/nx-freebsd-x64': 19.7.0 - '@nx/nx-linux-arm-gnueabihf': 19.7.0 - '@nx/nx-linux-arm64-gnu': 19.7.0 - '@nx/nx-linux-arm64-musl': 19.7.0 - '@nx/nx-linux-x64-gnu': 19.7.0 - '@nx/nx-linux-x64-musl': 19.7.0 - '@nx/nx-win32-arm64-msvc': 19.7.0 - '@nx/nx-win32-x64-msvc': 19.7.0 + '@nx/nx-darwin-arm64': 19.7.2 + '@nx/nx-darwin-x64': 19.7.2 + '@nx/nx-freebsd-x64': 19.7.2 + '@nx/nx-linux-arm-gnueabihf': 19.7.2 + '@nx/nx-linux-arm64-gnu': 19.7.2 + '@nx/nx-linux-arm64-musl': 19.7.2 + '@nx/nx-linux-x64-gnu': 19.7.2 + '@nx/nx-linux-x64-musl': 19.7.2 + '@nx/nx-win32-arm64-msvc': 19.7.2 + '@nx/nx-win32-x64-msvc': 19.7.2 '@swc-node/register': 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) '@swc/core': 1.5.29(@swc/helpers@0.5.12) transitivePeerDependencies: From 49e984a5a9e7bf96cbbc3da802372e019894101f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 10 Sep 2024 14:49:17 -0700 Subject: [PATCH 450/730] Remove outdated version plan file --- .nx/version-plans/version-plan-1725146936111.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .nx/version-plans/version-plan-1725146936111.md diff --git a/.nx/version-plans/version-plan-1725146936111.md b/.nx/version-plans/version-plan-1725146936111.md deleted file mode 100644 index a0569dda059..00000000000 --- a/.nx/version-plans/version-plan-1725146936111.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -node-fetch-server: minor ---- - -Initial release From ffe52efa5c475bb2afb84b5c49c6297bd8bdcf5c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 11 Sep 2024 15:37:28 -0700 Subject: [PATCH 451/730] Export OpenFileOptions --- packages/lazy-file/CHANGELOG.md | 15 +++++---------- packages/lazy-file/src/fs.ts | 6 +++--- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/packages/lazy-file/CHANGELOG.md b/packages/lazy-file/CHANGELOG.md index 5185ec2e9dc..f1e96de9917 100644 --- a/packages/lazy-file/CHANGELOG.md +++ b/packages/lazy-file/CHANGELOG.md @@ -1,16 +1,11 @@ -## 3.1.0 (2024-09-04) +## HEAD +- Export `OpenFileOptions` from `lazy-file/fs` -### 🚀 Features +## v3.1.0 (2024-09-04) -- Add writeFile method to lazy-file/fs and rename getFile => openFile ([f7233a8](https://github.com/mjackson/remix-the-web/commit/f7233a8)) - -- Accept an open file descriptor or file handle in `writeFile(fd)` ([d5087ba](https://github.com/mjackson/remix-the-web/commit/d5087ba)) - - -### ❤️ Thank You - -- Michael Jackson @mjackson +- Add writeFile method to `lazy-file/fs` and rename `getFile` => `openFile` +- Accept an open file descriptor or file handle in `writeFile(fd)` ## v3.0.0 (2024-08-25) diff --git a/packages/lazy-file/src/fs.ts b/packages/lazy-file/src/fs.ts index eebdb537b4a..2f91f0130e2 100644 --- a/packages/lazy-file/src/fs.ts +++ b/packages/lazy-file/src/fs.ts @@ -4,7 +4,7 @@ import { lookup } from 'mrmime'; import { LazyContent, LazyFile } from './lib/lazy-file.js'; -export interface GetFileOptions { +export interface OpenFileOptions { /** * Overrides the name of the file. Default is the name of the file on disk. */ @@ -28,7 +28,7 @@ export interface GetFileOptions { * @param options Options to override the file's metadata * @returns A `File` object */ -export function openFile(filename: string, options?: GetFileOptions): File { +export function openFile(filename: string, options?: OpenFileOptions): File { let stats = fs.statSync(filename); if (!stats.isFile()) { @@ -65,7 +65,7 @@ function streamFile(filename: string, start = 0, end = Infinity): ReadableStream } // Preserve backwards compat with v3.0 -export { openFile as getFile }; +export { type OpenFileOptions as GetFileOptions, openFile as getFile }; /** * Writes a `File` to the local filesytem and resolves when the stream is finished. From 9010bc241d40eb5c371b7912799da1ece553d432 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 11 Sep 2024 15:40:42 -0700 Subject: [PATCH 452/730] Remove Nx --- nx.json | 30 - package.json | 9 +- packages/file-storage/package.json | 5 +- packages/form-data-parser/package.json | 5 +- packages/headers/package.json | 5 +- packages/lazy-file/package.json | 5 +- packages/multipart-parser/package.json | 5 +- packages/node-fetch-server/package.json | 5 +- pnpm-lock.yaml | 3409 +---------------------- scripts/changelog-renderer.cjs | 30 - scripts/release.js | 13 - 11 files changed, 118 insertions(+), 3403 deletions(-) delete mode 100644 nx.json delete mode 100644 scripts/changelog-renderer.cjs delete mode 100644 scripts/release.js diff --git a/nx.json b/nx.json deleted file mode 100644 index fe9ec4b6696..00000000000 --- a/nx.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "./node_modules/nx/schemas/nx-schema.json", - "targetDefaults": { - "build": { - "dependsOn": ["^build"], - "outputs": ["{projectRoot}/dist"], - "cache": true - }, - "test": { - "cache": true - } - }, - "release": { - "projects": ["packages/*"], - "projectsRelationship": "independent", - "versionPlans": true, - "version": { - "generatorOptions": { - "updateDependents": "auto", - "preserveLocalDependencyProtocols": true - } - }, - "changelog": { - "projectChangelogs": { - "createRelease": "github", - "renderer": "{workspaceRoot}/scripts/changelog-renderer.cjs" - } - } - } -} diff --git a/package.json b/package.json index ddf825fb6db..4ab74067ce5 100644 --- a/package.json +++ b/package.json @@ -2,19 +2,12 @@ "name": "remix-the-web", "private": true, "packageManager": "pnpm@9.9.0", - "type": "module", "devDependencies": { - "@nx/js": "19.7.2", "@swc-node/register": "^1.10.9", - "@swc/core": "~1.5.7", - "@swc/helpers": "~0.5.11", - "nx": "19.7.2", "prettier": "^3.3.3", "typescript": "^5.5.4" }, "scripts": { - "clean": "git clean -fdX .", - "release": "node scripts/release.js", - "test": "nx run-many --projects='packages/*' --target=test" + "clean": "git clean -fdX ." } } diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index 58ab7b68868..ac61b96b6a8 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -38,8 +38,5 @@ "storage", "stream", "fs" - ], - "nx": { - "name": "file-storage" - } + ] } diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index bf4a63a32ea..c28d2d27695 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -36,8 +36,5 @@ "FormData", "multipart", "parser" - ], - "nx": { - "name": "form-data-parser" - } + ] } diff --git a/packages/headers/package.json b/packages/headers/package.json index 7605e9463a1..f284bba1461 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -33,8 +33,5 @@ "http", "header", "headers" - ], - "nx": { - "name": "headers" - } + ] } diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index a713c318955..ad618562b34 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -36,8 +36,5 @@ "file", "buffer", "blob" - ], - "nx": { - "name": "lazy-file" - } + ] } diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index bfbcf6047c5..1d6398e8425 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -41,8 +41,5 @@ "parser", "stream", "http" - ], - "nx": { - "name": "multipart-parser" - } + ] } diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 3cc3f61c72c..39cd4e0757d 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -36,8 +36,5 @@ "response", "fetch", "web" - ], - "nx": { - "name": "node-fetch-server" - } + ] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 41eeabc008d..391f287880e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,21 +8,9 @@ importers: .: devDependencies: - '@nx/js': - specifier: 19.7.2 - version: 19.7.2(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) '@swc-node/register': specifier: ^1.10.9 version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) - '@swc/core': - specifier: ~1.5.7 - version: 1.5.29(@swc/helpers@0.5.12) - '@swc/helpers': - specifier: ~0.5.11 - version: 0.5.12 - nx: - specifier: 19.7.2 - version: 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) prettier: specifier: ^3.3.3 version: 3.3.3 @@ -180,624 +168,6 @@ importers: packages: - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - - '@babel/code-frame@7.24.7': - resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.25.4': - resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.25.2': - resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.25.5': - resolution: {integrity: sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-annotate-as-pure@7.24.7': - resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': - resolution: {integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.25.2': - resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-create-class-features-plugin@7.25.4': - resolution: {integrity: sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-create-regexp-features-plugin@7.25.2': - resolution: {integrity: sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-define-polyfill-provider@0.6.2': - resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - - '@babel/helper-member-expression-to-functions@7.24.8': - resolution: {integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.24.7': - resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.25.2': - resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-optimise-call-expression@7.24.7': - resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} - engines: {node: '>=6.9.0'} - - '@babel/helper-plugin-utils@7.24.8': - resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-remap-async-to-generator@7.25.0': - resolution: {integrity: sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-replace-supers@7.25.0': - resolution: {integrity: sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-simple-access@7.24.7': - resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-skip-transparent-expression-wrappers@7.24.7': - resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.24.8': - resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.24.7': - resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-option@7.24.8': - resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} - engines: {node: '>=6.9.0'} - - '@babel/helper-wrap-function@7.25.0': - resolution: {integrity: sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.25.0': - resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} - engines: {node: '>=6.9.0'} - - '@babel/highlight@7.24.7': - resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.25.4': - resolution: {integrity: sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.3': - resolution: {integrity: sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.0': - resolution: {integrity: sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.0': - resolution: {integrity: sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7': - resolution: {integrity: sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.13.0 - - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.0': - resolution: {integrity: sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-proposal-decorators@7.24.7': - resolution: {integrity: sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': - resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-async-generators@7.8.4': - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-class-properties@7.12.13': - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-class-static-block@7.14.5': - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-decorators@7.24.7': - resolution: {integrity: sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-dynamic-import@7.8.3': - resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-export-namespace-from@7.8.3': - resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-assertions@7.24.7': - resolution: {integrity: sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-attributes@7.24.7': - resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-meta@7.10.4': - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-json-strings@7.8.3': - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-jsx@7.24.7': - resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-logical-assignment-operators@7.10.4': - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-numeric-separator@7.10.4': - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-object-rest-spread@7.8.3': - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-optional-catch-binding@7.8.3': - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-optional-chaining@7.8.3': - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-private-property-in-object@7.14.5': - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-top-level-await@7.14.5': - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-typescript@7.25.4': - resolution: {integrity: sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-unicode-sets-regex@7.18.6': - resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-transform-arrow-functions@7.24.7': - resolution: {integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-async-generator-functions@7.25.4': - resolution: {integrity: sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-async-to-generator@7.24.7': - resolution: {integrity: sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-block-scoped-functions@7.24.7': - resolution: {integrity: sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-block-scoping@7.25.0': - resolution: {integrity: sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-class-properties@7.25.4': - resolution: {integrity: sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-class-static-block@7.24.7': - resolution: {integrity: sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.12.0 - - '@babel/plugin-transform-classes@7.25.4': - resolution: {integrity: sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-computed-properties@7.24.7': - resolution: {integrity: sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-destructuring@7.24.8': - resolution: {integrity: sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-dotall-regex@7.24.7': - resolution: {integrity: sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-duplicate-keys@7.24.7': - resolution: {integrity: sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.0': - resolution: {integrity: sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-transform-dynamic-import@7.24.7': - resolution: {integrity: sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-exponentiation-operator@7.24.7': - resolution: {integrity: sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-export-namespace-from@7.24.7': - resolution: {integrity: sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-for-of@7.24.7': - resolution: {integrity: sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-function-name@7.25.1': - resolution: {integrity: sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-json-strings@7.24.7': - resolution: {integrity: sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-literals@7.25.2': - resolution: {integrity: sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-logical-assignment-operators@7.24.7': - resolution: {integrity: sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-member-expression-literals@7.24.7': - resolution: {integrity: sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-modules-amd@7.24.7': - resolution: {integrity: sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-modules-commonjs@7.24.8': - resolution: {integrity: sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-modules-systemjs@7.25.0': - resolution: {integrity: sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-modules-umd@7.24.7': - resolution: {integrity: sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-named-capturing-groups-regex@7.24.7': - resolution: {integrity: sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-transform-new-target@7.24.7': - resolution: {integrity: sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-nullish-coalescing-operator@7.24.7': - resolution: {integrity: sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-numeric-separator@7.24.7': - resolution: {integrity: sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-object-rest-spread@7.24.7': - resolution: {integrity: sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-object-super@7.24.7': - resolution: {integrity: sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-optional-catch-binding@7.24.7': - resolution: {integrity: sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-optional-chaining@7.24.8': - resolution: {integrity: sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-parameters@7.24.7': - resolution: {integrity: sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-private-methods@7.25.4': - resolution: {integrity: sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-private-property-in-object@7.24.7': - resolution: {integrity: sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-property-literals@7.24.7': - resolution: {integrity: sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-regenerator@7.24.7': - resolution: {integrity: sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-reserved-words@7.24.7': - resolution: {integrity: sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-runtime@7.25.4': - resolution: {integrity: sha512-8hsyG+KUYGY0coX6KUCDancA0Vw225KJ2HJO0yCNr1vq5r+lJTleDaJf0K7iOhjw4SWhu03TMBzYTJ9krmzULQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-shorthand-properties@7.24.7': - resolution: {integrity: sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-spread@7.24.7': - resolution: {integrity: sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-sticky-regex@7.24.7': - resolution: {integrity: sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-template-literals@7.24.7': - resolution: {integrity: sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-typeof-symbol@7.24.8': - resolution: {integrity: sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-typescript@7.25.2': - resolution: {integrity: sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-unicode-escapes@7.24.7': - resolution: {integrity: sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-unicode-property-regex@7.24.7': - resolution: {integrity: sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-unicode-regex@7.24.7': - resolution: {integrity: sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-unicode-sets-regex@7.25.4': - resolution: {integrity: sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/preset-env@7.25.4': - resolution: {integrity: sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/preset-modules@0.1.6-no-external-plugins': - resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} - peerDependencies: - '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - - '@babel/preset-typescript@7.24.7': - resolution: {integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/regjsgen@0.8.0': - resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} - - '@babel/runtime@7.25.4': - resolution: {integrity: sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==} - engines: {node: '>=6.9.0'} - - '@babel/template@7.25.0': - resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.25.4': - resolution: {integrity: sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.25.4': - resolution: {integrity: sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==} - engines: {node: '>=6.9.0'} - '@cloudflare/kv-asset-handler@0.3.4': resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} engines: {node: '>=16.13'} @@ -1001,172 +371,56 @@ packages: '@fastify/busboy@3.0.0': resolution: {integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==} - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} - '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@nrwl/devkit@19.7.2': - resolution: {integrity: sha512-cn1eTxSVh7RQeEsPLe++vIBKXKaeFvsqJFUgyYH2u9LH1ib6gTex6Ywa2QPHoVU9fvTTwOv7ZsZk4+usfwmsMg==} - - '@nrwl/js@19.7.2': - resolution: {integrity: sha512-Md2EWHbLrVhsB3KeI+EzgQPMCPwcGGAFZ17f9WnxzMHi5Wr219f7a72vD+6qIc3gwd+2EDMdvSHm10+oup+Rzg==} - - '@nrwl/tao@19.7.2': - resolution: {integrity: sha512-sGaJWgR2F9i64BAULzCG3D5Kmf96wg3hyEAICpZe0VNnJV/DuXoNKFW+uhy7/l4Z6thgBV3dvoPhN5YTN47ggA==} - hasBin: true - - '@nrwl/workspace@19.7.2': - resolution: {integrity: sha512-a6DojKBDdbAe85gV0Rxo92P8yhuXK1C2jWCIAZEaa6Am5gpfyezxIIKPcvKqucgtDg1aaU6zyP03GcMS9J6HuQ==} - - '@nx/devkit@19.7.2': - resolution: {integrity: sha512-WYffA5fXhXguy2/QphPCi8aZy39c14R2N1MkuNkOSVznZTgWbuHGiaP4BwD+/XAfbZhqnrEJvMHpmYcSm90DkQ==} - peerDependencies: - nx: '>= 17 <= 20' - - '@nx/js@19.7.2': - resolution: {integrity: sha512-lpMJVHerDdTPkfDnK/6wPnV6yoYq8x4/1nqfyH4OuX5V/oQIe2fKaqEGurvFvcn0f3zNopuyr6E1+w1rmYpODA==} - peerDependencies: - verdaccio: ^5.0.4 - peerDependenciesMeta: - verdaccio: - optional: true - - '@nx/nx-darwin-arm64@19.7.2': - resolution: {integrity: sha512-pKLhQSdbg9oIovQrzpJqzQk8vS2V1t8vPniRLpH3YGziAlo+wTESDkgE2ZNmv/NqLti45fjZZ6I/7r2jdF6z4A==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-darwin-arm64@1.11.0': + resolution: {integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==} cpu: [arm64] os: [darwin] - '@nx/nx-darwin-x64@19.7.2': - resolution: {integrity: sha512-PdQFp4Zo+Ero5tTh8d+mae0Fo64vWLLBcTh4zPmskjaU5PiY6/4xOzdaAjtbHiak7h1mCGB/31/efFzKf5EvKA==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-darwin-x64@1.11.0': + resolution: {integrity: sha512-w/svTRKnuRinojYAVsWRozVoPar7XUPlJhpfnsYlReRjls6A53/ziTzHfpmcKjdBrP/AXPcDVJDnM4pOSsvWvA==} cpu: [x64] os: [darwin] - '@nx/nx-freebsd-x64@19.7.2': - resolution: {integrity: sha512-ORedNKXCbH4DQ4lX+YoHsHwGNGWxeU/8OpiWRcZzpF5vYVoTR3m93szemdJ3U5V6IXFI7r6/qz/FRltnx+VT8g==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-freebsd-x64@1.11.0': + resolution: {integrity: sha512-thGp8g8maYUx7vYJqD0vSsuUO95vWNJwKS2AXchq212J5dQ0Dybq4gjt2O2N9iU+lxj1QzmIDXGw7q5HCagOiw==} cpu: [x64] os: [freebsd] - '@nx/nx-linux-arm-gnueabihf@19.7.2': - resolution: {integrity: sha512-KxCfE9qFwmtTBqcYGKs3uYkxsuAhItf1xyMK07uhdY6igI1cuhVBYNLtVd0t25lb4SU4RFtwQu69A328FVc11w==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-linux-arm-gnueabihf@1.11.0': + resolution: {integrity: sha512-8G99bs4cnwpJRjRK2cEJXiJVyLogzPJq4JgLlcMEKSGhdkoMV1Ia0dghLk9lAFog33U4lWIwKmPgqQzTO6JM8g==} cpu: [arm] os: [linux] - '@nx/nx-linux-arm64-gnu@19.7.2': - resolution: {integrity: sha512-ljiDNBPwL+aGnqZw9fAygNj4c2FRUDqGypli0gjWNZjri+JJqqtPwdYLYsUVBCs8chcgwvsHYP0AVKZaPf2K1A==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-linux-arm64-gnu@1.11.0': + resolution: {integrity: sha512-hNcB/wbuCFbsspg4h9+Nz5gSL8PbRW7zG/eVvmEpzGhmVubzDFuNmlYtmaUaZ6b9jzOrrqTkYCt9t7Q2TDHnBA==} cpu: [arm64] os: [linux] - '@nx/nx-linux-arm64-musl@19.7.2': - resolution: {integrity: sha512-G9IBIfCFknbVd+ZNn22BC80pu6JgToslEZyl2qRKRgq6D4Xsfm8zwKlKJNQDWY3I//f26u+wiA83yEFOaQcqyQ==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-linux-arm64-musl@1.11.0': + resolution: {integrity: sha512-H9rjqCcNQT9aip1VLrtsiyj9So0DEKUoutMNu1oL9UuD3H5lWIaxhDlHTAFsobWeUHCnuaCbizhGb9wyLRHSuA==} cpu: [arm64] os: [linux] - '@nx/nx-linux-x64-gnu@19.7.2': - resolution: {integrity: sha512-P5HQhLoxLodpbhF5Col+ygScXfcVnk0gqXPxbc7kOnhdCwwIISZxHPsrgm0jbWaB5TufBuZNlo+ST8Evtnzojg==} - engines: {node: '>= 10'} + '@oxc-resolver/binding-linux-x64-gnu@1.11.0': + resolution: {integrity: sha512-6hdv/kmaGysK3/hUaGTYG07yX+nvk6hGoWombmOuc0vBnGLRtSjqvvgDBdAs9/iIcOSQI2YNUEiJvTyy6eb5GA==} cpu: [x64] os: [linux] - '@nx/nx-linux-x64-musl@19.7.2': - resolution: {integrity: sha512-b08iqgz4Z2jKRJ66rf7ci/n0LFZ3CnaxdpXnOpb1FM/ZBLn3BuNah36K03UWamBlkrVEmAORZtPKZ5OuQHnlMg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@nx/nx-win32-arm64-msvc@19.7.2': - resolution: {integrity: sha512-hn8Qm/iGiOpyP/34M/aKFYDStLzudX1dYPC62RnXU0/WI29JTdnT420rYjwXkQTaPMZsvi5xkQmBphowfGlHww==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@nx/nx-win32-x64-msvc@19.7.2': - resolution: {integrity: sha512-gK5XnkeiVbjs9+dkukGmZedXrxSL845t/ntlA8wp4joOnb7xUED/xvwhIP7DRjL6VefFbFIzhxgPaSaKfzaiiA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@nx/workspace@19.7.2': - resolution: {integrity: sha512-Nj7OSY0jBtz5S2U5SC9HoUlaRyzUseQNwfVTvLb9yTByhcR/XkJZW+iWXYcG4VHF7fRhJjH1IdX8HaXkbN74KA==} - - '@oxc-resolver/binding-darwin-arm64@1.11.0': - resolution: {integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==} - cpu: [arm64] - os: [darwin] - - '@oxc-resolver/binding-darwin-x64@1.11.0': - resolution: {integrity: sha512-w/svTRKnuRinojYAVsWRozVoPar7XUPlJhpfnsYlReRjls6A53/ziTzHfpmcKjdBrP/AXPcDVJDnM4pOSsvWvA==} - cpu: [x64] - os: [darwin] - - '@oxc-resolver/binding-freebsd-x64@1.11.0': - resolution: {integrity: sha512-thGp8g8maYUx7vYJqD0vSsuUO95vWNJwKS2AXchq212J5dQ0Dybq4gjt2O2N9iU+lxj1QzmIDXGw7q5HCagOiw==} - cpu: [x64] - os: [freebsd] - - '@oxc-resolver/binding-linux-arm-gnueabihf@1.11.0': - resolution: {integrity: sha512-8G99bs4cnwpJRjRK2cEJXiJVyLogzPJq4JgLlcMEKSGhdkoMV1Ia0dghLk9lAFog33U4lWIwKmPgqQzTO6JM8g==} - cpu: [arm] - os: [linux] - - '@oxc-resolver/binding-linux-arm64-gnu@1.11.0': - resolution: {integrity: sha512-hNcB/wbuCFbsspg4h9+Nz5gSL8PbRW7zG/eVvmEpzGhmVubzDFuNmlYtmaUaZ6b9jzOrrqTkYCt9t7Q2TDHnBA==} - cpu: [arm64] - os: [linux] - - '@oxc-resolver/binding-linux-arm64-musl@1.11.0': - resolution: {integrity: sha512-H9rjqCcNQT9aip1VLrtsiyj9So0DEKUoutMNu1oL9UuD3H5lWIaxhDlHTAFsobWeUHCnuaCbizhGb9wyLRHSuA==} - cpu: [arm64] - os: [linux] - - '@oxc-resolver/binding-linux-x64-gnu@1.11.0': - resolution: {integrity: sha512-6hdv/kmaGysK3/hUaGTYG07yX+nvk6hGoWombmOuc0vBnGLRtSjqvvgDBdAs9/iIcOSQI2YNUEiJvTyy6eb5GA==} - cpu: [x64] - os: [linux] - - '@oxc-resolver/binding-linux-x64-musl@1.11.0': - resolution: {integrity: sha512-AYUvI4VwQkBq0rcYI3Z7a9+BpllbllbxQCD30ZRgHghvqXvDECWfP8r98iynz7u0oKGO8ZPf15d/l9VrkRtiuQ==} + '@oxc-resolver/binding-linux-x64-musl@1.11.0': + resolution: {integrity: sha512-AYUvI4VwQkBq0rcYI3Z7a9+BpllbllbxQCD30ZRgHghvqXvDECWfP8r98iynz7u0oKGO8ZPf15d/l9VrkRtiuQ==} cpu: [x64] os: [linux] @@ -1185,9 +439,6 @@ packages: cpu: [x64] os: [win32] - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - '@swc-node/core@1.13.3': resolution: {integrity: sha512-OGsvXIid2Go21kiNqeTIn79jcaX4l0G93X2rAnas4LFoDyA9wAwVK7xZdm+QsKoMn5Mus2yFLCc4OtX2dD/PWA==} engines: {node: '>= 10'} @@ -1282,18 +533,6 @@ packages: '@swc/types@0.1.12': resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==} - '@tsconfig/node10@1.0.11': - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} - - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - '@tybys/wasm-util@0.9.0': resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} @@ -1333,9 +572,6 @@ packages: '@types/node@22.5.0': resolution: {integrity: sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==} - '@types/parse-json@4.0.2': - resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} - '@types/qs@6.9.15': resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} @@ -1354,17 +590,6 @@ packages: '@types/ws@8.5.12': resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} - '@yarnpkg/lockfile@1.1.0': - resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} - - '@yarnpkg/parsers@3.0.0-rc.46': - resolution: {integrity: sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==} - engines: {node: '>=14.15.0'} - - '@zkochan/js-yaml@0.0.7': - resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} - hasBin: true - accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -1378,103 +603,20 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - address@1.2.2: - resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} - engines: {node: '>= 10.0.0'} - - ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} as-table@1.0.55: resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} - async@3.2.6: - resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - axios@1.7.5: - resolution: {integrity: sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==} - - babel-plugin-const-enum@1.2.0: - resolution: {integrity: sha512-o1m/6iyyFnp9MRsK1dHF3bneqyf3AlM2q3A/YbgQr2pCat6B6XJVDv2TXqzfY2RYUi4mak6WAksSBPlyYGx9dg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - babel-plugin-macros@2.8.0: - resolution: {integrity: sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==} - - babel-plugin-polyfill-corejs2@0.4.11: - resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - - babel-plugin-polyfill-corejs3@0.10.6: - resolution: {integrity: sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - - babel-plugin-polyfill-regenerator@0.6.2: - resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - - babel-plugin-transform-typescript-metadata@0.3.2: - resolution: {integrity: sha512-mWEvCQTgXQf48yDqgN7CH50waTyYBeP2Lpqx4nNWab9sxEpdXVeKgfj1qYI2/TgUPQtNFZ85i3PemRtnXVYYJg==} - peerDependencies: - '@babel/core': ^7 - '@babel/traverse': ^7 - peerDependenciesMeta: - '@babel/traverse': - optional: true - - 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'} - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - blake3-wasm@2.1.5: resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} @@ -1482,27 +624,13 @@ packages: resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.23.3: - resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - bun-types@1.1.26: resolution: {integrity: sha512-n7jDe62LsB2+WE8Q8/mT3azkPaatKlj/2MyP6hi3mKvPz9oPpB6JW/Ll6JHtNLudasFFuvfgklYSE+rreGvBjw==} @@ -1518,71 +646,16 @@ packages: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - caniuse-lite@1.0.30001653: - resolution: {integrity: sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==} - capnp-ts@0.7.0: resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} - chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} - cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - - cli-spinners@2.6.1: - resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} - engines: {node: '>=6'} - - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - - clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - - color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - columnify@1.6.0: - resolution: {integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==} - engines: {node: '>=8.0.0'} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - consola@3.2.3: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} engines: {node: ^14.18.0 || >=16.10.0} @@ -1595,9 +668,6 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} @@ -1609,16 +679,6 @@ packages: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} - core-js-compat@3.38.1: - resolution: {integrity: sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==} - - cosmiconfig@6.0.0: - resolution: {integrity: sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==} - engines: {node: '>=8'} - - create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - data-uri-to-buffer@2.0.2: resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} @@ -1642,24 +702,13 @@ packages: supports-color: optional: true - defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} - define-lazy-prop@2.0.0: - resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} - engines: {node: '>=8'} - defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -1668,58 +717,13 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - detect-port@1.6.1: - resolution: {integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==} - engines: {node: '>= 4.0.0'} - hasBin: true - - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - - dotenv-expand@11.0.6: - resolution: {integrity: sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==} - engines: {node: '>=12'} - - dotenv@16.4.5: - resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} - engines: {node: '>=12'} - - duplexer@0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - ejs@3.1.10: - resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} - engines: {node: '>=0.10.0'} - hasBin: true - - electron-to-chromium@1.5.13: - resolution: {integrity: sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - - enquirer@2.3.6: - resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} - engines: {node: '>=8.6'} - - error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - es-define-property@1.0.0: resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} engines: {node: '>= 0.4'} @@ -1733,33 +737,16 @@ packages: engines: {node: '>=12'} hasBin: true - escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} - engines: {node: '>=6'} - escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - estree-walker@0.6.1: resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - etag@1.8.1: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} @@ -1772,20 +759,6 @@ packages: resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} engines: {node: '>= 0.10.0'} - fast-glob@3.2.7: - resolution: {integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==} - engines: {node: '>=8'} - - fastq@1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - - figures@3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - - filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -1794,23 +767,6 @@ packages: resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} engines: {node: '>= 0.8'} - flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} - hasBin: true - - follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -1819,16 +775,6 @@ packages: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} - front-matter@4.0.2: - resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} - - fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - - fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} - engines: {node: '>=14.14'} - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1837,14 +783,6 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -1859,24 +797,9 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} @@ -1892,10 +815,6 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} - hosted-git-info@7.0.2: - resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} - engines: {node: ^16.14.0 || >=18.0.0} - http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} @@ -1904,17 +823,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.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -1922,9 +830,6 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -1933,108 +838,21 @@ packages: resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} engines: {node: '>= 0.4'} - is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - - is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} - - jake@10.9.2: - resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} - engines: {node: '>=10'} - hasBin: true - - jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - - jsesc@0.5.0: - resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} - hasBin: true - - jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - - json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - jsonc-parser@3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - - lines-and-columns@2.0.3: - resolution: {integrity: sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - lodash.debounce@4.0.8: - resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -2042,18 +860,10 @@ packages: merge-descriptors@1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -2072,29 +882,11 @@ packages: engines: {node: '>=10.0.0'} hasBin: true - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - miniflare@3.20240821.0: resolution: {integrity: sha512-4BhLGpssQxM/O6TZmJ10GkT3wBJK6emFkZ3V87/HyvQmVt8zMxEBvyw5uv6kdtp+7F54Nw6IKFJjPUL8rFVQrQ==} engines: {node: '>=16.13'} hasBin: true - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} - - minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - mrmime@2.0.0: resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} engines: {node: '>=10'} @@ -2131,36 +923,10 @@ packages: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} - node-machine-id@1.1.12: - resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} - - node-releases@2.0.18: - resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} - normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - npm-package-arg@11.0.1: - resolution: {integrity: sha512-M7s1BD4NxdAvBKUPqqRW957Xwcl/4Zvo8Aj+ANrzvIPzGJZElrH7Z//rSaec2ORcND6FHHLnZeY8qgTpXDMFQQ==} - engines: {node: ^16.14.0 || >=18.0.0} - - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - - nx@19.7.2: - resolution: {integrity: sha512-mHwRk6UdTkGrLwyYq4Via30kiG2he3d3z1ny0DFlkTQVHZPKpNOf0iROfyZOe31mcjSaTt/eHo7LgEQf1GaXvQ==} - hasBin: true - peerDependencies: - '@swc-node/register': ^1.8.0 - '@swc/core': ^1.3.85 - peerDependenciesMeta: - '@swc-node/register': - optional: true - '@swc/core': - optional: true - object-inspect@1.13.2: resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} engines: {node: '>= 0.4'} @@ -2169,40 +935,13 @@ packages: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - - open@8.4.2: - resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} - engines: {node: '>=12'} - - ora@5.3.0: - resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} - engines: {node: '>=10'} - oxc-resolver@1.11.0: resolution: {integrity: sha512-N3qMse2AM7uST8PaiUMXZkcACyGAMN073tomyvzHTICSzaOqKHvVS0IZ3vj/OqoE140QP4CyOiWmgC1Hw5Urmg==} - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -2212,16 +951,9 @@ packages: path-to-regexp@6.2.2: resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - picocolors@1.0.1: - resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} - picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -2235,31 +967,17 @@ packages: engines: {node: '>=14'} hasBin: true - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - printable-characters@1.0.42: resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} - proc-log@3.0.0: - resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - qs@6.11.0: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} engines: {node: '>=0.6'} - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -2268,46 +986,10 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} - regenerate-unicode-properties@10.1.1: - resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} - engines: {node: '>=4'} - - regenerate@1.4.2: - resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} - - regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - - regenerator-transform@0.15.2: - resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} - - regexpu-core@5.3.2: - resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} - engines: {node: '>=4'} - - regjsparser@0.9.1: - resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} - hasBin: true - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - resolve.exports@2.0.2: resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} engines: {node: '>=10'} @@ -2316,14 +998,6 @@ packages: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true - restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - - reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup-plugin-inject@3.0.2: resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. @@ -2334,9 +1008,6 @@ packages: rollup-pluginutils@2.8.2: resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -2347,15 +1018,6 @@ packages: resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} engines: {node: '>=10'} - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - semver@7.6.3: - resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} - engines: {node: '>=10'} - hasBin: true - send@0.18.0: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} engines: {node: '>= 0.8.0'} @@ -2375,1084 +1037,125 @@ packages: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - source-map-support@0.5.19: - resolution: {integrity: sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==} - source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - - stacktracey@2.1.8: - resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} - - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - - stoppable@1.1.0: - resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} - engines: {node: '>=4', npm: '>=6'} - - streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - 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'} - - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - - strong-log-transformer@2.1.0: - resolution: {integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==} - engines: {node: '>=4'} - hasBin: true - - supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - - tmp@0.2.3: - resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} - engines: {node: '>=14.14'} - - to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - ts-node@10.9.1: - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - - tsconfig-paths@4.2.0: - resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} - engines: {node: '>=6'} - - tslib@2.7.0: - resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} - - type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - - typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} - engines: {node: '>=14.17'} - hasBin: true - - ufo@1.5.4: - resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} - - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - - undici@5.28.4: - resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} - engines: {node: '>=14.0'} - - unenv-nightly@1.10.0-1717606461.a117952: - resolution: {integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==} - - unicode-canonical-property-names-ecmascript@2.0.0: - resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} - engines: {node: '>=4'} - - unicode-match-property-ecmascript@2.0.0: - resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} - engines: {node: '>=4'} - - unicode-match-property-value-ecmascript@2.1.0: - resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} - engines: {node: '>=4'} - - unicode-property-aliases-ecmascript@2.1.0: - resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} - engines: {node: '>=4'} - - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - update-browserslist-db@1.1.0: - resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - - v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - - validate-npm-package-name@5.0.1: - resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - - wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - - workerd@1.20240821.1: - resolution: {integrity: sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==} - engines: {node: '>=16'} - hasBin: true - - wrangler@3.72.3: - resolution: {integrity: sha512-EBlJGOcwanbzFkiJkRB47WKhvevh1AZK0ty0MyD0gptsgWnAxBfmFGiBuzOuRXbvH45ZrFrTqgi8c67EwcV1nA==} - engines: {node: '>=16.17.0'} - hasBin: true - peerDependencies: - '@cloudflare/workers-types': ^4.20240821.1 - peerDependenciesMeta: - '@cloudflare/workers-types': - optional: true - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - ws@8.18.0: - resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - xxhash-wasm@1.0.2: - resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - - yaml@1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} - engines: {node: '>= 6'} - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - - yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - - youch@3.3.3: - resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} - - zod@3.23.8: - resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} - -snapshots: - - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - - '@babel/code-frame@7.24.7': - dependencies: - '@babel/highlight': 7.24.7 - picocolors: 1.0.1 - - '@babel/compat-data@7.25.4': {} - - '@babel/core@7.25.2': - dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.24.7 - '@babel/generator': 7.25.5 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) - '@babel/helpers': 7.25.0 - '@babel/parser': 7.25.4 - '@babel/template': 7.25.0 - '@babel/traverse': 7.25.4 - '@babel/types': 7.25.4 - convert-source-map: 2.0.0 - debug: 4.3.6 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/generator@7.25.5': - dependencies: - '@babel/types': 7.25.4 - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 2.5.2 - - '@babel/helper-annotate-as-pure@7.24.7': - dependencies: - '@babel/types': 7.25.4 - - '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': - dependencies: - '@babel/traverse': 7.25.4 - '@babel/types': 7.25.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-compilation-targets@7.25.2': - dependencies: - '@babel/compat-data': 7.25.4 - '@babel/helper-validator-option': 7.24.8 - browserslist: 4.23.3 - lru-cache: 5.1.1 - semver: 6.3.1 - - '@babel/helper-create-class-features-plugin@7.25.4(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-member-expression-to-functions': 7.24.8 - '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/traverse': 7.25.4 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/helper-create-regexp-features-plugin@7.25.2(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - regexpu-core: 5.3.2 - semver: 6.3.1 - - '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - debug: 4.3.6 - lodash.debounce: 4.0.8 - resolve: 1.22.8 - transitivePeerDependencies: - - supports-color - - '@babel/helper-member-expression-to-functions@7.24.8': - dependencies: - '@babel/traverse': 7.25.4 - '@babel/types': 7.25.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-imports@7.24.7': - dependencies: - '@babel/traverse': 7.25.4 - '@babel/types': 7.25.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-imports': 7.24.7 - '@babel/helper-simple-access': 7.24.7 - '@babel/helper-validator-identifier': 7.24.7 - '@babel/traverse': 7.25.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-optimise-call-expression@7.24.7': - dependencies: - '@babel/types': 7.25.4 - - '@babel/helper-plugin-utils@7.24.8': {} - - '@babel/helper-remap-async-to-generator@7.25.0(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-wrap-function': 7.25.0 - '@babel/traverse': 7.25.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-replace-supers@7.25.0(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-member-expression-to-functions': 7.24.8 - '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/traverse': 7.25.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-simple-access@7.24.7': - dependencies: - '@babel/traverse': 7.25.4 - '@babel/types': 7.25.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-skip-transparent-expression-wrappers@7.24.7': - dependencies: - '@babel/traverse': 7.25.4 - '@babel/types': 7.25.4 - transitivePeerDependencies: - - supports-color - - '@babel/helper-string-parser@7.24.8': {} - - '@babel/helper-validator-identifier@7.24.7': {} - - '@babel/helper-validator-option@7.24.8': {} - - '@babel/helper-wrap-function@7.25.0': - dependencies: - '@babel/template': 7.25.0 - '@babel/traverse': 7.25.4 - '@babel/types': 7.25.4 - transitivePeerDependencies: - - supports-color - - '@babel/helpers@7.25.0': - dependencies: - '@babel/template': 7.25.0 - '@babel/types': 7.25.4 - - '@babel/highlight@7.24.7': - dependencies: - '@babel/helper-validator-identifier': 7.24.7 - chalk: 2.4.2 - js-tokens: 4.0.0 - picocolors: 1.0.1 - - '@babel/parser@7.25.4': - dependencies: - '@babel/types': 7.25.4 - - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.3(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/traverse': 7.25.4 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.0(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.0(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.25.2) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.0(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/traverse': 7.25.4 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-proposal-decorators@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-decorators': 7.24.7(@babel/core@7.25.2) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-decorators@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-import-assertions@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-typescript@7.25.4(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-transform-arrow-functions@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-transform-async-generator-functions@7.25.4(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-remap-async-to-generator': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) - '@babel/traverse': 7.25.4 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-async-to-generator@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-imports': 7.24.7 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-remap-async-to-generator': 7.25.0(@babel/core@7.25.2) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-block-scoped-functions@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-transform-block-scoping@7.25.0(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-transform-class-properties@7.25.4(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-class-static-block@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-classes@7.25.4(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) - '@babel/traverse': 7.25.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-computed-properties@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/template': 7.25.0 - - '@babel/plugin-transform-destructuring@7.24.8(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-transform-dotall-regex@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-transform-duplicate-keys@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.0(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-transform-dynamic-import@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) - - '@babel/plugin-transform-exponentiation-operator@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.24.7 - '@babel/helper-plugin-utils': 7.24.8 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-export-namespace-from@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.25.2) - - '@babel/plugin-transform-for-of@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-function-name@7.25.1(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/traverse': 7.25.4 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-json-strings@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) - - '@babel/plugin-transform-literals@7.25.2(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-transform-logical-assignment-operators@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) - - '@babel/plugin-transform-member-expression-literals@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-transform-modules-amd@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-modules-commonjs@7.24.8(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-simple-access': 7.24.7 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-modules-systemjs@7.25.0(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-validator-identifier': 7.24.7 - '@babel/traverse': 7.25.4 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-modules-umd@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-named-capturing-groups-regex@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-transform-new-target@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - - '@babel/plugin-transform-nullish-coalescing-operator@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) - - '@babel/plugin-transform-numeric-separator@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) - - '@babel/plugin-transform-object-rest-spread@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.25.2) - - '@babel/plugin-transform-object-super@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) - transitivePeerDependencies: - - supports-color + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} - '@babel/plugin-transform-optional-catch-binding@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) + sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead - '@babel/plugin-transform-optional-chaining@7.24.8(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) - transitivePeerDependencies: - - supports-color + stacktracey@2.1.8: + resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} - '@babel/plugin-transform-parameters@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} - '@babel/plugin-transform-private-methods@7.25.4(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - transitivePeerDependencies: - - supports-color + stoppable@1.1.0: + resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} + engines: {node: '>=4', npm: '>=6'} - '@babel/plugin-transform-private-property-in-object@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) - transitivePeerDependencies: - - supports-color + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} - '@babel/plugin-transform-property-literals@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} - '@babel/plugin-transform-regenerator@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - regenerator-transform: 0.15.2 + tmp@0.2.3: + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + engines: {node: '>=14.14'} - '@babel/plugin-transform-reserved-words@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} - '@babel/plugin-transform-runtime@7.25.4(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-module-imports': 7.24.7 - '@babel/helper-plugin-utils': 7.24.8 - babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.25.2) - babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.25.2) - babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.25.2) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} - '@babel/plugin-transform-shorthand-properties@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} - '@babel/plugin-transform-spread@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - transitivePeerDependencies: - - supports-color + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} - '@babel/plugin-transform-sticky-regex@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true - '@babel/plugin-transform-template-literals@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} - '@babel/plugin-transform-typeof-symbol@7.24.8(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - '@babel/plugin-transform-typescript@7.25.2(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-create-class-features-plugin': 7.25.4(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/plugin-syntax-typescript': 7.25.4(@babel/core@7.25.2) - transitivePeerDependencies: - - supports-color + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - '@babel/plugin-transform-unicode-escapes@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 + undici@5.28.4: + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} + engines: {node: '>=14.0'} - '@babel/plugin-transform-unicode-property-regex@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 + unenv-nightly@1.10.0-1717606461.a117952: + resolution: {integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==} - '@babel/plugin-transform-unicode-regex@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} - '@babel/plugin-transform-unicode-sets-regex@7.25.4(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.24.8 + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} - '@babel/preset-env@7.25.4(@babel/core@7.25.2)': - dependencies: - '@babel/compat-data': 7.25.4 - '@babel/core': 7.25.2 - '@babel/helper-compilation-targets': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-validator-option': 7.24.8 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.3(@babel/core@7.25.2) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.2) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-import-assertions': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.2) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.25.2) - '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-async-generator-functions': 7.25.4(@babel/core@7.25.2) - '@babel/plugin-transform-async-to-generator': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-block-scoped-functions': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-block-scoping': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-transform-class-properties': 7.25.4(@babel/core@7.25.2) - '@babel/plugin-transform-class-static-block': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-classes': 7.25.4(@babel/core@7.25.2) - '@babel/plugin-transform-computed-properties': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-destructuring': 7.24.8(@babel/core@7.25.2) - '@babel/plugin-transform-dotall-regex': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-duplicate-keys': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-transform-dynamic-import': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-exponentiation-operator': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-export-namespace-from': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-for-of': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-function-name': 7.25.1(@babel/core@7.25.2) - '@babel/plugin-transform-json-strings': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-literals': 7.25.2(@babel/core@7.25.2) - '@babel/plugin-transform-logical-assignment-operators': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-member-expression-literals': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-modules-amd': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.25.2) - '@babel/plugin-transform-modules-systemjs': 7.25.0(@babel/core@7.25.2) - '@babel/plugin-transform-modules-umd': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-named-capturing-groups-regex': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-new-target': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-nullish-coalescing-operator': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-numeric-separator': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-object-rest-spread': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-object-super': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-optional-catch-binding': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.25.2) - '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-private-methods': 7.25.4(@babel/core@7.25.2) - '@babel/plugin-transform-private-property-in-object': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-property-literals': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-regenerator': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-reserved-words': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-shorthand-properties': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-spread': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-sticky-regex': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-template-literals': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-typeof-symbol': 7.24.8(@babel/core@7.25.2) - '@babel/plugin-transform-unicode-escapes': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-unicode-property-regex': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-unicode-regex': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-unicode-sets-regex': 7.25.4(@babel/core@7.25.2) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.25.2) - babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.25.2) - babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.25.2) - babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.25.2) - core-js-compat: 3.38.1 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/types': 7.25.4 - esutils: 2.0.3 + workerd@1.20240821.1: + resolution: {integrity: sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==} + engines: {node: '>=16'} + hasBin: true - '@babel/preset-typescript@7.24.7(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-validator-option': 7.24.8 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.25.2) - '@babel/plugin-transform-typescript': 7.25.2(@babel/core@7.25.2) - transitivePeerDependencies: - - supports-color + wrangler@3.72.3: + resolution: {integrity: sha512-EBlJGOcwanbzFkiJkRB47WKhvevh1AZK0ty0MyD0gptsgWnAxBfmFGiBuzOuRXbvH45ZrFrTqgi8c67EwcV1nA==} + engines: {node: '>=16.17.0'} + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^4.20240821.1 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true - '@babel/regjsgen@0.8.0': {} + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true - '@babel/runtime@7.25.4': - dependencies: - regenerator-runtime: 0.14.1 + xxhash-wasm@1.0.2: + resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} - '@babel/template@7.25.0': - dependencies: - '@babel/code-frame': 7.24.7 - '@babel/parser': 7.25.4 - '@babel/types': 7.25.4 + youch@3.3.3: + resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} - '@babel/traverse@7.25.4': - dependencies: - '@babel/code-frame': 7.24.7 - '@babel/generator': 7.25.5 - '@babel/parser': 7.25.4 - '@babel/template': 7.25.0 - '@babel/types': 7.25.4 - debug: 4.3.6 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} - '@babel/types@7.25.4': - dependencies: - '@babel/helper-string-parser': 7.24.8 - '@babel/helper-validator-identifier': 7.24.7 - to-fast-properties: 2.0.0 +snapshots: '@cloudflare/kv-asset-handler@0.3.4': dependencies: @@ -3485,14 +1188,17 @@ snapshots: dependencies: '@emnapi/wasi-threads': 1.0.1 tslib: 2.7.0 + optional: true '@emnapi/runtime@1.2.0': dependencies: tslib: 2.7.0 + optional: true '@emnapi/wasi-threads@1.0.1': dependencies: tslib: 2.7.0 + optional: true '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': dependencies: @@ -3574,27 +1280,10 @@ snapshots: '@fastify/busboy@3.0.0': {} - '@jest/schemas@29.6.3': - dependencies: - '@sinclair/typebox': 0.27.8 - - '@jridgewell/gen-mapping@0.3.5': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 - '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/set-array@1.2.1': {} - '@jridgewell/sourcemap-codec@1.5.0': {} - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -3605,157 +1294,8 @@ snapshots: '@emnapi/core': 1.2.0 '@emnapi/runtime': 1.2.0 '@tybys/wasm-util': 0.9.0 - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.1 - - '@nrwl/devkit@19.7.2(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': - dependencies: - '@nx/devkit': 19.7.2(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) - transitivePeerDependencies: - - nx - - '@nrwl/js@19.7.2(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': - dependencies: - '@nx/js': 19.7.2(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) - transitivePeerDependencies: - - '@babel/traverse' - - '@swc-node/register' - - '@swc/core' - - '@swc/wasm' - - '@types/node' - - debug - - nx - - supports-color - - typescript - - verdaccio - - '@nrwl/tao@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': - dependencies: - nx: 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) - tslib: 2.7.0 - transitivePeerDependencies: - - '@swc-node/register' - - '@swc/core' - - debug - - '@nrwl/workspace@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': - dependencies: - '@nx/workspace': 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) - transitivePeerDependencies: - - '@swc-node/register' - - '@swc/core' - - debug - - '@nx/devkit@19.7.2(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))': - dependencies: - '@nrwl/devkit': 19.7.2(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) - ejs: 3.1.10 - enquirer: 2.3.6 - ignore: 5.3.2 - minimatch: 9.0.3 - nx: 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) - semver: 7.6.3 - tmp: 0.2.3 - tslib: 2.7.0 - yargs-parser: 21.1.1 - - '@nx/js@19.7.2(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4)': - dependencies: - '@babel/core': 7.25.2 - '@babel/plugin-proposal-decorators': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-class-properties': 7.25.4(@babel/core@7.25.2) - '@babel/plugin-transform-runtime': 7.25.4(@babel/core@7.25.2) - '@babel/preset-env': 7.25.4(@babel/core@7.25.2) - '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) - '@babel/runtime': 7.25.4 - '@nrwl/js': 19.7.2(@babel/traverse@7.25.4)(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)))(typescript@5.5.4) - '@nx/devkit': 19.7.2(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) - '@nx/workspace': 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) - babel-plugin-const-enum: 1.2.0(@babel/core@7.25.2) - babel-plugin-macros: 2.8.0 - babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.25.2)(@babel/traverse@7.25.4) - chalk: 4.1.2 - columnify: 1.6.0 - detect-port: 1.6.1 - fast-glob: 3.2.7 - fs-extra: 11.2.0 - ignore: 5.3.2 - js-tokens: 4.0.0 - jsonc-parser: 3.2.0 - minimatch: 9.0.3 - npm-package-arg: 11.0.1 - npm-run-path: 4.0.1 - ora: 5.3.0 - semver: 7.6.3 - source-map-support: 0.5.19 - ts-node: 10.9.1(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(typescript@5.5.4) - tsconfig-paths: 4.2.0 - tslib: 2.7.0 - transitivePeerDependencies: - - '@babel/traverse' - - '@swc-node/register' - - '@swc/core' - - '@swc/wasm' - - '@types/node' - - debug - - nx - - supports-color - - typescript - - '@nx/nx-darwin-arm64@19.7.2': - optional: true - - '@nx/nx-darwin-x64@19.7.2': - optional: true - - '@nx/nx-freebsd-x64@19.7.2': - optional: true - - '@nx/nx-linux-arm-gnueabihf@19.7.2': - optional: true - - '@nx/nx-linux-arm64-gnu@19.7.2': - optional: true - - '@nx/nx-linux-arm64-musl@19.7.2': - optional: true - - '@nx/nx-linux-x64-gnu@19.7.2': - optional: true - - '@nx/nx-linux-x64-musl@19.7.2': - optional: true - - '@nx/nx-win32-arm64-msvc@19.7.2': - optional: true - - '@nx/nx-win32-x64-msvc@19.7.2': optional: true - '@nx/workspace@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))': - dependencies: - '@nrwl/workspace': 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) - '@nx/devkit': 19.7.2(nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12))) - chalk: 4.1.2 - enquirer: 2.3.6 - nx: 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) - tslib: 2.7.0 - yargs-parser: 21.1.1 - transitivePeerDependencies: - - '@swc-node/register' - - '@swc/core' - - debug - '@oxc-resolver/binding-darwin-arm64@1.11.0': optional: true @@ -3791,8 +1331,6 @@ snapshots: '@oxc-resolver/binding-win32-x64-msvc@1.11.0': optional: true - '@sinclair/typebox@0.27.8': {} - '@swc-node/core@1.13.3(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)': dependencies: '@swc/core': 1.5.29(@swc/helpers@0.5.12) @@ -3870,22 +1408,16 @@ snapshots: '@swc/helpers@0.5.12': dependencies: tslib: 2.7.0 + optional: true '@swc/types@0.1.12': dependencies: '@swc/counter': 0.1.3 - '@tsconfig/node10@1.0.11': {} - - '@tsconfig/node12@1.0.11': {} - - '@tsconfig/node14@1.0.3': {} - - '@tsconfig/node16@1.0.4': {} - '@tybys/wasm-util@0.9.0': dependencies: tslib: 2.7.0 + optional: true '@types/body-parser@1.19.5': dependencies: @@ -3938,8 +1470,6 @@ snapshots: dependencies: undici-types: 6.19.8 - '@types/parse-json@4.0.2': {} - '@types/qs@6.9.15': {} '@types/range-parser@1.2.7': {} @@ -3961,17 +1491,6 @@ snapshots: dependencies: '@types/node': 22.5.0 - '@yarnpkg/lockfile@1.1.0': {} - - '@yarnpkg/parsers@3.0.0-rc.46': - dependencies: - js-yaml: 3.14.1 - tslib: 2.7.0 - - '@zkochan/js-yaml@0.0.7': - dependencies: - argparse: 2.0.1 - accepts@1.3.8: dependencies: mime-types: 2.1.35 @@ -3983,110 +1502,18 @@ snapshots: acorn@8.12.1: {} - address@1.2.2: {} - - ansi-colors@4.1.3: {} - - ansi-regex@5.0.1: {} - - ansi-styles@3.2.1: - dependencies: - color-convert: 1.9.3 - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@5.2.0: {} - anymatch@3.1.3: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 - arg@4.1.3: {} - - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - - argparse@2.0.1: {} - array-flatten@1.1.1: {} as-table@1.0.55: dependencies: printable-characters: 1.0.42 - async@3.2.6: {} - - asynckit@0.4.0: {} - - axios@1.7.5: - dependencies: - follow-redirects: 1.15.6 - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - babel-plugin-const-enum@1.2.0(@babel/core@7.25.2): - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-typescript': 7.25.4(@babel/core@7.25.2) - '@babel/traverse': 7.25.4 - transitivePeerDependencies: - - supports-color - - babel-plugin-macros@2.8.0: - dependencies: - '@babel/runtime': 7.25.4 - cosmiconfig: 6.0.0 - resolve: 1.22.8 - - babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.25.2): - dependencies: - '@babel/compat-data': 7.25.4 - '@babel/core': 7.25.2 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - babel-plugin-polyfill-corejs3@0.10.6(@babel/core@7.25.2): - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) - core-js-compat: 3.38.1 - transitivePeerDependencies: - - supports-color - - babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.25.2): - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) - transitivePeerDependencies: - - supports-color - - babel-plugin-transform-typescript-metadata@0.3.2(@babel/core@7.25.2)(@babel/traverse@7.25.4): - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.24.8 - optionalDependencies: - '@babel/traverse': 7.25.4 - - balanced-match@1.0.2: {} - - base64-js@1.5.1: {} - - binary-extensions@2.3.0: {} - - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 + binary-extensions@2.3.0: {} blake3-wasm@2.1.5: {} @@ -4107,33 +1534,12 @@ snapshots: transitivePeerDependencies: - supports-color - brace-expansion@1.1.11: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - braces@3.0.3: dependencies: fill-range: 7.1.1 - browserslist@4.23.3: - dependencies: - caniuse-lite: 1.0.30001653 - electron-to-chromium: 1.5.13 - node-releases: 2.0.18 - update-browserslist-db: 1.1.0(browserslist@4.23.3) - buffer-from@1.1.2: {} - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - bun-types@1.1.26: dependencies: '@types/node': 20.12.14 @@ -4153,10 +1559,6 @@ snapshots: get-intrinsic: 1.2.4 set-function-length: 1.2.2 - callsites@3.1.0: {} - - caniuse-lite@1.0.30001653: {} - capnp-ts@0.7.0: dependencies: debug: 4.3.6 @@ -4164,17 +1566,6 @@ snapshots: transitivePeerDependencies: - supports-color - chalk@2.4.2: - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -4187,45 +1578,8 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - cli-cursor@3.1.0: - dependencies: - restore-cursor: 3.1.0 - - cli-spinners@2.6.1: {} - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - clone@1.0.4: {} - - color-convert@1.9.3: - dependencies: - color-name: 1.1.3 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.3: {} - - color-name@1.1.4: {} - colorette@2.0.20: {} - columnify@1.6.0: - dependencies: - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - concat-map@0.0.1: {} - consola@3.2.3: {} content-disposition@0.5.4: @@ -4234,28 +1588,12 @@ snapshots: content-type@1.0.5: {} - convert-source-map@2.0.0: {} - cookie-signature@1.0.6: {} cookie@0.5.0: {} cookie@0.6.0: {} - core-js-compat@3.38.1: - dependencies: - browserslist: 4.23.3 - - cosmiconfig@6.0.0: - dependencies: - '@types/parse-json': 4.0.2 - import-fresh: 3.3.0 - parse-json: 5.2.0 - path-type: 4.0.0 - yaml: 1.10.2 - - create-require@1.1.1: {} - data-uri-to-buffer@2.0.2: {} date-fns@3.6.0: {} @@ -4268,69 +1606,22 @@ snapshots: dependencies: ms: 2.1.2 - defaults@1.0.4: - dependencies: - clone: 1.0.4 - define-data-property@1.1.4: dependencies: es-define-property: 1.0.0 es-errors: 1.3.0 gopd: 1.0.1 - define-lazy-prop@2.0.0: {} - defu@6.1.4: {} - delayed-stream@1.0.0: {} - depd@2.0.0: {} destroy@1.2.0: {} - detect-port@1.6.1: - dependencies: - address: 1.2.2 - debug: 4.3.6 - transitivePeerDependencies: - - supports-color - - diff-sequences@29.6.3: {} - - diff@4.0.2: {} - - dotenv-expand@11.0.6: - dependencies: - dotenv: 16.4.5 - - dotenv@16.4.5: {} - - duplexer@0.1.2: {} - ee-first@1.1.1: {} - ejs@3.1.10: - dependencies: - jake: 10.9.2 - - electron-to-chromium@1.5.13: {} - - emoji-regex@8.0.0: {} - encodeurl@1.0.2: {} - end-of-stream@1.4.4: - dependencies: - once: 1.4.0 - - enquirer@2.3.6: - dependencies: - ansi-colors: 4.1.3 - - error-ex@1.3.2: - dependencies: - is-arrayish: 0.2.1 - es-define-property@1.0.0: dependencies: get-intrinsic: 1.2.4 @@ -4362,20 +1653,12 @@ snapshots: '@esbuild/win32-ia32': 0.17.19 '@esbuild/win32-x64': 0.17.19 - escalade@3.1.2: {} - escape-html@1.0.3: {} - escape-string-regexp@1.0.5: {} - escape-string-regexp@4.0.0: {} - esprima@4.0.1: {} - estree-walker@0.6.1: {} - esutils@2.0.3: {} - etag@1.8.1: {} exit-hook@2.2.1: {} @@ -4416,26 +1699,6 @@ snapshots: transitivePeerDependencies: - supports-color - fast-glob@3.2.7: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fastq@1.17.1: - dependencies: - reusify: 1.0.4 - - figures@3.2.0: - dependencies: - escape-string-regexp: 1.0.5 - - filelist@1.0.4: - dependencies: - minimatch: 5.1.6 - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -4452,41 +1715,15 @@ snapshots: transitivePeerDependencies: - supports-color - flat@5.0.2: {} - - follow-redirects@1.15.6: {} - - form-data@4.0.0: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - forwarded@0.2.0: {} fresh@0.5.2: {} - front-matter@4.0.2: - dependencies: - js-yaml: 3.14.1 - - fs-constants@1.0.0: {} - - fs-extra@11.2.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - fsevents@2.3.3: optional: true function-bind@1.1.2: {} - gensync@1.0.0-beta.2: {} - - get-caller-file@2.0.5: {} - get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 @@ -4506,18 +1743,10 @@ snapshots: glob-to-regexp@0.4.1: {} - globals@11.12.0: {} - gopd@1.0.1: dependencies: get-intrinsic: 1.2.4 - graceful-fs@4.2.11: {} - - has-flag@3.0.0: {} - - has-flag@4.0.0: {} - has-property-descriptors@1.0.2: dependencies: es-define-property: 1.0.0 @@ -4530,10 +1759,6 @@ snapshots: dependencies: function-bind: 1.1.2 - hosted-git-info@7.0.2: - dependencies: - lru-cache: 10.4.3 - http-errors@2.0.0: dependencies: depd: 2.0.0 @@ -4546,21 +1771,10 @@ snapshots: dependencies: safer-buffer: 2.1.2 - ieee754@1.2.1: {} - - ignore@5.3.2: {} - - import-fresh@3.3.0: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - inherits@2.0.4: {} ipaddr.js@1.9.1: {} - is-arrayish@0.2.1: {} - is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 @@ -4569,101 +1783,24 @@ snapshots: dependencies: hasown: 2.0.2 - is-docker@2.2.1: {} - is-extglob@2.1.1: {} - is-fullwidth-code-point@3.0.0: {} - is-glob@4.0.3: dependencies: is-extglob: 2.1.1 - is-interactive@1.0.0: {} - is-number@7.0.0: {} - is-unicode-supported@0.1.0: {} - - is-wsl@2.2.0: - dependencies: - is-docker: 2.2.1 - - jake@10.9.2: - dependencies: - async: 3.2.6 - chalk: 4.1.2 - filelist: 1.0.4 - minimatch: 3.1.2 - - jest-diff@29.7.0: - dependencies: - chalk: 4.1.2 - diff-sequences: 29.6.3 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-get-type@29.6.3: {} - - js-tokens@4.0.0: {} - - js-yaml@3.14.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - jsesc@0.5.0: {} - - jsesc@2.5.2: {} - - json-parse-even-better-errors@2.3.1: {} - - json5@2.2.3: {} - - jsonc-parser@3.2.0: {} - - jsonfile@6.1.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - lines-and-columns@1.2.4: {} - - lines-and-columns@2.0.3: {} - - lodash.debounce@4.0.8: {} - - log-symbols@4.1.0: - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - - lru-cache@10.4.3: {} - - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 - magic-string@0.25.9: dependencies: sourcemap-codec: 1.4.8 - make-error@1.3.6: {} - media-typer@0.3.0: {} merge-descriptors@1.0.1: {} - merge2@1.4.1: {} - methods@1.1.2: {} - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - mime-db@1.52.0: {} mime-types@2.1.35: @@ -4674,8 +1811,6 @@ snapshots: mime@3.0.0: {} - mimic-fn@2.1.0: {} - miniflare@3.20240821.0: dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -4695,20 +1830,6 @@ snapshots: - supports-color - utf-8-validate - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.11 - - minimatch@5.1.6: - dependencies: - brace-expansion: 2.0.1 - - minimatch@9.0.3: - dependencies: - brace-expansion: 2.0.1 - - minimist@1.2.8: {} - mrmime@2.0.0: {} ms@2.0.0: {} @@ -4729,107 +1850,14 @@ snapshots: node-forge@1.3.1: {} - node-machine-id@1.1.12: {} - - node-releases@2.0.18: {} - normalize-path@3.0.0: {} - npm-package-arg@11.0.1: - dependencies: - hosted-git-info: 7.0.2 - proc-log: 3.0.0 - semver: 7.6.3 - validate-npm-package-name: 5.0.1 - - npm-run-path@4.0.1: - dependencies: - path-key: 3.1.1 - - nx@19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)): - dependencies: - '@napi-rs/wasm-runtime': 0.2.4 - '@nrwl/tao': 19.7.2(@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4))(@swc/core@1.5.29(@swc/helpers@0.5.12)) - '@yarnpkg/lockfile': 1.1.0 - '@yarnpkg/parsers': 3.0.0-rc.46 - '@zkochan/js-yaml': 0.0.7 - axios: 1.7.5 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.6.1 - cliui: 8.0.1 - dotenv: 16.4.5 - dotenv-expand: 11.0.6 - enquirer: 2.3.6 - figures: 3.2.0 - flat: 5.0.2 - front-matter: 4.0.2 - fs-extra: 11.2.0 - ignore: 5.3.2 - jest-diff: 29.7.0 - jsonc-parser: 3.2.0 - lines-and-columns: 2.0.3 - minimatch: 9.0.3 - node-machine-id: 1.1.12 - npm-run-path: 4.0.1 - open: 8.4.2 - ora: 5.3.0 - semver: 7.6.3 - string-width: 4.2.3 - strong-log-transformer: 2.1.0 - tar-stream: 2.2.0 - tmp: 0.2.3 - tsconfig-paths: 4.2.0 - tslib: 2.7.0 - yargs: 17.7.2 - yargs-parser: 21.1.1 - optionalDependencies: - '@nx/nx-darwin-arm64': 19.7.2 - '@nx/nx-darwin-x64': 19.7.2 - '@nx/nx-freebsd-x64': 19.7.2 - '@nx/nx-linux-arm-gnueabihf': 19.7.2 - '@nx/nx-linux-arm64-gnu': 19.7.2 - '@nx/nx-linux-arm64-musl': 19.7.2 - '@nx/nx-linux-x64-gnu': 19.7.2 - '@nx/nx-linux-x64-musl': 19.7.2 - '@nx/nx-win32-arm64-msvc': 19.7.2 - '@nx/nx-win32-x64-msvc': 19.7.2 - '@swc-node/register': 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) - '@swc/core': 1.5.29(@swc/helpers@0.5.12) - transitivePeerDependencies: - - debug - object-inspect@1.13.2: {} on-finished@2.4.1: dependencies: ee-first: 1.1.1 - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - open@8.4.2: - dependencies: - define-lazy-prop: 2.0.0 - is-docker: 2.2.1 - is-wsl: 2.2.0 - - ora@5.3.0: - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.6.1 - is-interactive: 1.0.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - oxc-resolver@1.11.0: optionalDependencies: '@oxc-resolver/binding-darwin-arm64': 1.11.0 @@ -4844,62 +1872,33 @@ snapshots: '@oxc-resolver/binding-win32-arm64-msvc': 1.11.0 '@oxc-resolver/binding-win32-x64-msvc': 1.11.0 - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - parse-json@5.2.0: - dependencies: - '@babel/code-frame': 7.24.7 - error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - parseurl@1.3.3: {} - path-key@3.1.1: {} - path-parse@1.0.7: {} path-to-regexp@0.1.7: {} path-to-regexp@6.2.2: {} - path-type@4.0.0: {} - pathe@1.1.2: {} - picocolors@1.0.1: {} - picomatch@2.3.1: {} pirates@4.0.6: {} prettier@3.3.3: {} - pretty-format@29.7.0: - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.3.1 - printable-characters@1.0.42: {} - proc-log@3.0.0: {} - proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 ipaddr.js: 1.9.1 - proxy-from-env@1.1.0: {} - qs@6.11.0: dependencies: side-channel: 1.0.6 - queue-microtask@1.2.3: {} - range-parser@1.2.1: {} raw-body@2.5.2: @@ -4909,47 +1908,10 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - react-is@18.3.1: {} - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - readdirp@3.6.0: dependencies: picomatch: 2.3.1 - regenerate-unicode-properties@10.1.1: - dependencies: - regenerate: 1.4.2 - - regenerate@1.4.2: {} - - regenerator-runtime@0.14.1: {} - - regenerator-transform@0.15.2: - dependencies: - '@babel/runtime': 7.25.4 - - regexpu-core@5.3.2: - dependencies: - '@babel/regjsgen': 0.8.0 - regenerate: 1.4.2 - regenerate-unicode-properties: 10.1.1 - regjsparser: 0.9.1 - unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.1.0 - - regjsparser@0.9.1: - dependencies: - jsesc: 0.5.0 - - require-directory@2.1.1: {} - - resolve-from@4.0.0: {} - resolve.exports@2.0.2: {} resolve@1.22.8: @@ -4958,13 +1920,6 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - restore-cursor@3.1.0: - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - - reusify@1.0.4: {} - rollup-plugin-inject@3.0.2: dependencies: estree-walker: 0.6.1 @@ -4979,10 +1934,6 @@ snapshots: dependencies: estree-walker: 0.6.1 - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - safe-buffer@5.2.1: {} safer-buffer@2.1.2: {} @@ -4992,10 +1943,6 @@ snapshots: '@types/node-forge': 1.3.11 node-forge: 1.3.1 - semver@6.3.1: {} - - semver@7.6.3: {} - send@0.18.0: dependencies: debug: 2.6.9 @@ -5041,13 +1988,6 @@ snapshots: get-intrinsic: 1.2.4 object-inspect: 1.13.2 - signal-exit@3.0.7: {} - - source-map-support@0.5.19: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 @@ -5057,8 +1997,6 @@ snapshots: sourcemap-codec@1.4.8: {} - sprintf-js@1.0.3: {} - stacktracey@2.1.8: dependencies: as-table: 1.0.55 @@ -5070,84 +2008,16 @@ snapshots: streamsearch@1.1.0: {} - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-bom@3.0.0: {} - - strong-log-transformer@2.1.0: - dependencies: - duplexer: 0.1.2 - minimist: 1.2.8 - through: 2.3.8 - - supports-color@5.5.0: - dependencies: - has-flag: 3.0.0 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - supports-preserve-symlinks-flag@1.0.0: {} - tar-stream@2.2.0: - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.4 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - - through@2.3.8: {} - tmp@0.2.3: {} - to-fast-properties@2.0.0: {} - to-regex-range@5.0.1: dependencies: is-number: 7.0.0 toidentifier@1.0.1: {} - ts-node@10.9.1(@swc/core@1.5.29(@swc/helpers@0.5.12))(@types/node@22.5.0)(typescript@5.5.4): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 22.5.0 - acorn: 8.12.1 - acorn-walk: 8.3.3 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.5.4 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optionalDependencies: - '@swc/core': 1.5.29(@swc/helpers@0.5.12) - - tsconfig-paths@4.2.0: - dependencies: - json5: 2.2.3 - minimist: 1.2.8 - strip-bom: 3.0.0 - tslib@2.7.0: {} type-is@1.6.18: @@ -5176,41 +2046,12 @@ snapshots: pathe: 1.1.2 ufo: 1.5.4 - unicode-canonical-property-names-ecmascript@2.0.0: {} - - unicode-match-property-ecmascript@2.0.0: - dependencies: - unicode-canonical-property-names-ecmascript: 2.0.0 - unicode-property-aliases-ecmascript: 2.1.0 - - unicode-match-property-value-ecmascript@2.1.0: {} - - unicode-property-aliases-ecmascript@2.1.0: {} - - universalify@2.0.1: {} - unpipe@1.0.0: {} - update-browserslist-db@1.1.0(browserslist@4.23.3): - dependencies: - browserslist: 4.23.3 - escalade: 3.1.2 - picocolors: 1.0.1 - - util-deprecate@1.0.2: {} - utils-merge@1.0.1: {} - v8-compile-cache-lib@3.0.1: {} - - validate-npm-package-name@5.0.1: {} - vary@1.1.2: {} - wcwidth@1.0.1: - dependencies: - defaults: 1.0.4 - workerd@1.20240821.1: optionalDependencies: '@cloudflare/workerd-darwin-64': 1.20240821.1 @@ -5247,38 +2088,10 @@ snapshots: - supports-color - utf-8-validate - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrappy@1.0.2: {} - ws@8.18.0: {} xxhash-wasm@1.0.2: {} - y18n@5.0.8: {} - - yallist@3.1.1: {} - - yaml@1.10.2: {} - - yargs-parser@21.1.1: {} - - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.1.2 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - - yn@3.1.1: {} - youch@3.3.3: dependencies: cookie: 0.5.0 diff --git a/scripts/changelog-renderer.cjs b/scripts/changelog-renderer.cjs deleted file mode 100644 index a9513bf9e4b..00000000000 --- a/scripts/changelog-renderer.cjs +++ /dev/null @@ -1,30 +0,0 @@ -// @ts-check -const { default: defaultChangelogRenderer } = require('nx/release/changelog-renderer'); - -const changelogRenderer = async ({ - projectGraph, - commits, - releaseVersion, - project, - entryWhenNoChanges, - changelogRenderOptions, - repoSlug, - conventionalCommitsConfig, - changes, -}) => { - const defaultChangelog = await defaultChangelogRenderer({ - projectGraph, - commits, - releaseVersion, - project, - entryWhenNoChanges, - changelogRenderOptions, - repoSlug, - conventionalCommitsConfig, - changes, - }); - // Rename the authors section title - return defaultChangelog.replace('❤️ Thank You', 'Contributors'); -}; - -module.exports = changelogRenderer; diff --git a/scripts/release.js b/scripts/release.js deleted file mode 100644 index 61ac79314cd..00000000000 --- a/scripts/release.js +++ /dev/null @@ -1,13 +0,0 @@ -import { releaseVersion, releaseChangelog, releasePublish } from 'nx/release/index.js'; - -const dryRun = false; -const verbose = true; - -let { projectsVersionData } = await releaseVersion({ dryRun, verbose }); - -await releaseChangelog({ dryRun, verbose, versionData: projectsVersionData }); - -let statusCode = await releasePublish({ dryRun, verbose }); - -// Force exit because it's connected to the Nx daemon -process.exit(0); From 28ae84fe674819c0e63ad4bec6c6347cc470f7bf Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 11 Sep 2024 17:13:40 -0700 Subject: [PATCH 453/730] Add release script --- packages/file-storage/package.json | 3 +- packages/form-data-parser/package.json | 3 +- packages/headers/package.json | 3 +- packages/lazy-file/package.json | 3 +- packages/multipart-parser/package.json | 3 +- packages/node-fetch-server/package.json | 3 +- pnpm-lock.yaml | 32 +++++++++++ pnpm-workspace.yaml | 1 + scripts/package.json | 10 ++++ scripts/release.ts | 75 +++++++++++++++++++++++++ scripts/tsconfig.json | 8 +++ 11 files changed, 138 insertions(+), 6 deletions(-) create mode 100644 scripts/package.json create mode 100644 scripts/release.ts create mode 100644 scripts/tsconfig.json diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index ac61b96b6a8..48298c0ca44 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -31,7 +31,8 @@ "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build" + "prepare": "pnpm run build", + "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" }, "keywords": [ "file", diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index c28d2d27695..e4030f6da4b 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -29,7 +29,8 @@ "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build" + "prepare": "pnpm run build", + "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" }, "keywords": [ "form-data", diff --git a/packages/headers/package.json b/packages/headers/package.json index f284bba1461..28d1d680091 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -26,7 +26,8 @@ "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build" + "prepare": "pnpm run build", + "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" }, "keywords": [ "fetch", diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index ad618562b34..98c5080e56a 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -30,7 +30,8 @@ "scripts": { "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build" + "prepare": "pnpm run build", + "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" }, "keywords": [ "file", diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 1d6398e8425..87d302bb7d0 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -34,7 +34,8 @@ "bench:node": "node --import @swc-node/register/esm-register ./bench/runner.ts", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build" + "prepare": "pnpm run build", + "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" }, "keywords": [ "multipart", diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 39cd4e0757d..a3d2bb9a202 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -27,7 +27,8 @@ "bench": "bash ./bench/runner.sh", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build" + "prepare": "pnpm run build", + "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" }, "keywords": [ "http", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 391f287880e..d9b47fc68d5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -166,6 +166,19 @@ importers: specifier: ^4.17.21 version: 4.17.21 + scripts: + dependencies: + '@types/semver': + specifier: ^7.5.8 + version: 7.5.8 + semver: + specifier: ^7.6.3 + version: 7.6.3 + devDependencies: + '@types/node': + specifier: ^22.5.4 + version: 22.5.4 + packages: '@cloudflare/kv-asset-handler@0.3.4': @@ -572,12 +585,18 @@ packages: '@types/node@22.5.0': resolution: {integrity: sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==} + '@types/node@22.5.4': + resolution: {integrity: sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==} + '@types/qs@6.9.15': resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + '@types/semver@7.5.8': + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + '@types/send@0.17.4': resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} @@ -1018,6 +1037,11 @@ packages: resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} engines: {node: '>=10'} + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + send@0.18.0: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} engines: {node: '>= 0.8.0'} @@ -1470,10 +1494,16 @@ snapshots: dependencies: undici-types: 6.19.8 + '@types/node@22.5.4': + dependencies: + undici-types: 6.19.8 + '@types/qs@6.9.15': {} '@types/range-parser@1.2.7': {} + '@types/semver@7.5.8': {} + '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 @@ -1943,6 +1973,8 @@ snapshots: '@types/node-forge': 1.3.11 node-forge: 1.3.1 + semver@7.6.3: {} + send@0.18.0: dependencies: debug: 2.6.9 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 5845e2430d5..3b843b4e575 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,3 +3,4 @@ packages: - packages/multipart-parser/bench - packages/multipart-parser/examples/* - packages/node-fetch-server/bench + - scripts diff --git a/scripts/package.json b/scripts/package.json new file mode 100644 index 00000000000..18d638c99f8 --- /dev/null +++ b/scripts/package.json @@ -0,0 +1,10 @@ +{ + "name": "remix-the-scripts", + "private": true, + "type": "module", + "dependencies": { + "@types/node": "^22.5.4", + "@types/semver": "^7.5.8", + "semver": "^7.6.3" + } +} diff --git a/scripts/release.ts b/scripts/release.ts new file mode 100644 index 00000000000..3c407968383 --- /dev/null +++ b/scripts/release.ts @@ -0,0 +1,75 @@ +import * as cp from 'node:child_process'; +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import * as process from 'node:process'; + +import * as semver from 'semver'; + +const __dirname = path.dirname(new URL(import.meta.url).pathname); + +const packageName = process.env.npm_package_name; +const packageVersion = process.env.npm_package_version; +const releaseType = process.argv[2]; + +if (packageName === undefined || packageVersion === undefined || releaseType === undefined) { + console.error('Usage: npm run release '); + process.exit(1); +} + +let newVersion = semver.inc(packageVersion, releaseType as semver.ReleaseType); +let [_packageScope, packageNameWithoutScope] = packageName.split('/'); +let packageDir = path.resolve(__dirname, '..', 'packages', packageNameWithoutScope); + +// Ensure git staging area is clean +let status = cp.execSync('git status --porcelain').toString(); +if (status !== '') { + console.error('Git staging area is not clean'); + process.exit(1); +} + +console.log(`Releasing ${packageNameWithoutScope}@${newVersion} ...`); +console.log(); + +function execWithLog(command: string) { + console.log(`$ ${command}`); + cp.execSync(command, { stdio: 'inherit' }); +} + +// Update package.json +let packageJsonPath = path.relative(process.cwd(), path.join(packageDir, 'package.json')); +let packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); +packageJson.version = newVersion; +fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); +execWithLog(`git add ${packageJsonPath}`); + +// Update CHANGELOG.md +let changelogPath = path.relative(process.cwd(), path.join(packageDir, 'CHANGELOG.md')); +let changelog = fs.readFileSync(changelogPath, 'utf-8'); +let match = /^## HEAD\n/m.exec(changelog); +if (match) { + let [today] = new Date().toISOString().split('T'); + + changelog = + changelog.slice(0, match.index) + + `## v${newVersion} (${today})\n` + + changelog.slice(match.index + match[0].length); + + fs.writeFileSync(changelogPath, changelog); + execWithLog(`git add ${changelogPath}`); +} + +// Update jsr.json +let jsrJsonPath = path.relative(process.cwd(), path.join(packageDir, 'jsr.json')); +if (fs.existsSync(jsrJsonPath)) { + let jsrJson = JSON.parse(fs.readFileSync(jsrJsonPath, 'utf-8')); + jsrJson.version = newVersion; + fs.writeFileSync(jsrJsonPath, JSON.stringify(jsrJson, null, 2) + '\n'); + execWithLog(`git add ${jsrJsonPath}`); +} + +// Commit and tag +let tag = `${packageNameWithoutScope}@${newVersion}`; +execWithLog(`git commit -m "Release ${tag}"`); +execWithLog(`git tag ${tag}`); + +console.log(); diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json new file mode 100644 index 00000000000..d8aaef54f9d --- /dev/null +++ b/scripts/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "lib": ["DOM", "ES2020"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true + } +} From 44163f09c76f7a68f1908b55fa7e39af6d7d2de2 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 11 Sep 2024 18:06:32 -0700 Subject: [PATCH 454/730] Release lazy-file@3.2.0 --- packages/lazy-file/CHANGELOG.md | 2 +- packages/lazy-file/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/lazy-file/CHANGELOG.md b/packages/lazy-file/CHANGELOG.md index f1e96de9917..1584ba29af0 100644 --- a/packages/lazy-file/CHANGELOG.md +++ b/packages/lazy-file/CHANGELOG.md @@ -1,4 +1,4 @@ -## HEAD +## v3.2.0 (2024-09-12) - Export `OpenFileOptions` from `lazy-file/fs` diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index 98c5080e56a..430b66d2fdf 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/lazy-file", - "version": "3.1.0", + "version": "3.2.0", "description": "Lazy, streaming files for JavaScript", "author": "Michael Jackson ", "repository": { From a7afb9165c0946e65f79b2990a4db1b59b7819ab Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 12 Sep 2024 15:25:26 -0700 Subject: [PATCH 455/730] Initial commit of fetch-proxy --- packages/fetch-proxy/CHANGELOG.md | 3 + packages/fetch-proxy/LICENSE | 21 +++ packages/fetch-proxy/README.md | 51 ++++++ packages/fetch-proxy/package.json | 40 +++++ packages/fetch-proxy/src/fetch-proxy.ts | 1 + .../fetch-proxy/src/lib/fetch-proxy.spec.ts | 148 ++++++++++++++++++ packages/fetch-proxy/src/lib/fetch-proxy.ts | 113 +++++++++++++ packages/fetch-proxy/tsconfig.json | 8 + packages/fetch-proxy/tsconfig.lib.json | 9 ++ packages/fetch-proxy/tsconfig.spec.json | 7 + packages/node-fetch-server/README.md | 4 + 11 files changed, 405 insertions(+) create mode 100644 packages/fetch-proxy/CHANGELOG.md create mode 100644 packages/fetch-proxy/LICENSE create mode 100644 packages/fetch-proxy/README.md create mode 100644 packages/fetch-proxy/package.json create mode 100644 packages/fetch-proxy/src/fetch-proxy.ts create mode 100644 packages/fetch-proxy/src/lib/fetch-proxy.spec.ts create mode 100644 packages/fetch-proxy/src/lib/fetch-proxy.ts create mode 100644 packages/fetch-proxy/tsconfig.json create mode 100644 packages/fetch-proxy/tsconfig.lib.json create mode 100644 packages/fetch-proxy/tsconfig.spec.json diff --git a/packages/fetch-proxy/CHANGELOG.md b/packages/fetch-proxy/CHANGELOG.md new file mode 100644 index 00000000000..d4a40e60478 --- /dev/null +++ b/packages/fetch-proxy/CHANGELOG.md @@ -0,0 +1,3 @@ +## HEAD + +- Initial release diff --git a/packages/fetch-proxy/LICENSE b/packages/fetch-proxy/LICENSE new file mode 100644 index 00000000000..717984c0442 --- /dev/null +++ b/packages/fetch-proxy/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Michael Jackson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/fetch-proxy/README.md b/packages/fetch-proxy/README.md new file mode 100644 index 00000000000..fa5e5cbcada --- /dev/null +++ b/packages/fetch-proxy/README.md @@ -0,0 +1,51 @@ +# fetch-proxy + +`fetch-proxy` is an HTTP proxy for the [JavaScript Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). + +In the context of servers, an HTTP proxy server is a server that forwards all requests it receives to another server and returns the responses it receives. When you think about it this way, a [`fetch` function](https://developer.mozilla.org/en-US/docs/Web/API/Window/fetch) is like a mini proxy server sitting right there in your code. You send it requests, it goes and talks to some other server, and it gives you back the response it received. + +`fetch-proxy` allows you to easily create `fetch` functions that act as proxies to "target" servers. + +## Features + +- Built on the standard [JavaScript Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) +- Supports rewriting `Set-Cookie` headers received from target server +- Supports `X-Forwarded-Proto` and `X-Forwarded-Host` headers +- Supports custom `fetch` implementations + +## Installation + +Install from [npm](https://www.npmjs.com/): + +```sh +npm i @mjackson/fetch-proxy +``` + +## Usage + +```ts +import { createFetchProxy } from '@mjackson/fetch-proxy'; + +// Create a proxy that sends all requests through to remix.run +let proxy = createFetchProxy('https://remix.run'); + +// This fetch handler is probably running as part of your server somewhere... +function handleFetch(request: Request): Promise { + return proxy(request); +} + +// Test it out by manually throwing a Request at it +let response = await handleFetch(new Request('https://shopify.com')); + +let text = await response.text(); +let title = text.match(/([^<]+)<\/title>/)[1]; +assert(title.includes('Remix')); +``` + +## Related Packages + +- [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server) - Build HTTP servers for Node.js using the web fetch API + +## License + +See [LICENSE](https://github.com/mjackson/remix-the-web/blob/main/LICENSE) diff --git a/packages/fetch-proxy/package.json b/packages/fetch-proxy/package.json new file mode 100644 index 00000000000..1df0553612f --- /dev/null +++ b/packages/fetch-proxy/package.json @@ -0,0 +1,40 @@ +{ + "name": "@mjackson/fetch-proxy", + "version": "0.0.0", + "description": "An HTTP proxy for the web Fetch API", + "author": "Michael Jackson <mjijackson@gmail.com>", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/mjackson/remix-the-web.git", + "directory": "packages/fetch-proxy" + }, + "homepage": "https://github.com/mjackson/remix-the-web/tree/main/packages/fetch-proxy#readme", + "files": [ + "dist", + "LICENSE", + "README.md" + ], + "type": "module", + "exports": { + ".": "./dist/fetch-proxy.js", + "./package.json": "./package.json" + }, + "dependencies": { + "@mjackson/headers": "workspace:^" + }, + "devDependencies": { + "@types/node": "^20.14.10" + }, + "scripts": { + "build": "tsc --outDir dist --project tsconfig.lib.json", + "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", + "prepare": "pnpm run build", + "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" + }, + "keywords": [ + "fetch", + "http", + "proxy" + ] +} diff --git a/packages/fetch-proxy/src/fetch-proxy.ts b/packages/fetch-proxy/src/fetch-proxy.ts new file mode 100644 index 00000000000..877a9decfd9 --- /dev/null +++ b/packages/fetch-proxy/src/fetch-proxy.ts @@ -0,0 +1 @@ +export { type FetchProxyOptions, type FetchProxy, createFetchProxy } from './lib/fetch-proxy.js'; diff --git a/packages/fetch-proxy/src/lib/fetch-proxy.spec.ts b/packages/fetch-proxy/src/lib/fetch-proxy.spec.ts new file mode 100644 index 00000000000..c87d38e78d9 --- /dev/null +++ b/packages/fetch-proxy/src/lib/fetch-proxy.spec.ts @@ -0,0 +1,148 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { FetchProxyOptions, createFetchProxy } from './fetch-proxy.js'; + +async function runProxy<ResponseType extends Response>( + request: Request, + target: string | URL, + options?: FetchProxyOptions, +): Promise<{ request: Request; response: ResponseType }> { + let outgoingRequest: Request; + let proxy = createFetchProxy(target, { + ...options, + async fetch(input, init) { + outgoingRequest = new Request(input, init); + return options?.fetch?.(input, init) ?? new Response(); + }, + }); + + let proxyResponse = (await proxy(request)) as ResponseType; + + assert.ok(outgoingRequest!); + + return { + request: outgoingRequest, + response: proxyResponse, + }; +} + +describe('fetch proxy', () => { + it('appends the request URL pathname + search to the target URL', async () => { + let { request: request1 } = await runProxy( + new Request('http://shopify.com'), + 'https://remix.run:3000/rsc', + ); + + assert.equal(request1.url, 'https://remix.run:3000/rsc'); + + let { request: request2 } = await runProxy( + new Request('http://shopify.com/?q=remix'), + 'https://remix.run:3000/rsc', + ); + + assert.equal(request2.url, 'https://remix.run:3000/rsc?q=remix'); + + let { request: request3 } = await runProxy( + new Request('http://shopify.com/search?q=remix'), + 'https://remix.run:3000/', + ); + + assert.equal(request3.url, 'https://remix.run:3000/search?q=remix'); + + let { request: request4 } = await runProxy( + new Request('http://shopify.com/search?q=remix'), + 'https://remix.run:3000/rsc', + ); + + assert.equal(request4.url, 'https://remix.run:3000/rsc/search?q=remix'); + }); + + it('forwards request method, headers, and body', async () => { + let { request } = await runProxy( + new Request('http://shopify.com/search?q=remix', { + method: 'POST', + headers: { + 'Content-Type': 'text/plain', + }, + body: 'hello', + }), + 'https://remix.run:3000/rsc', + ); + + assert.equal(request.method, 'POST'); + assert.equal(request.headers.get('Content-Type'), 'text/plain'); + assert.equal(await request.text(), 'hello'); + }); + + it('does not append X-Forwarded-Proto and X-Forwarded-Host headers by default', async () => { + let { request } = await runProxy( + new Request('http://shopify.com:8080/search?q=remix'), + 'https://remix.run:3000/rsc', + ); + + assert.equal(request.headers.get('X-Forwarded-Proto'), null); + assert.equal(request.headers.get('X-Forwarded-Host'), null); + }); + + it('appends X-Forwarded-Proto and X-Forwarded-Host headers when desired', async () => { + let { request } = await runProxy( + new Request('http://shopify.com:8080/search?q=remix'), + 'https://remix.run:3000/rsc', + { + xForwardedHeaders: true, + }, + ); + + assert.equal(request.headers.get('X-Forwarded-Proto'), 'http'); + assert.equal(request.headers.get('X-Forwarded-Host'), 'shopify.com:8080'); + }); + + it('rewrites cookie domain and path', async () => { + let { response } = await runProxy( + new Request('http://shopify.com/search?q=remix'), + 'https://remix.run:3000/rsc', + { + async fetch() { + return new Response(null, { + headers: [ + ['Set-Cookie', 'name=value; Domain=remix.run:3000; Path=/rsc/search'], + ['Set-Cookie', 'name2=value2; Domain=remix.run:3000; Path=/rsc'], + ], + }); + }, + }, + ); + + let setCookie = response.headers.getSetCookie(); + assert.ok(setCookie); + assert.equal(setCookie.length, 2); + assert.equal(setCookie[0], 'name=value; Domain=shopify.com; Path=/search'); + assert.equal(setCookie[1], 'name2=value2; Domain=shopify.com; Path=/'); + }); + + it('does not rewrite cookie domain and path when opting-out', async () => { + let { response } = await runProxy( + new Request('http://shopify.com/?q=remix'), + 'https://remix.run:3000/rsc', + { + rewriteCookieDomain: false, + rewriteCookiePath: false, + async fetch() { + return new Response(null, { + headers: [ + ['Set-Cookie', 'name=value; Domain=remix.run:3000; Path=/rsc/search'], + ['Set-Cookie', 'name2=value2; Domain=remix.run:3000; Path=/rsc'], + ], + }); + }, + }, + ); + + let setCookie = response.headers.getSetCookie(); + assert.ok(setCookie); + assert.equal(setCookie.length, 2); + assert.equal(setCookie[0], 'name=value; Domain=remix.run:3000; Path=/rsc/search'); + assert.equal(setCookie[1], 'name2=value2; Domain=remix.run:3000; Path=/rsc'); + }); +}); diff --git a/packages/fetch-proxy/src/lib/fetch-proxy.ts b/packages/fetch-proxy/src/lib/fetch-proxy.ts new file mode 100644 index 00000000000..59bea7a4197 --- /dev/null +++ b/packages/fetch-proxy/src/lib/fetch-proxy.ts @@ -0,0 +1,113 @@ +import { SetCookie } from '@mjackson/headers'; + +export interface FetchProxyOptions { + /** + * The `fetch` function to use for the actual fetch. Defaults to the global `fetch` function. + */ + fetch?: typeof globalThis.fetch; + /** + * Set `false` to prevent the `Domain` attribute of `Set-Cookie` headers from being rewritten. By + * default the domain will be rewritten to the domain of the incoming request. + */ + rewriteCookieDomain?: boolean; + /** + * Set `false` to prevent the `Path` attribute of `Set-Cookie` headers from being rewritten. By + * default the portion of the pathname that matches the proxy target's pathname will be removed. + */ + rewriteCookiePath?: boolean; + /** + * Set `true` to add `X-Forwarded-Proto` and `X-Forwarded-Host` headers to the proxied request. + * Defaults to `false`. + */ + xForwardedHeaders?: boolean; +} + +/** + * A [`fetch` function](https://developer.mozilla.org/en-US/docs/Web/API/Window/fetch) + * that forwards requests to another server. + */ +export interface FetchProxy { + (input: URL | RequestInfo, init?: RequestInit): Promise<Response>; +} + +/** + * Creates a `fetch` function that forwards requests to another server. + * @param target The URL of the server to proxy requests to + * @param options Options to customize the behavior of the proxy + * @returns A fetch function that forwards requests to the target server + */ +export function createFetchProxy(target: string | URL, options?: FetchProxyOptions): FetchProxy { + let localFetch = options?.fetch ?? globalThis.fetch; + let rewriteCookieDomain = options?.rewriteCookieDomain ?? true; + let rewriteCookiePath = options?.rewriteCookiePath ?? true; + let xForwardedHeaders = options?.xForwardedHeaders ?? false; + + let targetUrl = new URL(target); + if (targetUrl.pathname.endsWith('/')) { + targetUrl.pathname = targetUrl.pathname.replace(/\/+$/, ''); + } + + return async (input: URL | RequestInfo, init?: RequestInit) => { + let incomingRequest = new Request(input, init); + let incomingUrl = new URL(incomingRequest.url); + + let proxyUrl = new URL(incomingUrl.search, targetUrl); + if (incomingUrl.pathname !== '/') { + proxyUrl.pathname = + proxyUrl.pathname === '/' ? incomingUrl.pathname : proxyUrl.pathname + incomingUrl.pathname; + } + + let proxyHeaders = new Headers(incomingRequest.headers); + if (xForwardedHeaders) { + proxyHeaders.append('X-Forwarded-Proto', incomingUrl.protocol.replace(/:$/, '')); + proxyHeaders.append('X-Forwarded-Host', incomingUrl.host); + } + + let proxyInit: RequestInit = { + method: incomingRequest.method, + headers: proxyHeaders, + }; + if (incomingRequest.method !== 'GET' && incomingRequest.method !== 'HEAD') { + proxyInit.body = incomingRequest.body; + + // init.duplex = 'half' must be set when body is a ReadableStream, and Node follows the spec. + // However, this property is not defined in the TypeScript types for RequestInit, so we have + // to cast it here in order to set it without a type error. + // See https://fetch.spec.whatwg.org/#dom-requestinit-duplex + (proxyInit as { duplex: 'half' }).duplex = 'half'; + } + + let targetResponse = await localFetch(proxyUrl, proxyInit); + let responseHeaders = new Headers(targetResponse.headers); + + if (responseHeaders.has('Set-Cookie')) { + let setCookie = responseHeaders.getSetCookie(); + + responseHeaders.delete('Set-Cookie'); + + for (let cookie of setCookie) { + let header = new SetCookie(cookie); + + if (rewriteCookieDomain && header.domain) { + header.domain = incomingUrl.host; + } + + if (rewriteCookiePath && header.path) { + if (header.path.startsWith(targetUrl.pathname + '/')) { + header.path = header.path.slice(targetUrl.pathname.length); + } else if (header.path === targetUrl.pathname) { + header.path = '/'; + } + } + + responseHeaders.append('Set-Cookie', header.toString()); + } + } + + return new Response(targetResponse.body, { + status: targetResponse.status, + statusText: targetResponse.statusText, + headers: responseHeaders, + }); + }; +} diff --git a/packages/fetch-proxy/tsconfig.json b/packages/fetch-proxy/tsconfig.json new file mode 100644 index 00000000000..d8aaef54f9d --- /dev/null +++ b/packages/fetch-proxy/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "lib": ["DOM", "ES2020"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true + } +} diff --git a/packages/fetch-proxy/tsconfig.lib.json b/packages/fetch-proxy/tsconfig.lib.json new file mode 100644 index 00000000000..8e712f7d6c8 --- /dev/null +++ b/packages/fetch-proxy/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.spec.ts"], + "compilerOptions": { + "composite": true, + "rootDir": "src" + } +} diff --git a/packages/fetch-proxy/tsconfig.spec.json b/packages/fetch-proxy/tsconfig.spec.json new file mode 100644 index 00000000000..456f4c46cca --- /dev/null +++ b/packages/fetch-proxy/tsconfig.spec.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.spec.ts"], + "compilerOptions": { + "types": ["node"] + } +} diff --git a/packages/node-fetch-server/README.md b/packages/node-fetch-server/README.md index 3771c05f78d..517ccfaa8c4 100644 --- a/packages/node-fetch-server/README.md +++ b/packages/node-fetch-server/README.md @@ -68,6 +68,10 @@ let handler: FetchHandler = (request, client) => { }; ``` +## Related Packages + +- [`fetch-proxy`](https://github.com/mjackson/remix-the-web/tree/main/packages/fetch-proxy) - Build HTTP proxy servers using the web fetch API + ## Benchmark A basic "hello world" benchmark shows `node-fetch-server` introduces considerable overhead on top of a vanilla `node:http` server. However, it is still able to serve more requests per second (and has higher overall throughput) than Express v4, so the slowdown should be acceptable for most applications. From a8c4e23d0b7ea5f4fc5b474fa4e25e05d399c597 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 12 Sep 2024 15:25:44 -0700 Subject: [PATCH 456/730] Release fetch-proxy@0.1.0 --- packages/fetch-proxy/CHANGELOG.md | 2 +- packages/fetch-proxy/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/fetch-proxy/CHANGELOG.md b/packages/fetch-proxy/CHANGELOG.md index d4a40e60478..0e0e9d12f97 100644 --- a/packages/fetch-proxy/CHANGELOG.md +++ b/packages/fetch-proxy/CHANGELOG.md @@ -1,3 +1,3 @@ -## HEAD +## v0.1.0 (2024-09-12) - Initial release diff --git a/packages/fetch-proxy/package.json b/packages/fetch-proxy/package.json index 1df0553612f..3addac25c7b 100644 --- a/packages/fetch-proxy/package.json +++ b/packages/fetch-proxy/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/fetch-proxy", - "version": "0.0.0", + "version": "0.1.0", "description": "An HTTP proxy for the web Fetch API", "author": "Michael Jackson <mjijackson@gmail.com>", "license": "MIT", From 3f9da7f0001d4b49a201a2f6ffffbbee8b29da1f Mon Sep 17 00:00:00 2001 From: Lennart Hildebrandt <lennart.hildebrandt@wps.de> Date: Sat, 14 Sep 2024 12:40:25 +0200 Subject: [PATCH 457/730] Allow returning strings from the upload handler --- .../src/lib/form-data.spec.ts | 23 +++++++++++++++++++ .../form-data-parser/src/lib/form-data.ts | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/form-data-parser/src/lib/form-data.spec.ts b/packages/form-data-parser/src/lib/form-data.spec.ts index 49b60490795..e9464c6c18c 100644 --- a/packages/form-data-parser/src/lib/form-data.spec.ts +++ b/packages/form-data-parser/src/lib/form-data.spec.ts @@ -99,4 +99,27 @@ describe('parseFormData', () => { assert.equal(formData.get('file'), null); }); + + it('allows returning strings from the upload handler', async () => { + let request = new Request('http://localhost:8080', { + method: 'POST', + headers: { + 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW', + }, + body: [ + '------WebKitFormBoundary7MA4YWxkTrZu0gW', + 'Content-Disposition: form-data; name="file"; filename="example.txt"', + 'Content-Type: text/plain', + '', + 'This is an example file.', + '------WebKitFormBoundary7MA4YWxkTrZu0gW--', + ].join('\r\n'), + }); + + let formData = await parseFormData(request, (fileUpload) => { + return fileUpload.text(); + }); + + assert.equal(formData.get('file'), 'This is an example file.'); + }); }); diff --git a/packages/form-data-parser/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts index 560d83e7162..2651a0096cf 100644 --- a/packages/form-data-parser/src/lib/form-data.ts +++ b/packages/form-data-parser/src/lib/form-data.ts @@ -66,7 +66,7 @@ export class FileUpload implements File { * A function used for handling file uploads. */ export interface FileUploadHandler { - (file: FileUpload): void | null | File | Promise<void | null | File>; + (file: FileUpload): void | null | string | File | Promise<void | null | string | File>; } async function defaultFileUploadHandler(file: FileUpload): Promise<File> { From f053c79393d391c28318a804232c150c23c5f483 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 17 Oct 2024 11:54:57 -0700 Subject: [PATCH 458/730] Move test utils --- packages/multipart-parser/src/lib/multipart.node.spec.ts | 5 +++-- packages/multipart-parser/src/lib/multipart.spec.ts | 3 ++- packages/multipart-parser/{src => }/test/utils.node.ts | 0 packages/multipart-parser/{src => }/test/utils.ts | 0 packages/multipart-parser/tsconfig.lib.json | 2 +- packages/multipart-parser/tsconfig.spec.json | 2 +- 6 files changed, 7 insertions(+), 5 deletions(-) rename packages/multipart-parser/{src => }/test/utils.node.ts (100%) rename packages/multipart-parser/{src => }/test/utils.ts (100%) diff --git a/packages/multipart-parser/src/lib/multipart.node.spec.ts b/packages/multipart-parser/src/lib/multipart.node.spec.ts index 20293db5e92..490d80fc01e 100644 --- a/packages/multipart-parser/src/lib/multipart.node.spec.ts +++ b/packages/multipart-parser/src/lib/multipart.node.spec.ts @@ -1,9 +1,10 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; +import { getRandomBytes } from '../../test/utils.js'; +import { createMultipartMockRequest } from '../../test/utils.node.js'; + import { parseMultipartRequest } from './multipart.node.js'; -import { getRandomBytes } from '../test/utils.js'; -import { createMultipartMockRequest } from '../test/utils.node.js'; describe('parseMultipartRequest (node)', () => { let boundary = 'boundary123'; diff --git a/packages/multipart-parser/src/lib/multipart.spec.ts b/packages/multipart-parser/src/lib/multipart.spec.ts index b0aa85d5799..61a400fb5e8 100644 --- a/packages/multipart-parser/src/lib/multipart.spec.ts +++ b/packages/multipart-parser/src/lib/multipart.spec.ts @@ -1,13 +1,14 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; +import { createMockRequest, createMultipartMockRequest, getRandomBytes } from '../../test/utils.js'; + import { isMultipartRequest, parseMultipartRequest, MultipartParseError, getMultipartBoundary, } from './multipart.js'; -import { createMockRequest, createMultipartMockRequest, getRandomBytes } from '../test/utils.js'; const CRLF = '\r\n'; diff --git a/packages/multipart-parser/src/test/utils.node.ts b/packages/multipart-parser/test/utils.node.ts similarity index 100% rename from packages/multipart-parser/src/test/utils.node.ts rename to packages/multipart-parser/test/utils.node.ts diff --git a/packages/multipart-parser/src/test/utils.ts b/packages/multipart-parser/test/utils.ts similarity index 100% rename from packages/multipart-parser/src/test/utils.ts rename to packages/multipart-parser/test/utils.ts diff --git a/packages/multipart-parser/tsconfig.lib.json b/packages/multipart-parser/tsconfig.lib.json index c9819aa7ed5..8e712f7d6c8 100644 --- a/packages/multipart-parser/tsconfig.lib.json +++ b/packages/multipart-parser/tsconfig.lib.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts", "src/test/**/*.ts"], + "exclude": ["src/**/*.spec.ts"], "compilerOptions": { "composite": true, "rootDir": "src" diff --git a/packages/multipart-parser/tsconfig.spec.json b/packages/multipart-parser/tsconfig.spec.json index 0dcc65f3ce6..547e6dabbd4 100644 --- a/packages/multipart-parser/tsconfig.spec.json +++ b/packages/multipart-parser/tsconfig.spec.json @@ -1,6 +1,6 @@ { "extends": "./tsconfig.json", - "include": ["src/**/*.spec.ts", "src/test/**/*.ts"], + "include": ["src/**/*.spec.ts", "test/**/*.ts"], "compilerOptions": { "composite": true, "types": ["node"] From f57915564928bd096fafbe920c9a42a8f1a4e0bf Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 17 Oct 2024 11:55:04 -0700 Subject: [PATCH 459/730] Ran pnpm i --- pnpm-lock.yaml | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d9b47fc68d5..134572b057d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,6 +18,16 @@ importers: specifier: ^5.5.4 version: 5.5.4 + packages/fetch-proxy: + dependencies: + '@mjackson/headers': + specifier: workspace:^ + version: link:../headers + devDependencies: + '@types/node': + specifier: ^20.14.10 + version: 20.16.1 + packages/file-storage: dependencies: '@mjackson/lazy-file': @@ -168,16 +178,15 @@ importers: scripts: dependencies: + '@types/node': + specifier: ^22.5.4 + version: 22.5.4 '@types/semver': specifier: ^7.5.8 version: 7.5.8 semver: specifier: ^7.6.3 version: 7.6.3 - devDependencies: - '@types/node': - specifier: ^22.5.4 - version: 22.5.4 packages: @@ -1446,7 +1455,7 @@ snapshots: '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.5.0 + '@types/node': 22.5.4 '@types/bun@1.1.8': dependencies: @@ -1454,15 +1463,15 @@ snapshots: '@types/busboy@1.5.4': dependencies: - '@types/node': 22.5.0 + '@types/node': 22.5.4 '@types/connect@3.4.38': dependencies: - '@types/node': 22.5.0 + '@types/node': 22.5.4 '@types/express-serve-static-core@4.19.5': dependencies: - '@types/node': 22.5.0 + '@types/node': 22.5.4 '@types/qs': 6.9.15 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -1480,7 +1489,7 @@ snapshots: '@types/node-forge@1.3.11': dependencies: - '@types/node': 22.5.0 + '@types/node': 22.5.4 '@types/node@20.12.14': dependencies: @@ -1507,19 +1516,19 @@ snapshots: '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.5.0 + '@types/node': 22.5.4 '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 22.5.0 + '@types/node': 22.5.4 '@types/send': 0.17.4 '@types/tmp@0.2.6': {} '@types/ws@8.5.12': dependencies: - '@types/node': 22.5.0 + '@types/node': 22.5.4 accepts@1.3.8: dependencies: From 7dd01c5708f7e845e4b8a80b8fd317a52a0beb5e Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 12 Sep 2024 16:01:56 -0700 Subject: [PATCH 460/730] Small simplification --- packages/fetch-proxy/src/lib/fetch-proxy.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/fetch-proxy/src/lib/fetch-proxy.spec.ts b/packages/fetch-proxy/src/lib/fetch-proxy.spec.ts index c87d38e78d9..29c56d173ec 100644 --- a/packages/fetch-proxy/src/lib/fetch-proxy.spec.ts +++ b/packages/fetch-proxy/src/lib/fetch-proxy.spec.ts @@ -3,11 +3,11 @@ import { describe, it } from 'node:test'; import { FetchProxyOptions, createFetchProxy } from './fetch-proxy.js'; -async function runProxy<ResponseType extends Response>( +async function runProxy( request: Request, target: string | URL, options?: FetchProxyOptions, -): Promise<{ request: Request; response: ResponseType }> { +): Promise<{ request: Request; response: Response }> { let outgoingRequest: Request; let proxy = createFetchProxy(target, { ...options, @@ -17,7 +17,7 @@ async function runProxy<ResponseType extends Response>( }, }); - let proxyResponse = (await proxy(request)) as ResponseType; + let proxyResponse = await proxy(request); assert.ok(outgoingRequest!); From fab5a1b8e02ab1860a1046ad2b9c54159027ec80 Mon Sep 17 00:00:00 2001 From: Jacob Ebey <jacob.ebey@live.com> Date: Wed, 13 Nov 2024 13:46:32 -0800 Subject: [PATCH 461/730] feat: add tsup to produce CJS and ESM output modules --- package.json | 3 +- packages/fetch-proxy/package.json | 27 +- packages/fetch-proxy/tsup.config.ts | 9 + packages/file-storage/package.json | 65 +- packages/file-storage/tsup.config.ts | 20 + packages/form-data-parser/package.json | 27 +- packages/form-data-parser/tsup.config.ts | 9 + packages/headers/package.json | 27 +- packages/headers/tsup.config.ts | 9 + packages/lazy-file/package.json | 46 +- packages/lazy-file/tsup.config.ts | 20 + packages/multipart-parser/bench/package.json | 3 +- .../examples/bun/package.json | 3 +- .../examples/cf-workers/package.json | 2 +- .../examples/deno/package.json | 3 +- .../examples/node/package.json | 3 +- packages/multipart-parser/package.json | 46 +- packages/multipart-parser/tsup.config.ts | 20 + packages/node-fetch-server/package.json | 27 +- packages/node-fetch-server/tsup.config.ts | 9 + pnpm-lock.yaml | 1070 ++++++++++++++++- 21 files changed, 1405 insertions(+), 43 deletions(-) create mode 100644 packages/fetch-proxy/tsup.config.ts create mode 100644 packages/file-storage/tsup.config.ts create mode 100644 packages/form-data-parser/tsup.config.ts create mode 100644 packages/headers/tsup.config.ts create mode 100644 packages/lazy-file/tsup.config.ts create mode 100644 packages/multipart-parser/tsup.config.ts create mode 100644 packages/node-fetch-server/tsup.config.ts diff --git a/package.json b/package.json index 4ab74067ce5..079596813a4 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,7 @@ "packageManager": "pnpm@9.9.0", "devDependencies": { "@swc-node/register": "^1.10.9", - "prettier": "^3.3.3", - "typescript": "^5.5.4" + "prettier": "^3.3.3" }, "scripts": { "clean": "git clean -fdX ." diff --git a/packages/fetch-proxy/package.json b/packages/fetch-proxy/package.json index 3addac25c7b..4eafabed509 100644 --- a/packages/fetch-proxy/package.json +++ b/packages/fetch-proxy/package.json @@ -16,18 +16,39 @@ "README.md" ], "type": "module", + "types": "dist/fetch-proxy.d.ts", + "main": "dist/fetch-proxy.js", "exports": { - ".": "./dist/fetch-proxy.js", + ".": { + "module-sync": { + "types": "./dist/fetch-proxy.d.ts", + "default": "./dist/fetch-proxy.js" + }, + "import": { + "types": "./dist/fetch-proxy.d.ts", + "default": "./dist/fetch-proxy.js" + }, + "require": { + "types": "./dist/fetch-proxy.d.cts", + "default": "./dist/fetch-proxy.cjs" + }, + "default": { + "types": "./dist/fetch-proxy.d.ts", + "default": "./dist/fetch-proxy.js" + } + }, "./package.json": "./package.json" }, "dependencies": { "@mjackson/headers": "workspace:^" }, "devDependencies": { - "@types/node": "^20.14.10" + "@types/node": "^20.14.10", + "tsup": "^8.3.5", + "typescript": "^5.6.3" }, "scripts": { - "build": "tsc --outDir dist --project tsconfig.lib.json", + "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", "prepare": "pnpm run build", "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" diff --git a/packages/fetch-proxy/tsup.config.ts b/packages/fetch-proxy/tsup.config.ts new file mode 100644 index 00000000000..3bb9618c27f --- /dev/null +++ b/packages/fetch-proxy/tsup.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig({ + clean: true, + dts: true, + entry: ['src/fetch-proxy.ts'], + format: ['cjs', 'esm'], + platform: 'neutral', +}); diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index 48298c0ca44..a55ba62d3c1 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -16,20 +16,75 @@ "README.md" ], "type": "module", + "types": "./dist/file-storage.d.ts", + "main": "./dist/file-storage.js", "exports": { - ".": "./dist/file-storage.js", - "./local": "./dist/local.js", - "./memory": "./dist/memory.js", + ".": { + "module-sync": { + "types": "./dist/file-storage.d.ts", + "default": "./dist/file-storage.js" + }, + "import": { + "types": "./dist/file-storage.d.ts", + "default": "./dist/file-storage.js" + }, + "require": { + "types": "./dist/file-storage.d.cts", + "default": "./dist/file-storage.cjs" + }, + "default": { + "types": "./dist/file-storage.d.ts", + "default": "./dist/file-storage.js" + } + }, + "./local": { + "module-sync": { + "types": "./dist/local.d.ts", + "default": "./dist/local.js" + }, + "import": { + "types": "./dist/local.d.ts", + "default": "./dist/local.js" + }, + "require": { + "types": "./dist/local.d.cts", + "default": "./dist/local.cjs" + }, + "default": { + "types": "./dist/local.d.ts", + "default": "./dist/local.js" + } + }, + "./memory": { + "module-sync": { + "types": "./dist/memory.d.ts", + "default": "./dist/memory.js" + }, + "import": { + "types": "./dist/memory.d.ts", + "default": "./dist/memory.js" + }, + "require": { + "types": "./dist/memory.d.cts", + "default": "./dist/memory.cjs" + }, + "default": { + "types": "./dist/memory.d.ts", + "default": "./dist/memory.js" + } + }, "./package.json": "./package.json" }, "dependencies": { "@mjackson/lazy-file": "workspace:^" }, "devDependencies": { - "@types/node": "^20.14.10" + "@types/node": "^20.14.10", + "tsup": "^8.3.5", + "typescript": "^5.6.3" }, "scripts": { - "build": "tsc --outDir dist --project tsconfig.lib.json", + "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", "prepare": "pnpm run build", "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" diff --git a/packages/file-storage/tsup.config.ts b/packages/file-storage/tsup.config.ts new file mode 100644 index 00000000000..79f2fb41489 --- /dev/null +++ b/packages/file-storage/tsup.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig([ + // Platform-neutral build + { + clean: true, + dts: true, + entry: ['src/file-storage.ts', 'src/memory.ts'], + format: ['cjs', 'esm'], + platform: 'neutral', + }, + // Node specific build + { + clean: false, + dts: true, + entry: ['src/local.ts'], + format: ['cjs', 'esm'], + platform: 'node', + }, +]); diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index e4030f6da4b..f0694a02571 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -16,18 +16,39 @@ "README.md" ], "type": "module", + "types": "./dist/form-data-parser.d.ts", + "main": "./dist/form-data-parser.js", "exports": { - ".": "./dist/form-data-parser.js", + ".": { + "module-sync": { + "types": "./dist/form-data-parser.d.ts", + "default": "./dist/form-data-parser.js" + }, + "import": { + "types": "./dist/form-data-parser.d.ts", + "default": "./dist/form-data-parser.js" + }, + "require": { + "types": "./dist/form-data-parser.d.cts", + "default": "./dist/form-data-parser.cjs" + }, + "default": { + "types": "./dist/form-data-parser.d.ts", + "default": "./dist/form-data-parser.js" + } + }, "./package.json": "./package.json" }, "dependencies": { "@mjackson/multipart-parser": "workspace:^" }, "devDependencies": { - "@types/node": "^22.4.1" + "@types/node": "^22.4.1", + "tsup": "^8.3.5", + "typescript": "^5.6.3" }, "scripts": { - "build": "tsc --outDir dist --project tsconfig.lib.json", + "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", "prepare": "pnpm run build", "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" diff --git a/packages/form-data-parser/tsup.config.ts b/packages/form-data-parser/tsup.config.ts new file mode 100644 index 00000000000..37785d93cf4 --- /dev/null +++ b/packages/form-data-parser/tsup.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig({ + clean: true, + dts: true, + entry: ['src/form-data-parser.ts'], + format: ['cjs', 'esm'], + platform: 'neutral', +}); diff --git a/packages/headers/package.json b/packages/headers/package.json index 28d1d680091..0f7ce92851f 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -16,15 +16,36 @@ "README.md" ], "type": "module", + "types": "./dist/headers.d.ts", + "main": "./dist/headers.js", "exports": { - ".": "./dist/headers.js", + ".": { + "module-sync": { + "types": "./dist/headers.d.ts", + "default": "./dist/headers.js" + }, + "import": { + "types": "./dist/headers.d.ts", + "default": "./dist/headers.js" + }, + "require": { + "types": "./dist/headers.d.cts", + "default": "./dist/headers.cjs" + }, + "default": { + "types": "./dist/headers.d.ts", + "default": "./dist/headers.js" + } + }, "./package.json": "./package.json" }, "devDependencies": { - "@types/node": "^20.14.10" + "@types/node": "^20.14.10", + "tsup": "^8.3.5", + "typescript": "^5.6.3" }, "scripts": { - "build": "tsc --outDir dist --project tsconfig.lib.json", + "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", "prepare": "pnpm run build", "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" diff --git a/packages/headers/tsup.config.ts b/packages/headers/tsup.config.ts new file mode 100644 index 00000000000..d2992de6d9e --- /dev/null +++ b/packages/headers/tsup.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig({ + clean: true, + dts: true, + entry: ['src/headers.ts'], + format: ['cjs', 'esm'], + platform: 'neutral', +}); diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index 430b66d2fdf..9997ffbaba2 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -16,19 +16,57 @@ "README.md" ], "type": "module", + "types": "./dist/lazy-file.d.ts", + "main": "./dist/lazy-file.js", "exports": { - ".": "./dist/lazy-file.js", - "./fs": "./dist/fs.js", + ".": { + "module-sync": { + "types": "./dist/lazy-file.d.ts", + "default": "./dist/lazy-file.js" + }, + "import": { + "types": "./dist/lazy-file.d.ts", + "default": "./dist/lazy-file.js" + }, + "require": { + "types": "./dist/lazy-file.d.cts", + "default": "./dist/lazy-file.cjs" + }, + "default": { + "types": "./dist/lazy-file.d.ts", + "default": "./dist/lazy-file.js" + } + }, + "./fs": { + "module-sync": { + "types": "./dist/fs.d.ts", + "default": "./dist/fs.js" + }, + "import": { + "types": "./dist/fs.d.ts", + "default": "./dist/fs.js" + }, + "require": { + "types": "./dist/fs.d.cts", + "default": "./dist/fs.cjs" + }, + "default": { + "types": "./dist/fs.d.ts", + "default": "./dist/fs.js" + } + }, "./package.json": "./package.json" }, "dependencies": { "mrmime": "^2.0.0" }, "devDependencies": { - "@types/node": "^22.5.0" + "@types/node": "^22.5.0", + "tsup": "^8.3.5", + "typescript": "^5.6.3" }, "scripts": { - "build": "tsc --outDir dist --project tsconfig.lib.json", + "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", "prepare": "pnpm run build", "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" diff --git a/packages/lazy-file/tsup.config.ts b/packages/lazy-file/tsup.config.ts new file mode 100644 index 00000000000..3812c722c1e --- /dev/null +++ b/packages/lazy-file/tsup.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig([ + // Platform-neutral build + { + clean: true, + dts: true, + entry: ['src/lazy-file.ts'], + format: ['cjs', 'esm'], + platform: 'neutral', + }, + // Node specific build + { + clean: true, + dts: true, + entry: ['src/fs.ts'], + format: ['cjs', 'esm'], + platform: 'node', + }, +]); diff --git a/packages/multipart-parser/bench/package.json b/packages/multipart-parser/bench/package.json index 4bb5e8ce417..f516f7af336 100644 --- a/packages/multipart-parser/bench/package.json +++ b/packages/multipart-parser/bench/package.json @@ -10,6 +10,7 @@ }, "devDependencies": { "@types/bun": "^1.1.6", - "@types/busboy": "^1.5.4" + "@types/busboy": "^1.5.4", + "typescript": "^5.6.3" } } diff --git a/packages/multipart-parser/examples/bun/package.json b/packages/multipart-parser/examples/bun/package.json index fa37c3b35d0..1218f42e702 100644 --- a/packages/multipart-parser/examples/bun/package.json +++ b/packages/multipart-parser/examples/bun/package.json @@ -7,7 +7,8 @@ }, "devDependencies": { "@types/bun": "^1.1.6", - "@types/tmp": "^0.2.6" + "@types/tmp": "^0.2.6", + "typescript": "^5.6.3" }, "scripts": { "start": "bun run server.ts" diff --git a/packages/multipart-parser/examples/cf-workers/package.json b/packages/multipart-parser/examples/cf-workers/package.json index 3ae2bf546a8..76c24e93065 100644 --- a/packages/multipart-parser/examples/cf-workers/package.json +++ b/packages/multipart-parser/examples/cf-workers/package.json @@ -6,7 +6,7 @@ }, "devDependencies": { "@cloudflare/workers-types": "^4.20240725.0", - "typescript": "^5.5.2", + "typescript": "^5.6.3", "wrangler": "^3.60.3" }, "scripts": { diff --git a/packages/multipart-parser/examples/deno/package.json b/packages/multipart-parser/examples/deno/package.json index 050d73d47d5..3769ccad3d4 100644 --- a/packages/multipart-parser/examples/deno/package.json +++ b/packages/multipart-parser/examples/deno/package.json @@ -6,7 +6,8 @@ "tmp": "^0.2.3" }, "devDependencies": { - "@types/tmp": "^0.2.6" + "@types/tmp": "^0.2.6", + "typescript": "^5.6.3" }, "scripts": { "start": "deno --unstable-byonm run --allow-all main.ts" diff --git a/packages/multipart-parser/examples/node/package.json b/packages/multipart-parser/examples/node/package.json index 13297b1a278..9962681886e 100644 --- a/packages/multipart-parser/examples/node/package.json +++ b/packages/multipart-parser/examples/node/package.json @@ -8,7 +8,8 @@ }, "devDependencies": { "@types/node": "^20.14.10", - "@types/tmp": "^0.2.6" + "@types/tmp": "^0.2.6", + "typescript": "^5.6.3" }, "scripts": { "start": "node server.js" diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 87d302bb7d0..912ddaa3fda 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -16,23 +16,61 @@ "README.md" ], "type": "module", + "types": "./dist/multipart-parser.d.ts", + "main": "./dist/multipart-parser.js", "exports": { - ".": "./dist/multipart-parser.js", - "./node": "./dist/multipart-parser.node.js", + ".": { + "module-sync": { + "types": "./dist/multipart-parser.d.ts", + "default": "./dist/multipart-parser.js" + }, + "import": { + "types": "./dist/multipart-parser.d.ts", + "default": "./dist/multipart-parser.js" + }, + "require": { + "types": "./dist/multipart-parser.d.cts", + "default": "./dist/multipart-parser.cjs" + }, + "default": { + "types": "./dist/multipart-parser.d.ts", + "default": "./dist/multipart-parser.js" + } + }, + "./node": { + "module-sync": { + "types": "./dist/multipart-parser.node.d.ts", + "default": "./dist/multipart-parser.node.js" + }, + "import": { + "types": "./dist/multipart-parser.node.d.ts", + "default": "./dist/multipart-parser.node.js" + }, + "require": { + "types": "./dist/multipart-parser.node.d.cts", + "default": "./dist/multipart-parser.node.cjs" + }, + "default": { + "types": "./dist/multipart-parser.node.d.ts", + "default": "./dist/multipart-parser.node.js" + } + }, "./package.json": "./package.json" }, "dependencies": { "@mjackson/headers": "workspace:^" }, "devDependencies": { - "@types/node": "^20.14.10" + "@types/node": "^20.14.10", + "tsup": "^8.3.5", + "typescript": "^5.6.3" }, "scripts": { "bench": "pnpm run bench:node && pnpm run bench:bun && pnpm run bench:deno", "bench:bun": "bun run ./bench/runner.ts", "bench:deno": "deno --unstable-byonm --unstable-sloppy-imports run --allow-sys ./bench/runner.ts", "bench:node": "node --import @swc-node/register/esm-register ./bench/runner.ts", - "build": "tsc --outDir dist --project tsconfig.lib.json", + "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", "prepare": "pnpm run build", "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" diff --git a/packages/multipart-parser/tsup.config.ts b/packages/multipart-parser/tsup.config.ts new file mode 100644 index 00000000000..90675d51d03 --- /dev/null +++ b/packages/multipart-parser/tsup.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig([ + // Platform-neutral build + { + clean: true, + dts: true, + entry: ['src/multipart-parser.ts'], + format: ['cjs', 'esm'], + platform: 'neutral', + }, + // Node specific build + { + clean: true, + dts: true, + entry: ['src/multipart-parser.node.ts'], + format: ['cjs', 'esm'], + platform: 'node', + }, +]); diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index a3d2bb9a202..1701867a666 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -16,16 +16,37 @@ "README.md" ], "type": "module", + "types": "./dist/node-fetch-server.d.ts", + "main": "./dist/node-fetch-server.js", "exports": { - ".": "./dist/node-fetch-server.js", + ".": { + "module-sync": { + "types": "./dist/node-fetch-server.d.ts", + "default": "./dist/node-fetch-server.js" + }, + "import": { + "types": "./dist/node-fetch-server.d.ts", + "default": "./dist/node-fetch-server.js" + }, + "require": { + "types": "./dist/node-fetch-server.d.cts", + "default": "./dist/node-fetch-server.cjs" + }, + "default": { + "types": "./dist/node-fetch-server.d.ts", + "default": "./dist/node-fetch-server.js" + } + }, "./package.json": "./package.json" }, "devDependencies": { - "@types/node": "^22.5.0" + "@types/node": "^22.5.0", + "tsup": "^8.3.5", + "typescript": "^5.6.3" }, "scripts": { "bench": "bash ./bench/runner.sh", - "build": "tsc --outDir dist --project tsconfig.lib.json", + "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", "prepare": "pnpm run build", "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" diff --git a/packages/node-fetch-server/tsup.config.ts b/packages/node-fetch-server/tsup.config.ts new file mode 100644 index 00000000000..8b826dd4eb6 --- /dev/null +++ b/packages/node-fetch-server/tsup.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig({ + clean: true, + dts: true, + entry: ['src/node-fetch-server.ts'], + format: ['cjs', 'esm'], + platform: 'neutral', +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 134572b057d..0fff7bb82fb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,13 +10,10 @@ importers: devDependencies: '@swc-node/register': specifier: ^1.10.9 - version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) + version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) prettier: specifier: ^3.3.3 version: 3.3.3 - typescript: - specifier: ^5.5.4 - version: 5.5.4 packages/fetch-proxy: dependencies: @@ -27,6 +24,12 @@ importers: '@types/node': specifier: ^20.14.10 version: 20.16.1 + tsup: + specifier: ^8.3.5 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) + typescript: + specifier: ^5.6.3 + version: 5.6.3 packages/file-storage: dependencies: @@ -37,6 +40,12 @@ importers: '@types/node': specifier: ^20.14.10 version: 20.16.1 + tsup: + specifier: ^8.3.5 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) + typescript: + specifier: ^5.6.3 + version: 5.6.3 packages/form-data-parser: dependencies: @@ -47,12 +56,24 @@ importers: '@types/node': specifier: ^22.4.1 version: 22.5.0 + tsup: + specifier: ^8.3.5 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) + typescript: + specifier: ^5.6.3 + version: 5.6.3 packages/headers: devDependencies: '@types/node': specifier: ^20.14.10 version: 20.16.1 + tsup: + specifier: ^8.3.5 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) + typescript: + specifier: ^5.6.3 + version: 5.6.3 packages/lazy-file: dependencies: @@ -63,6 +84,12 @@ importers: '@types/node': specifier: ^22.5.0 version: 22.5.0 + tsup: + specifier: ^8.3.5 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) + typescript: + specifier: ^5.6.3 + version: 5.6.3 packages/multipart-parser: dependencies: @@ -73,6 +100,12 @@ importers: '@types/node': specifier: ^20.14.10 version: 20.16.1 + tsup: + specifier: ^8.3.5 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) + typescript: + specifier: ^5.6.3 + version: 5.6.3 packages/multipart-parser/bench: dependencies: @@ -95,6 +128,9 @@ importers: '@types/busboy': specifier: ^1.5.4 version: 1.5.4 + typescript: + specifier: ^5.6.3 + version: 5.6.3 packages/multipart-parser/examples/bun: dependencies: @@ -111,6 +147,9 @@ importers: '@types/tmp': specifier: ^0.2.6 version: 0.2.6 + typescript: + specifier: ^5.6.3 + version: 5.6.3 packages/multipart-parser/examples/cf-workers: dependencies: @@ -122,8 +161,8 @@ importers: specifier: ^4.20240725.0 version: 4.20240821.1 typescript: - specifier: ^5.5.2 - version: 5.5.4 + specifier: ^5.6.3 + version: 5.6.3 wrangler: specifier: ^3.60.3 version: 3.72.3(@cloudflare/workers-types@4.20240821.1) @@ -140,6 +179,9 @@ importers: '@types/tmp': specifier: ^0.2.6 version: 0.2.6 + typescript: + specifier: ^5.6.3 + version: 5.6.3 packages/multipart-parser/examples/node: dependencies: @@ -156,12 +198,21 @@ importers: '@types/tmp': specifier: ^0.2.6 version: 0.2.6 + typescript: + specifier: ^5.6.3 + version: 5.6.3 packages/node-fetch-server: devDependencies: '@types/node': specifier: ^22.5.0 version: 22.5.0 + tsup: + specifier: ^8.3.5 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) + typescript: + specifier: ^5.6.3 + version: 5.6.3 packages/node-fetch-server/bench: dependencies: @@ -254,138 +305,282 @@ packages: peerDependencies: esbuild: '*' + '@esbuild/aix-ppc64@0.24.0': + resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.17.19': resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} engines: {node: '>=12'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.24.0': + resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.17.19': resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} engines: {node: '>=12'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.24.0': + resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.17.19': resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} engines: {node: '>=12'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.24.0': + resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.17.19': resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.24.0': + resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.17.19': resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.24.0': + resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.17.19': resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.24.0': + resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.17.19': resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.24.0': + resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.17.19': resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} engines: {node: '>=12'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.24.0': + resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.17.19': resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} engines: {node: '>=12'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.24.0': + resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.17.19': resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} engines: {node: '>=12'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.24.0': + resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.17.19': resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} engines: {node: '>=12'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.24.0': + resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.17.19': resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.24.0': + resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.17.19': resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.24.0': + resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.17.19': resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.24.0': + resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.17.19': resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} engines: {node: '>=12'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.24.0': + resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.17.19': resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} engines: {node: '>=12'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.24.0': + resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-x64@0.17.19': resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.24.0': + resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.24.0': + resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.17.19': resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.24.0': + resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/sunos-x64@0.17.19': resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.24.0': + resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.17.19': resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} engines: {node: '>=12'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.24.0': + resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.17.19': resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} engines: {node: '>=12'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.24.0': + resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.17.19': resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} engines: {node: '>=12'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.24.0': + resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@fastify/busboy@2.1.1': resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} engines: {node: '>=14'} @@ -393,13 +588,28 @@ packages: '@fastify/busboy@3.0.0': resolution: {integrity: sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==} + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} @@ -461,6 +671,100 @@ packages: cpu: [x64] os: [win32] + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@rollup/rollup-android-arm-eabi@4.26.0': + resolution: {integrity: sha512-gJNwtPDGEaOEgejbaseY6xMFu+CPltsc8/T+diUTTbOQLqD+bnrJq9ulH6WD69TqwqWmrfRAtUv30cCFZlbGTQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.26.0': + resolution: {integrity: sha512-YJa5Gy8mEZgz5JquFruhJODMq3lTHWLm1fOy+HIANquLzfIOzE9RA5ie3JjCdVb9r46qfAQY/l947V0zfGJ0OQ==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.26.0': + resolution: {integrity: sha512-ErTASs8YKbqTBoPLp/kA1B1Um5YSom8QAc4rKhg7b9tyyVqDBlQxy7Bf2wW7yIlPGPg2UODDQcbkTlruPzDosw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.26.0': + resolution: {integrity: sha512-wbgkYDHcdWW+NqP2mnf2NOuEbOLzDblalrOWcPyY6+BRbVhliavon15UploG7PpBRQ2bZJnbmh8o3yLoBvDIHA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.26.0': + resolution: {integrity: sha512-Y9vpjfp9CDkAG4q/uwuhZk96LP11fBz/bYdyg9oaHYhtGZp7NrbkQrj/66DYMMP2Yo/QPAsVHkV891KyO52fhg==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.26.0': + resolution: {integrity: sha512-A/jvfCZ55EYPsqeaAt/yDAG4q5tt1ZboWMHEvKAH9Zl92DWvMIbnZe/f/eOXze65aJaaKbL+YeM0Hz4kLQvdwg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.26.0': + resolution: {integrity: sha512-paHF1bMXKDuizaMODm2bBTjRiHxESWiIyIdMugKeLnjuS1TCS54MF5+Y5Dx8Ui/1RBPVRE09i5OUlaLnv8OGnA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.26.0': + resolution: {integrity: sha512-cwxiHZU1GAs+TMxvgPfUDtVZjdBdTsQwVnNlzRXC5QzIJ6nhfB4I1ahKoe9yPmoaA/Vhf7m9dB1chGPpDRdGXg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.26.0': + resolution: {integrity: sha512-4daeEUQutGRCW/9zEo8JtdAgtJ1q2g5oHaoQaZbMSKaIWKDQwQ3Yx0/3jJNmpzrsScIPtx/V+1AfibLisb3AMQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.26.0': + resolution: {integrity: sha512-eGkX7zzkNxvvS05ROzJ/cO/AKqNvR/7t1jA3VZDi2vRniLKwAWxUr85fH3NsvtxU5vnUUKFHKh8flIBdlo2b3Q==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.26.0': + resolution: {integrity: sha512-Odp/lgHbW/mAqw/pU21goo5ruWsytP7/HCC/liOt0zcGG0llYWKrd10k9Fj0pdj3prQ63N5yQLCLiE7HTX+MYw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.26.0': + resolution: {integrity: sha512-MBR2ZhCTzUgVD0OJdTzNeF4+zsVogIR1U/FsyuFerwcqjZGvg2nYe24SAHp8O5sN8ZkRVbHwlYeHqcSQ8tcYew==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.26.0': + resolution: {integrity: sha512-YYcg8MkbN17fMbRMZuxwmxWqsmQufh3ZJFxFGoHjrE7bv0X+T6l3glcdzd7IKLiwhT+PZOJCblpnNlz1/C3kGQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.26.0': + resolution: {integrity: sha512-ZuwpfjCwjPkAOxpjAEjabg6LRSfL7cAJb6gSQGZYjGhadlzKKywDkCUnJ+KEfrNY1jH5EEoSIKLCb572jSiglA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.26.0': + resolution: {integrity: sha512-+HJD2lFS86qkeF8kNu0kALtifMpPCZU80HvwztIKnYwym3KnA1os6nsX4BGSTLtS2QVAGG1P3guRgsYyMA0Yhg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.26.0': + resolution: {integrity: sha512-WUQzVFWPSw2uJzX4j6YEbMAiLbs0BUysgysh8s817doAYhR5ybqTI1wtKARQKo6cGop3pHnrUJPFCsXdoFaimQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.26.0': + resolution: {integrity: sha512-D4CxkazFKBfN1akAIY6ieyOqzoOoBV1OICxgUblWxff/pSjCA2khXlASUx7mK6W1oP4McqhgcCsu6QaLj3WMWg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.26.0': + resolution: {integrity: sha512-2x8MO1rm4PGEP0xWbubJW5RtbNLk3puzAMaLQd3B3JHVw4KcHlmXcO+Wewx9zCoo7EUFiMlu/aZbCJ7VjMzAag==} + cpu: [x64] + os: [win32] + '@swc-node/core@1.13.3': resolution: {integrity: sha512-OGsvXIid2Go21kiNqeTIn79jcaX4l0G93X2rAnas4LFoDyA9wAwVK7xZdm+QsKoMn5Mus2yFLCc4OtX2dD/PWA==} engines: {node: '>= 10'} @@ -570,6 +874,9 @@ packages: '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/express-serve-static-core@4.19.5': resolution: {integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==} @@ -631,6 +938,25 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -641,6 +967,9 @@ packages: as-table@1.0.55: resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -652,6 +981,9 @@ packages: resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -662,6 +994,12 @@ packages: bun-types@1.1.26: resolution: {integrity: sha512-n7jDe62LsB2+WE8Q8/mT3azkPaatKlj/2MyP6hi3mKvPz9oPpB6JW/Ll6JHtNLudasFFuvfgklYSE+rreGvBjw==} + bundle-require@5.0.0: + resolution: {integrity: sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -670,6 +1008,10 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} @@ -681,9 +1023,24 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + chokidar@4.0.1: + resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} + engines: {node: '>= 14.16.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + consola@3.2.3: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} engines: {node: ^14.18.0 || >=16.10.0} @@ -707,6 +1064,10 @@ packages: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} + cross-spawn@7.0.5: + resolution: {integrity: sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==} + engines: {node: '>= 8'} + data-uri-to-buffer@2.0.2: resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} @@ -730,6 +1091,15 @@ packages: supports-color: optional: true + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} @@ -745,9 +1115,18 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} @@ -765,6 +1144,11 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.24.0: + resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} + engines: {node: '>=18'} + hasBin: true + escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} @@ -787,6 +1171,14 @@ packages: resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} engines: {node: '>= 0.10.0'} + fdir@6.4.2: + resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -795,6 +1187,10 @@ packages: resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} engines: {node: '>= 0.8'} + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -825,6 +1221,10 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} @@ -870,6 +1270,10 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -878,6 +1282,33 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} @@ -915,6 +1346,14 @@ packages: engines: {node: '>=16.13'} hasBin: true + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + mrmime@2.0.0: resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} engines: {node: '>=10'} @@ -935,6 +1374,9 @@ packages: resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} hasBin: true + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -955,6 +1397,10 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + object-inspect@1.13.2: resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} engines: {node: '>= 0.4'} @@ -966,13 +1412,24 @@ packages: oxc-resolver@1.11.0: resolution: {integrity: sha512-N3qMse2AM7uST8PaiUMXZkcACyGAMN073tomyvzHTICSzaOqKHvVS0IZ3vj/OqoE140QP4CyOiWmgC1Hw5Urmg==} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-to-regexp@0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} @@ -982,14 +1439,39 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + prettier@3.3.3: resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} engines: {node: '>=14'} @@ -1002,6 +1484,10 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + qs@6.11.0: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} engines: {node: '>=0.6'} @@ -1018,6 +1504,14 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + readdirp@4.0.2: + resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} + engines: {node: '>= 14.16.0'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + resolve.exports@2.0.2: resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} engines: {node: '>=10'} @@ -1036,6 +1530,11 @@ packages: rollup-pluginutils@2.8.2: resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + rollup@4.26.0: + resolution: {integrity: sha512-ilcl12hnWonG8f+NxU6BlgysVA0gvY2l8N0R84S1HcINbW20bvwuCngJkkInV6LXhwRpucsW5k1ovDwEdBVrNg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -1066,10 +1565,22 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -1077,6 +1588,10 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + sourcemap-codec@1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} deprecated: Please use @jridgewell/sourcemap-codec instead @@ -1096,10 +1611,45 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + + tinyglobby@0.2.10: + resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} + engines: {node: '>=12.0.0'} + tmp@0.2.3: resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} engines: {node: '>=14.14'} @@ -1112,15 +1662,44 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tsup@8.3.5: + resolution: {integrity: sha512-Tunf6r6m6tnZsG9GYWndg0z8dEV7fD733VBFzFJ5Vcm1FtlXB8xBD/rtrBi2a3YKEV7hHtxiZtW5EAVADoe1pA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} - typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} hasBin: true @@ -1152,6 +1731,17 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + + whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + workerd@1.20240821.1: resolution: {integrity: sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==} engines: {node: '>=16'} @@ -1167,6 +1757,14 @@ packages: '@cloudflare/workers-types': optional: true + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + ws@8.18.0: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} @@ -1243,80 +1841,174 @@ snapshots: escape-string-regexp: 4.0.0 rollup-plugin-node-polyfills: 0.2.1 + '@esbuild/aix-ppc64@0.24.0': + optional: true + '@esbuild/android-arm64@0.17.19': optional: true + '@esbuild/android-arm64@0.24.0': + optional: true + '@esbuild/android-arm@0.17.19': optional: true + '@esbuild/android-arm@0.24.0': + optional: true + '@esbuild/android-x64@0.17.19': optional: true + '@esbuild/android-x64@0.24.0': + optional: true + '@esbuild/darwin-arm64@0.17.19': optional: true + '@esbuild/darwin-arm64@0.24.0': + optional: true + '@esbuild/darwin-x64@0.17.19': optional: true + '@esbuild/darwin-x64@0.24.0': + optional: true + '@esbuild/freebsd-arm64@0.17.19': optional: true + '@esbuild/freebsd-arm64@0.24.0': + optional: true + '@esbuild/freebsd-x64@0.17.19': optional: true + '@esbuild/freebsd-x64@0.24.0': + optional: true + '@esbuild/linux-arm64@0.17.19': optional: true + '@esbuild/linux-arm64@0.24.0': + optional: true + '@esbuild/linux-arm@0.17.19': optional: true + '@esbuild/linux-arm@0.24.0': + optional: true + '@esbuild/linux-ia32@0.17.19': optional: true + '@esbuild/linux-ia32@0.24.0': + optional: true + '@esbuild/linux-loong64@0.17.19': optional: true + '@esbuild/linux-loong64@0.24.0': + optional: true + '@esbuild/linux-mips64el@0.17.19': optional: true + '@esbuild/linux-mips64el@0.24.0': + optional: true + '@esbuild/linux-ppc64@0.17.19': optional: true + '@esbuild/linux-ppc64@0.24.0': + optional: true + '@esbuild/linux-riscv64@0.17.19': optional: true + '@esbuild/linux-riscv64@0.24.0': + optional: true + '@esbuild/linux-s390x@0.17.19': optional: true + '@esbuild/linux-s390x@0.24.0': + optional: true + '@esbuild/linux-x64@0.17.19': optional: true + '@esbuild/linux-x64@0.24.0': + optional: true + '@esbuild/netbsd-x64@0.17.19': optional: true + '@esbuild/netbsd-x64@0.24.0': + optional: true + + '@esbuild/openbsd-arm64@0.24.0': + optional: true + '@esbuild/openbsd-x64@0.17.19': optional: true + '@esbuild/openbsd-x64@0.24.0': + optional: true + '@esbuild/sunos-x64@0.17.19': optional: true + '@esbuild/sunos-x64@0.24.0': + optional: true + '@esbuild/win32-arm64@0.17.19': optional: true + '@esbuild/win32-arm64@0.24.0': + optional: true + '@esbuild/win32-ia32@0.17.19': optional: true + '@esbuild/win32-ia32@0.24.0': + optional: true + '@esbuild/win32-x64@0.17.19': optional: true + '@esbuild/win32-x64@0.24.0': + optional: true + '@fastify/busboy@2.1.1': {} '@fastify/busboy@3.0.0': {} + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/resolve-uri@3.1.2': {} + '@jridgewell/set-array@1.2.1': {} + '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -1364,12 +2056,69 @@ snapshots: '@oxc-resolver/binding-win32-x64-msvc@1.11.0': optional: true + '@pkgjs/parseargs@0.11.0': + optional: true + + '@rollup/rollup-android-arm-eabi@4.26.0': + optional: true + + '@rollup/rollup-android-arm64@4.26.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.26.0': + optional: true + + '@rollup/rollup-darwin-x64@4.26.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.26.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.26.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.26.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.26.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.26.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.26.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.26.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.26.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.26.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.26.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.26.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.26.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.26.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.26.0': + optional: true + '@swc-node/core@1.13.3(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)': dependencies: '@swc/core': 1.5.29(@swc/helpers@0.5.12) '@swc/types': 0.1.12 - '@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4)': + '@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3)': dependencies: '@swc-node/core': 1.13.3(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12) '@swc-node/sourcemap-support': 0.5.1 @@ -1379,7 +2128,7 @@ snapshots: oxc-resolver: 1.11.0 pirates: 4.0.6 tslib: 2.7.0 - typescript: 5.5.4 + typescript: 5.6.3 transitivePeerDependencies: - '@swc/types' - supports-color @@ -1469,6 +2218,8 @@ snapshots: dependencies: '@types/node': 22.5.4 + '@types/estree@1.0.6': {} + '@types/express-serve-static-core@4.19.5': dependencies: '@types/node': 22.5.4 @@ -1541,6 +2292,18 @@ snapshots: acorn@8.12.1: {} + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -1552,6 +2315,8 @@ snapshots: dependencies: printable-characters: 1.0.42 + balanced-match@1.0.2: {} + binary-extensions@2.3.0: {} blake3-wasm@2.1.5: {} @@ -1573,6 +2338,10 @@ snapshots: transitivePeerDependencies: - supports-color + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -1584,12 +2353,19 @@ snapshots: '@types/node': 20.12.14 '@types/ws': 8.5.12 + bundle-require@5.0.0(esbuild@0.24.0): + dependencies: + esbuild: 0.24.0 + load-tsconfig: 0.2.5 + busboy@1.6.0: dependencies: streamsearch: 1.1.0 bytes@3.1.2: {} + cac@6.7.14: {} + call-bind@1.0.7: dependencies: es-define-property: 1.0.0 @@ -1617,8 +2393,20 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + chokidar@4.0.1: + dependencies: + readdirp: 4.0.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + colorette@2.0.20: {} + commander@4.1.1: {} + consola@3.2.3: {} content-disposition@0.5.4: @@ -1633,6 +2421,12 @@ snapshots: cookie@0.6.0: {} + cross-spawn@7.0.5: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + data-uri-to-buffer@2.0.2: {} date-fns@3.6.0: {} @@ -1645,6 +2439,10 @@ snapshots: dependencies: ms: 2.1.2 + debug@4.3.7: + dependencies: + ms: 2.1.3 + define-data-property@1.1.4: dependencies: es-define-property: 1.0.0 @@ -1657,8 +2455,14 @@ snapshots: destroy@1.2.0: {} + eastasianwidth@0.2.0: {} + ee-first@1.1.1: {} + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + encodeurl@1.0.2: {} es-define-property@1.0.0: @@ -1692,6 +2496,33 @@ snapshots: '@esbuild/win32-ia32': 0.17.19 '@esbuild/win32-x64': 0.17.19 + esbuild@0.24.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.0 + '@esbuild/android-arm': 0.24.0 + '@esbuild/android-arm64': 0.24.0 + '@esbuild/android-x64': 0.24.0 + '@esbuild/darwin-arm64': 0.24.0 + '@esbuild/darwin-x64': 0.24.0 + '@esbuild/freebsd-arm64': 0.24.0 + '@esbuild/freebsd-x64': 0.24.0 + '@esbuild/linux-arm': 0.24.0 + '@esbuild/linux-arm64': 0.24.0 + '@esbuild/linux-ia32': 0.24.0 + '@esbuild/linux-loong64': 0.24.0 + '@esbuild/linux-mips64el': 0.24.0 + '@esbuild/linux-ppc64': 0.24.0 + '@esbuild/linux-riscv64': 0.24.0 + '@esbuild/linux-s390x': 0.24.0 + '@esbuild/linux-x64': 0.24.0 + '@esbuild/netbsd-x64': 0.24.0 + '@esbuild/openbsd-arm64': 0.24.0 + '@esbuild/openbsd-x64': 0.24.0 + '@esbuild/sunos-x64': 0.24.0 + '@esbuild/win32-arm64': 0.24.0 + '@esbuild/win32-ia32': 0.24.0 + '@esbuild/win32-x64': 0.24.0 + escape-html@1.0.3: {} escape-string-regexp@4.0.0: {} @@ -1738,6 +2569,10 @@ snapshots: transitivePeerDependencies: - supports-color + fdir@6.4.2(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -1754,6 +2589,11 @@ snapshots: transitivePeerDependencies: - supports-color + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.5 + signal-exit: 4.1.0 + forwarded@0.2.0: {} fresh@0.5.2: {} @@ -1782,6 +2622,15 @@ snapshots: glob-to-regexp@0.4.1: {} + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + gopd@1.0.1: dependencies: get-intrinsic: 1.2.4 @@ -1824,12 +2673,34 @@ snapshots: is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 is-number@7.0.0: {} + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + joycon@3.1.1: {} + + lilconfig@3.1.2: {} + + lines-and-columns@1.2.4: {} + + load-tsconfig@0.2.5: {} + + lodash.sortby@4.7.0: {} + + lru-cache@10.4.3: {} + magic-string@0.25.9: dependencies: sourcemap-codec: 1.4.8 @@ -1869,6 +2740,12 @@ snapshots: - supports-color - utf-8-validate + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + mrmime@2.0.0: {} ms@2.0.0: {} @@ -1881,6 +2758,12 @@ snapshots: mustache@4.2.0: {} + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + nanoid@3.3.7: {} negotiator@0.6.3: {} @@ -1891,6 +2774,8 @@ snapshots: normalize-path@3.0.0: {} + object-assign@4.1.1: {} + object-inspect@1.13.2: {} on-finished@2.4.1: @@ -1911,20 +2796,37 @@ snapshots: '@oxc-resolver/binding-win32-arm64-msvc': 1.11.0 '@oxc-resolver/binding-win32-x64-msvc': 1.11.0 + package-json-from-dist@1.0.1: {} + parseurl@1.3.3: {} + path-key@3.1.1: {} + path-parse@1.0.7: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + path-to-regexp@0.1.7: {} path-to-regexp@6.2.2: {} pathe@1.1.2: {} + picocolors@1.1.1: {} + picomatch@2.3.1: {} + picomatch@4.0.2: {} + pirates@4.0.6: {} + postcss-load-config@6.0.1: + dependencies: + lilconfig: 3.1.2 + prettier@3.3.3: {} printable-characters@1.0.42: {} @@ -1934,6 +2836,8 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 + punycode@2.3.1: {} + qs@6.11.0: dependencies: side-channel: 1.0.6 @@ -1951,6 +2855,10 @@ snapshots: dependencies: picomatch: 2.3.1 + readdirp@4.0.2: {} + + resolve-from@5.0.0: {} + resolve.exports@2.0.2: {} resolve@1.22.8: @@ -1973,6 +2881,30 @@ snapshots: dependencies: estree-walker: 0.6.1 + rollup@4.26.0: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.26.0 + '@rollup/rollup-android-arm64': 4.26.0 + '@rollup/rollup-darwin-arm64': 4.26.0 + '@rollup/rollup-darwin-x64': 4.26.0 + '@rollup/rollup-freebsd-arm64': 4.26.0 + '@rollup/rollup-freebsd-x64': 4.26.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.26.0 + '@rollup/rollup-linux-arm-musleabihf': 4.26.0 + '@rollup/rollup-linux-arm64-gnu': 4.26.0 + '@rollup/rollup-linux-arm64-musl': 4.26.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.26.0 + '@rollup/rollup-linux-riscv64-gnu': 4.26.0 + '@rollup/rollup-linux-s390x-gnu': 4.26.0 + '@rollup/rollup-linux-x64-gnu': 4.26.0 + '@rollup/rollup-linux-x64-musl': 4.26.0 + '@rollup/rollup-win32-arm64-msvc': 4.26.0 + '@rollup/rollup-win32-ia32-msvc': 4.26.0 + '@rollup/rollup-win32-x64-msvc': 4.26.0 + fsevents: 2.3.3 + safe-buffer@5.2.1: {} safer-buffer@2.1.2: {} @@ -2022,6 +2954,12 @@ snapshots: setprototypeof@1.2.0: {} + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + side-channel@1.0.6: dependencies: call-bind: 1.0.7 @@ -2029,6 +2967,8 @@ snapshots: get-intrinsic: 1.2.4 object-inspect: 1.13.2 + signal-exit@4.1.0: {} + source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 @@ -2036,6 +2976,10 @@ snapshots: source-map@0.6.1: {} + source-map@0.8.0-beta.0: + dependencies: + whatwg-url: 7.1.0 + sourcemap-codec@1.4.8: {} stacktracey@2.1.8: @@ -2049,8 +2993,53 @@ snapshots: streamsearch@1.1.0: {} + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + supports-preserve-symlinks-flag@1.0.0: {} + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinyexec@0.3.1: {} + + tinyglobby@0.2.10: + dependencies: + fdir: 6.4.2(picomatch@4.0.2) + picomatch: 4.0.2 + tmp@0.2.3: {} to-regex-range@5.0.1: @@ -2059,14 +3048,49 @@ snapshots: toidentifier@1.0.1: {} + tr46@1.0.1: + dependencies: + punycode: 2.3.1 + + tree-kill@1.2.2: {} + + ts-interface-checker@0.1.13: {} + tslib@2.7.0: {} + tsup@8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3): + dependencies: + bundle-require: 5.0.0(esbuild@0.24.0) + cac: 6.7.14 + chokidar: 4.0.1 + consola: 3.2.3 + debug: 4.3.7 + esbuild: 0.24.0 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1 + resolve-from: 5.0.0 + rollup: 4.26.0 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tinyexec: 0.3.1 + tinyglobby: 0.2.10 + tree-kill: 1.2.2 + optionalDependencies: + '@swc/core': 1.5.29(@swc/helpers@0.5.12) + typescript: 5.6.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + type-is@1.6.18: dependencies: media-typer: 0.3.0 mime-types: 2.1.35 - typescript@5.5.4: {} + typescript@5.6.3: {} ufo@1.5.4: {} @@ -2093,6 +3117,18 @@ snapshots: vary@1.1.2: {} + webidl-conversions@4.0.2: {} + + whatwg-url@7.1.0: + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + workerd@1.20240821.1: optionalDependencies: '@cloudflare/workerd-darwin-64': 1.20240821.1 @@ -2129,6 +3165,18 @@ snapshots: - supports-color - utf-8-validate + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + ws@8.18.0: {} xxhash-wasm@1.0.2: {} From 8ec072697d8348c6530dd9cb56c55d7cb7e48cd1 Mon Sep 17 00:00:00 2001 From: Jacob Ebey <jacob.ebey@live.com> Date: Wed, 13 Nov 2024 13:52:02 -0800 Subject: [PATCH 462/730] chore: move deps to packages that use them --- package.json | 1 - packages/fetch-proxy/package.json | 1 + packages/file-storage/package.json | 1 + packages/form-data-parser/package.json | 1 + packages/headers/package.json | 1 + packages/lazy-file/package.json | 1 + packages/multipart-parser/package.json | 1 + packages/node-fetch-server/package.json | 1 + pnpm-lock.yaml | 26 +++++++++++++++++++++---- 9 files changed, 29 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 079596813a4..8f628df8a7e 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,6 @@ "private": true, "packageManager": "pnpm@9.9.0", "devDependencies": { - "@swc-node/register": "^1.10.9", "prettier": "^3.3.3" }, "scripts": { diff --git a/packages/fetch-proxy/package.json b/packages/fetch-proxy/package.json index 4eafabed509..9680826f883 100644 --- a/packages/fetch-proxy/package.json +++ b/packages/fetch-proxy/package.json @@ -43,6 +43,7 @@ "@mjackson/headers": "workspace:^" }, "devDependencies": { + "@swc-node/register": "^1.10.9", "@types/node": "^20.14.10", "tsup": "^8.3.5", "typescript": "^5.6.3" diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index a55ba62d3c1..604a67422df 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -79,6 +79,7 @@ "@mjackson/lazy-file": "workspace:^" }, "devDependencies": { + "@swc-node/register": "^1.10.9", "@types/node": "^20.14.10", "tsup": "^8.3.5", "typescript": "^5.6.3" diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index f0694a02571..72c759af9c3 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -43,6 +43,7 @@ "@mjackson/multipart-parser": "workspace:^" }, "devDependencies": { + "@swc-node/register": "^1.10.9", "@types/node": "^22.4.1", "tsup": "^8.3.5", "typescript": "^5.6.3" diff --git a/packages/headers/package.json b/packages/headers/package.json index 0f7ce92851f..3f5cc36f61a 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -40,6 +40,7 @@ "./package.json": "./package.json" }, "devDependencies": { + "@swc-node/register": "^1.10.9", "@types/node": "^20.14.10", "tsup": "^8.3.5", "typescript": "^5.6.3" diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index 9997ffbaba2..34c46e5e062 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -61,6 +61,7 @@ "mrmime": "^2.0.0" }, "devDependencies": { + "@swc-node/register": "^1.10.9", "@types/node": "^22.5.0", "tsup": "^8.3.5", "typescript": "^5.6.3" diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 912ddaa3fda..c1ad8a2c876 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -61,6 +61,7 @@ "@mjackson/headers": "workspace:^" }, "devDependencies": { + "@swc-node/register": "^1.10.9", "@types/node": "^20.14.10", "tsup": "^8.3.5", "typescript": "^5.6.3" diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 1701867a666..bd3cc2b5d5b 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -40,6 +40,7 @@ "./package.json": "./package.json" }, "devDependencies": { + "@swc-node/register": "^1.10.9", "@types/node": "^22.5.0", "tsup": "^8.3.5", "typescript": "^5.6.3" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0fff7bb82fb..7070f5818b1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,6 @@ importers: .: devDependencies: - '@swc-node/register': - specifier: ^1.10.9 - version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) prettier: specifier: ^3.3.3 version: 3.3.3 @@ -21,6 +18,9 @@ importers: specifier: workspace:^ version: link:../headers devDependencies: + '@swc-node/register': + specifier: ^1.10.9 + version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^20.14.10 version: 20.16.1 @@ -37,6 +37,9 @@ importers: specifier: workspace:^ version: link:../lazy-file devDependencies: + '@swc-node/register': + specifier: ^1.10.9 + version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^20.14.10 version: 20.16.1 @@ -53,6 +56,9 @@ importers: specifier: workspace:^ version: link:../multipart-parser devDependencies: + '@swc-node/register': + specifier: ^1.10.9 + version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^22.4.1 version: 22.5.0 @@ -65,6 +71,9 @@ importers: packages/headers: devDependencies: + '@swc-node/register': + specifier: ^1.10.9 + version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^20.14.10 version: 20.16.1 @@ -81,6 +90,9 @@ importers: specifier: ^2.0.0 version: 2.0.0 devDependencies: + '@swc-node/register': + specifier: ^1.10.9 + version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^22.5.0 version: 22.5.0 @@ -97,6 +109,9 @@ importers: specifier: workspace:^ version: link:../headers devDependencies: + '@swc-node/register': + specifier: ^1.10.9 + version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^20.14.10 version: 20.16.1 @@ -204,6 +219,9 @@ importers: packages/node-fetch-server: devDependencies: + '@swc-node/register': + specifier: ^1.10.9 + version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^22.5.0 version: 22.5.0 @@ -2124,7 +2142,7 @@ snapshots: '@swc-node/sourcemap-support': 0.5.1 '@swc/core': 1.5.29(@swc/helpers@0.5.12) colorette: 2.0.20 - debug: 4.3.6 + debug: 4.3.7 oxc-resolver: 1.11.0 pirates: 4.0.6 tslib: 2.7.0 From 4fbe2803e4cbe486dea0b274f6a376af32430f50 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Wed, 13 Nov 2024 14:21:09 -0800 Subject: [PATCH 463/730] Fix import --- packages/node-fetch-server/src/lib/request-listener.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.spec.ts b/packages/node-fetch-server/src/lib/request-listener.spec.ts index fb40de2f8e9..ce8c4c36566 100644 --- a/packages/node-fetch-server/src/lib/request-listener.spec.ts +++ b/packages/node-fetch-server/src/lib/request-listener.spec.ts @@ -4,7 +4,8 @@ import { describe, it, mock } from 'node:test'; import * as http from 'node:http'; import * as stream from 'node:stream'; -import { FetchHandler, createRequestListener } from './request-listener.js'; +import { FetchHandler } from './fetch-handler.js'; +import { createRequestListener } from './request-listener.js'; describe('createRequestListener', () => { it('returns a request listener', async () => { From e1ab5b64dc00c9c4108f4618d42594b74322de7c Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 13:53:11 -0800 Subject: [PATCH 464/730] Update release script --- scripts/release.ts | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/scripts/release.ts b/scripts/release.ts index 3c407968383..0b5342ec217 100644 --- a/scripts/release.ts +++ b/scripts/release.ts @@ -7,6 +7,8 @@ import * as semver from 'semver'; const __dirname = path.dirname(new URL(import.meta.url).pathname); +// This script should be run as part of an npm script ("scripts" key in package.json) +// so that it can access the package name and version from environment variables. const packageName = process.env.npm_package_name; const packageVersion = process.env.npm_package_version; const releaseType = process.argv[2]; @@ -20,7 +22,7 @@ let newVersion = semver.inc(packageVersion, releaseType as semver.ReleaseType); let [_packageScope, packageNameWithoutScope] = packageName.split('/'); let packageDir = path.resolve(__dirname, '..', 'packages', packageNameWithoutScope); -// Ensure git staging area is clean +// 1) Ensure git staging area is clean let status = cp.execSync('git status --porcelain').toString(); if (status !== '') { console.error('Git staging area is not clean'); @@ -30,19 +32,19 @@ if (status !== '') { console.log(`Releasing ${packageNameWithoutScope}@${newVersion} ...`); console.log(); -function execWithLog(command: string) { +function logAndExec(command: string) { console.log(`$ ${command}`); cp.execSync(command, { stdio: 'inherit' }); } -// Update package.json +// 2) Update package.json with the new release version let packageJsonPath = path.relative(process.cwd(), path.join(packageDir, 'package.json')); let packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); packageJson.version = newVersion; fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); -execWithLog(`git add ${packageJsonPath}`); +logAndExec(`git add ${packageJsonPath}`); -// Update CHANGELOG.md +// 3) Swap out "## HEAD" in CHANGELOG.md with the new release version + date let changelogPath = path.relative(process.cwd(), path.join(packageDir, 'CHANGELOG.md')); let changelog = fs.readFileSync(changelogPath, 'utf-8'); let match = /^## HEAD\n/m.exec(changelog); @@ -55,21 +57,21 @@ if (match) { changelog.slice(match.index + match[0].length); fs.writeFileSync(changelogPath, changelog); - execWithLog(`git add ${changelogPath}`); + logAndExec(`git add ${changelogPath}`); } -// Update jsr.json +// 4) Update jsr.json (if applicable) with the new release version let jsrJsonPath = path.relative(process.cwd(), path.join(packageDir, 'jsr.json')); if (fs.existsSync(jsrJsonPath)) { let jsrJson = JSON.parse(fs.readFileSync(jsrJsonPath, 'utf-8')); jsrJson.version = newVersion; fs.writeFileSync(jsrJsonPath, JSON.stringify(jsrJson, null, 2) + '\n'); - execWithLog(`git add ${jsrJsonPath}`); + logAndExec(`git add ${jsrJsonPath}`); } -// Commit and tag +// 5) Commit and tag let tag = `${packageNameWithoutScope}@${newVersion}`; -execWithLog(`git commit -m "Release ${tag}"`); -execWithLog(`git tag ${tag}`); +logAndExec(`git commit -m "Release ${tag}"`); +logAndExec(`git tag ${tag}`); console.log(); From ca7cfb907c580e5d4510c8e92b4871cacef2656b Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:30:15 -0800 Subject: [PATCH 465/730] Use req.rawHeaders directly --- .../src/lib/request-listener.spec.ts | 8 ++- .../src/lib/request-listener.ts | 71 ++++++++----------- 2 files changed, 36 insertions(+), 43 deletions(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.spec.ts b/packages/node-fetch-server/src/lib/request-listener.spec.ts index ce8c4c36566..51fac3786d3 100644 --- a/packages/node-fetch-server/src/lib/request-listener.spec.ts +++ b/packages/node-fetch-server/src/lib/request-listener.spec.ts @@ -220,13 +220,15 @@ function createIncomingMessage({ }: { method?: string; url?: string; - headers?: Record<string, string | string[]>; + headers?: Record<string, string>; socket?: { encrypted?: boolean; remoteAddress?: string; }; body?: string | Buffer; } = {}): http.IncomingMessage { + let rawHeaders = Object.entries(headers).flatMap(([key, value]) => [key, value]); + return Object.assign( new stream.Readable({ read() { @@ -237,10 +239,10 @@ function createIncomingMessage({ { url, method, - headers, + rawHeaders, socket, }, - ) as unknown as http.IncomingMessage; + ) as http.IncomingMessage; } function createServerResponse(): http.ServerResponse { diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index b02f2bae4c1..e51c551279d 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -54,17 +54,12 @@ export function createRequestListener( let onError = options?.onError ?? defaultErrorHandler; return async (req, res) => { - let protocol = - options?.protocol ?? ('encrypted' in req.socket && req.socket.encrypted ? 'https:' : 'http:'); - let host = options?.host ?? req.headers.host ?? 'localhost'; - let url = new URL(req.url!, `${protocol}//${host}`); - let controller = new AbortController(); res.on('close', () => { controller.abort(); }); - let request = createRequest(req, url, controller.signal); + let request = createRequest(req, controller.signal, options); let client = { address: req.socket.remoteAddress!, family: req.socket.remoteFamily! as ClientAddress['family'], @@ -124,15 +119,33 @@ function internalServerError(): Response { ); } -function createRequest(req: http.IncomingMessage, url: URL, signal: AbortSignal): Request { - let init: RequestInit = { - method: req.method, - headers: createHeaders(req.headers), - signal, - }; - - if (req.method !== 'GET' && req.method !== 'HEAD') { - init.body = createBody(req); +function createRequest( + req: http.IncomingMessage, + signal: AbortSignal, + options?: RequestListenerOptions, +): Request { + let method = req.method ?? 'GET'; + let headers = createHeaders(req.rawHeaders); + + let protocol = + options?.protocol ?? ('encrypted' in req.socket && req.socket.encrypted ? 'https:' : 'http:'); + let host = options?.host ?? headers.get('host') ?? 'localhost'; + let url = new URL(req.url!, `${protocol}//${host}`); + + let init: RequestInit = { method, headers, signal }; + + if (method !== 'GET' && method !== 'HEAD') { + init.body = new ReadableStream({ + start(controller) { + req.on('data', (chunk) => { + controller.enqueue(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength)); + }); + + req.on('end', () => { + controller.close(); + }); + }, + }); // init.duplex = 'half' must be set when body is a ReadableStream, and Node follows the spec. // However, this property is not defined in the TypeScript types for RequestInit, so we have @@ -144,34 +157,12 @@ function createRequest(req: http.IncomingMessage, url: URL, signal: AbortSignal) return new Request(url, init); } -function createHeaders(incoming: http.IncomingHttpHeaders): Headers { +function createHeaders(rawHeaders: string[]): Headers { let headers = new Headers(); - for (let key in incoming) { - let value = incoming[key]; - - if (Array.isArray(value)) { - for (let item of value) { - headers.append(key, item); - } - } else if (value != null) { - headers.append(key, value); - } + for (let i = 0; i < rawHeaders.length; i += 2) { + headers.append(rawHeaders[i], rawHeaders[i + 1]); } return headers; } - -function createBody(req: http.IncomingMessage): ReadableStream<Uint8Array> { - return new ReadableStream({ - start(controller) { - req.on('data', (chunk) => { - controller.enqueue(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength)); - }); - - req.on('end', () => { - controller.close(); - }); - }, - }); -} From 9aacf8743490e13013070fbe32a0e18944afdc26 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:34:38 -0800 Subject: [PATCH 466/730] Update benchmark --- packages/node-fetch-server/README.md | 44 ++++++++++++++-------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/node-fetch-server/README.md b/packages/node-fetch-server/README.md index 517ccfaa8c4..70f1f864ccd 100644 --- a/packages/node-fetch-server/README.md +++ b/packages/node-fetch-server/README.md @@ -80,45 +80,45 @@ A basic "hello world" benchmark shows `node-fetch-server` introduces considerabl > @mjackson/node-fetch-server@0.0.0 bench /Users/michael/Projects/remix-the-web/packages/node-fetch-server > bash ./bench/runner.sh -Platform: Darwin (23.5.0) +Platform: Darwin (24.0.0) CPU: Apple M1 Pro -Date: 8/31/2024, 5:43:47 PM +Date: 11/14/2024, 2:30:22 PM -Running benchmark for node:http@22.1.0 ... +Running benchmark for node:http@22.8.0 ... Running 30s test @ http://127.0.0.1:3000/ 12 threads and 400 connections Thread Stats Avg Stdev Max +/- Stdev - Latency 22.28ms 71.96ms 1.36s 98.37% - Req/Sec 2.37k 538.29 9.51k 85.30% - 848851 requests in 30.10s, 174.05MB read - Socket errors: connect 0, read 544, write 27, timeout 0 -Requests/sec: 28198.41 -Transfer/sec: 5.78MB + Latency 9.97ms 31.92ms 786.67ms 99.09% + Req/Sec 4.45k 268.33 6.38k 93.69% + 1594257 requests in 30.02s, 326.89MB read + Socket errors: connect 0, read 1317, write 6, timeout 0 +Requests/sec: 53110.92 +Transfer/sec: 10.89MB -Running benchmark for node-fetch-server@0.0.0 ... +Running benchmark for node-fetch-server@0.1.0 ... Running 30s test @ http://127.0.0.1:3000/ 12 threads and 400 connections Thread Stats Avg Stdev Max +/- Stdev - Latency 42.57ms 109.55ms 2.00s 98.37% - Req/Sec 1.03k 282.58 2.78k 77.37% - 368110 requests in 30.10s, 75.48MB read - Socket errors: connect 0, read 717, write 152, timeout 126 -Requests/sec: 12228.31 -Transfer/sec: 2.51MB + Latency 22.74ms 81.06ms 1.46s 98.22% + Req/Sec 2.42k 185.82 4.30k 91.80% + 866347 requests in 30.03s, 177.64MB read + Socket errors: connect 0, read 1496, write 3, timeout 0 +Requests/sec: 28849.46 +Transfer/sec: 5.92MB Running benchmark for express@4.19.2 ... Running 30s test @ http://127.0.0.1:3000/ 12 threads and 400 connections Thread Stats Avg Stdev Max +/- Stdev - Latency 48.76ms 87.38ms 2.00s 98.90% - Req/Sec 734.60 190.17 3.03k 79.08% - 261725 requests in 30.09s, 63.15MB read - Socket errors: connect 0, read 1259, write 110, timeout 200 -Requests/sec: 8696.85 -Transfer/sec: 2.10MB + Latency 36.46ms 125.89ms 1.99s 97.89% + Req/Sec 1.56k 146.86 2.93k 88.25% + 558504 requests in 30.06s, 134.76MB read + Socket errors: connect 0, read 1261, write 11, timeout 36 +Requests/sec: 18579.11 +Transfer/sec: 4.48MB ``` ## License From c332c590361df56eeaf714128401071ed0eefca5 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:36:00 -0800 Subject: [PATCH 467/730] Update Changelog for release --- packages/node-fetch-server/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 747b95f0d4d..45c6bb8b659 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -1,3 +1,8 @@ +## HEAD + +- Small perf improvement from avoiding accessing `req.headers` and reading `req.rawHeaders` instead +- Added CommonJS build + ## v0.1.0 (2024-09-05) - Initial release From ec4ac5b5d387a09a65f8a1aff09f68a036d9ad5a Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:36:08 -0800 Subject: [PATCH 468/730] Release node-fetch-server@0.2.0 --- packages/node-fetch-server/CHANGELOG.md | 2 +- packages/node-fetch-server/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 45c6bb8b659..5f90992ce18 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -1,4 +1,4 @@ -## HEAD +## v0.2.0 (2024-11-14) - Small perf improvement from avoiding accessing `req.headers` and reading `req.rawHeaders` instead - Added CommonJS build diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index bd3cc2b5d5b..7c473a62ef3 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/node-fetch-server", - "version": "0.1.0", + "version": "0.2.0", "description": "Build servers for Node.js using the web fetch API", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From bbaf5fbdbf29505a5ce5b5d387c913e48c77d89c Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:47:21 -0800 Subject: [PATCH 469/730] Update changelog --- packages/multipart-parser/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index e4cf8128dc5..28402a205af 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -1,3 +1,7 @@ +## HEAD + +- Added CommonJS build + ## v0.6.3 (2024-09-05) - Moved to a new monorepo From e0cc104bc0679e8959537cea578f6701525d3818 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:47:25 -0800 Subject: [PATCH 470/730] Release multipart-parser@0.7.0 --- packages/multipart-parser/CHANGELOG.md | 2 +- packages/multipart-parser/jsr.json | 2 +- packages/multipart-parser/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index 28402a205af..b6cfaeb7ca8 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -1,4 +1,4 @@ -## HEAD +## v0.7.0 (2024-11-14) - Added CommonJS build diff --git a/packages/multipart-parser/jsr.json b/packages/multipart-parser/jsr.json index 04f9ab7f050..45eb3932629 100644 --- a/packages/multipart-parser/jsr.json +++ b/packages/multipart-parser/jsr.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.6.2", + "version": "0.7.0", "exports": "./src/multipart-parser.ts", "publish": { "include": [ diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index c1ad8a2c876..3124a2b1b62 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.6.3", + "version": "0.7.0", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From 492359e4e084ff1f65eb56628e5f6629b445bb32 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:49:13 -0800 Subject: [PATCH 471/730] Update changelog --- packages/lazy-file/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/lazy-file/CHANGELOG.md b/packages/lazy-file/CHANGELOG.md index 1584ba29af0..c95f4b588a9 100644 --- a/packages/lazy-file/CHANGELOG.md +++ b/packages/lazy-file/CHANGELOG.md @@ -1,3 +1,7 @@ +## HEAD + +- Added CommonJS build + ## v3.2.0 (2024-09-12) - Export `OpenFileOptions` from `lazy-file/fs` From 4de6b1d035eb7858835989c2d99ba79b95f945a9 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:49:20 -0800 Subject: [PATCH 472/730] Release lazy-file@3.3.0 --- packages/lazy-file/CHANGELOG.md | 2 +- packages/lazy-file/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/lazy-file/CHANGELOG.md b/packages/lazy-file/CHANGELOG.md index c95f4b588a9..bf0e2f120f1 100644 --- a/packages/lazy-file/CHANGELOG.md +++ b/packages/lazy-file/CHANGELOG.md @@ -1,4 +1,4 @@ -## HEAD +## v3.3.0 (2024-11-14) - Added CommonJS build diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index 34c46e5e062..13157b8907b 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/lazy-file", - "version": "3.2.0", + "version": "3.3.0", "description": "Lazy, streaming files for JavaScript", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From 90a041ccb3fcd5d0e467d956749fd5f322424f68 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:50:51 -0800 Subject: [PATCH 473/730] Update changelog --- packages/headers/CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 25fb814d87d..f61bb226e83 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -1,6 +1,8 @@ -## 0.7.2 (2024-08-29) +## HEAD + +- Added CommonJS build -### 🩹 Fixes +## 0.7.2 (2024-08-29) - Treat `Headers` as iterable in the constructor From cf31a371d8921f23ed02e3ec539b76ffafcf5a72 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:50:58 -0800 Subject: [PATCH 474/730] Release headers@0.8.0 --- packages/headers/CHANGELOG.md | 2 +- packages/headers/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index f61bb226e83..e6783ce4a42 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -1,4 +1,4 @@ -## HEAD +## v0.8.0 (2024-11-14) - Added CommonJS build diff --git a/packages/headers/package.json b/packages/headers/package.json index 3f5cc36f61a..016e45f12a1 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/headers", - "version": "0.7.2", + "version": "0.8.0", "description": "A toolkit for working with HTTP headers in JavaScript", "author": "Michael Jackson <mjijackson@gmail.com>", "license": "MIT", From 26b1a703c1bed944c2cf6d52ebfb50cc712feefb Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:51:39 -0800 Subject: [PATCH 475/730] Update changelog --- packages/form-data-parser/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index 1aa4f883771..4fab628684a 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -1,3 +1,7 @@ +## HEAD + +- Added CommonJS build + ## v0.4.0 (2024-09-05) - Allow passing `MultipartParserOptions` as optional 3rd arg to `parseFormData()` From 2e87844c670a2439c12b994f9cb91b1571c52514 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:51:48 -0800 Subject: [PATCH 476/730] Release form-data-parser@0.5.0 --- packages/form-data-parser/CHANGELOG.md | 2 +- packages/form-data-parser/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index 4fab628684a..a9d62d5fb3e 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -1,4 +1,4 @@ -## HEAD +## v0.5.0 (2024-11-14) - Added CommonJS build diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index 72c759af9c3..ede34ddcefc 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/form-data-parser", - "version": "0.4.0", + "version": "0.5.0", "description": "A request.formData() wrapper with streaming file upload handling", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From 8d5558d00b4cd7ae7b9ee189b2506b02938be0e6 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:53:39 -0800 Subject: [PATCH 477/730] Update changelog --- packages/file-storage/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 308cbf33ae5..0411f3d27ad 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -1,5 +1,6 @@ ## HEAD +- Added CommonJS build - Upgrade to lazy-file@3.1.0 ## v0.2.1 (2024-09-04) From 67b923c0847b256febbe8ea0a691b28ed1794eb9 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:53:47 -0800 Subject: [PATCH 478/730] Release file-storage@0.3.0 --- packages/file-storage/CHANGELOG.md | 2 +- packages/file-storage/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 0411f3d27ad..a1c2bc83b56 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -1,4 +1,4 @@ -## HEAD +## v0.3.0 (2024-11-14) - Added CommonJS build - Upgrade to lazy-file@3.1.0 diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index 604a67422df..b3c135edad8 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/file-storage", - "version": "0.2.1", + "version": "0.3.0", "description": "Key/value storage for JavaScript File objects", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From ea84ebb4a44722ad1d8d1baf54fce543b8511b64 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:54:31 -0800 Subject: [PATCH 479/730] Update changelog --- packages/fetch-proxy/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/fetch-proxy/CHANGELOG.md b/packages/fetch-proxy/CHANGELOG.md index 0e0e9d12f97..f9975d408af 100644 --- a/packages/fetch-proxy/CHANGELOG.md +++ b/packages/fetch-proxy/CHANGELOG.md @@ -1,3 +1,7 @@ +## HEAD + +- Added CommonJS build + ## v0.1.0 (2024-09-12) - Initial release From 097704f944172fa1279c0fefe16e58c49c867752 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 14:54:39 -0800 Subject: [PATCH 480/730] Release fetch-proxy@0.2.0 --- packages/fetch-proxy/CHANGELOG.md | 2 +- packages/fetch-proxy/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/fetch-proxy/CHANGELOG.md b/packages/fetch-proxy/CHANGELOG.md index f9975d408af..78594319f91 100644 --- a/packages/fetch-proxy/CHANGELOG.md +++ b/packages/fetch-proxy/CHANGELOG.md @@ -1,4 +1,4 @@ -## HEAD +## v0.2.0 (2024-11-14) - Added CommonJS build diff --git a/packages/fetch-proxy/package.json b/packages/fetch-proxy/package.json index 9680826f883..0dad5fb8a1e 100644 --- a/packages/fetch-proxy/package.json +++ b/packages/fetch-proxy/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/fetch-proxy", - "version": "0.1.0", + "version": "0.2.0", "description": "An HTTP proxy for the web Fetch API", "author": "Michael Jackson <mjijackson@gmail.com>", "license": "MIT", From 0d52f0d76469695536bbf142240ce1db98dff404 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Tue, 19 Nov 2024 16:17:02 -0800 Subject: [PATCH 481/730] Add low-level createRequest and sendResponse APIs --- packages/node-fetch-server/CHANGELOG.md | 4 + packages/node-fetch-server/README.md | 37 ++++++++- .../src/lib/request-listener.spec.ts | 41 ++++++---- .../src/lib/request-listener.ts | 82 +++++++++++-------- .../src/node-fetch-server.ts | 8 +- 5 files changed, 116 insertions(+), 56 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 5f90992ce18..4eb00657aff 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -1,3 +1,7 @@ +## HEAD + +- Added low-level `createRequest(req, options)` and `sendResponse(res, response)` exports to assist with building custom fetch servers on Node.js + ## v0.2.0 (2024-11-14) - Small perf improvement from avoiding accessing `req.headers` and reading `req.rawHeaders` instead diff --git a/packages/node-fetch-server/README.md b/packages/node-fetch-server/README.md index 70f1f864ccd..ef3dddb3ef5 100644 --- a/packages/node-fetch-server/README.md +++ b/packages/node-fetch-server/README.md @@ -31,9 +31,9 @@ npm install @mjackson/node-fetch-server import * as http from 'node:http'; import { createRequestListener } from '@mjackson/node-fetch-server'; -let handler = (request: Request) => { +function handler(request: Request) { return new Response('Hello, world!'); -}; +} let server = http.createServer(createRequestListener(handler)); @@ -47,11 +47,11 @@ import * as assert from 'node:assert/strict'; import * as http from 'node:http'; import { createRequestListener } from '@mjackson/node-fetch-server'; -let handler = (request: Request) => { +function handler(request: Request) { // This is now true assert.equal(new URL(request.url).host, process.env.HOST); return new Response('Hello, world!'); -}; +} let server = http.createServer(createRequestListener(handler, { host: process.env.HOST })); @@ -68,6 +68,35 @@ let handler: FetchHandler = (request, client) => { }; ``` +## Low-level API + +In addition to the high-level `createRequestListener()` API, this package also provides 2 low-level APIs that are useful when building custom `fetch`-based servers in Node.js: + +- `createRequest(req: http.IncomingMessage, options: RequestOptions): Request` +- `sendResponse(res: http.ServerResponse, response: Response): Promise<void>` + +These two functions serve as an efficient, minimal translation layer between Node.js `req`/`res` objects and fetch `Request`/`Response` objects. You could build your own custom server like this: + +```ts +import * as http from 'node:http'; +import { createRequest, sendResponse } from '@mjackson/node-fetch-server'; + +let server = http.createServer(async (req, res) => { + let request = createRequest(req, { host: process.env.HOST }); + + try { + let response = await customAppLogic(request); + await sendResponse(res, response); + } catch (error) { + console.error(error); + res.writeHead(500, { 'Content-Type': 'text/plain' }); + res.end('Internal Server Error'); + } +}); + +server.listen(3000); +``` + ## Related Packages - [`fetch-proxy`](https://github.com/mjackson/remix-the-web/tree/main/packages/fetch-proxy) - Build HTTP proxy servers using the web fetch API diff --git a/packages/node-fetch-server/src/lib/request-listener.spec.ts b/packages/node-fetch-server/src/lib/request-listener.spec.ts index 51fac3786d3..2b6c793d46c 100644 --- a/packages/node-fetch-server/src/lib/request-listener.spec.ts +++ b/packages/node-fetch-server/src/lib/request-listener.spec.ts @@ -17,8 +17,8 @@ describe('createRequestListener', () => { let listener = createRequestListener(handler); assert.ok(listener); - let req = createIncomingMessage(); - let res = createServerResponse(); + let req = createMockRequest(); + let res = createMockResponse({ req }); let chunks: Uint8Array[] = []; mock.method(res, 'write', (chunk: Uint8Array) => { @@ -45,8 +45,8 @@ describe('createRequestListener', () => { let listener = createRequestListener(handler, { onError: errorHandler }); assert.ok(listener); - let req = createIncomingMessage(); - let res = createServerResponse(); + let req = createMockRequest(); + let res = createMockResponse({ req }); mock.method(res, 'end', () => { assert.equal(errorHandler.mock.calls.length, 1); @@ -69,8 +69,8 @@ describe('createRequestListener', () => { let listener = createRequestListener(handler, { onError: errorHandler }); assert.ok(listener); - let req = createIncomingMessage(); - let res = createServerResponse(); + let req = createMockRequest(); + let res = createMockResponse({ req }); let status: number | undefined; mock.method(res, 'writeHead', (statusCode: number) => { @@ -103,8 +103,8 @@ describe('createRequestListener', () => { let listener = createRequestListener(handler); assert.ok(listener); - let req = createIncomingMessage({ headers: { host: 'example.com' } }); - let res = createServerResponse(); + let req = createMockRequest({ headers: { host: 'example.com' } }); + let res = createMockResponse({ req }); listener(req, res); resolve(); @@ -121,8 +121,8 @@ describe('createRequestListener', () => { let listener = createRequestListener(handler, { host: 'remix.run' }); assert.ok(listener); - let req = createIncomingMessage({ headers: { host: 'example.com' } }); - let res = createServerResponse(); + let req = createMockRequest({ headers: { host: 'example.com' } }); + let res = createMockResponse({ req }); listener(req, res); resolve(); @@ -139,8 +139,8 @@ describe('createRequestListener', () => { let listener = createRequestListener(handler, { protocol: 'https:' }); assert.ok(listener); - let req = createIncomingMessage({ headers: { host: 'example.com' } }); - let res = createServerResponse(); + let req = createMockRequest({ headers: { host: 'example.com' } }); + let res = createMockResponse({ req }); listener(req, res); resolve(); @@ -160,8 +160,8 @@ describe('createRequestListener', () => { let listener = createRequestListener(handler); assert.ok(listener); - let req = createIncomingMessage(); - let res = createServerResponse(); + let req = createMockRequest(); + let res = createMockResponse({ req }); let headers: string[]; mock.method(res, 'writeHead', (_status: number, headersArray: string[]) => { @@ -193,8 +193,8 @@ describe('createRequestListener', () => { let listener = createRequestListener(handler); assert.ok(listener); - let req = createIncomingMessage({ method: 'HEAD' }); - let res = createServerResponse(); + let req = createMockRequest({ method: 'HEAD' }); + let res = createMockResponse({ req }); let chunks: Uint8Array[] = []; mock.method(res, 'write', (chunk: Uint8Array) => { @@ -211,7 +211,7 @@ describe('createRequestListener', () => { }); }); -function createIncomingMessage({ +function createMockRequest({ url = '/', method = 'GET', headers = {}, @@ -245,8 +245,13 @@ function createIncomingMessage({ ) as http.IncomingMessage; } -function createServerResponse(): http.ServerResponse { +function createMockResponse({ + req = createMockRequest(), +}: { + req: http.IncomingMessage; +}): http.ServerResponse { return Object.assign(new stream.Writable(), { + req, writeHead() {}, write() {}, end() {}, diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index e51c551279d..f88001d06c7 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -34,11 +34,11 @@ export interface RequestListenerOptions { * * ```ts * import * as http from 'node:http'; - * import { type FetchHandler, createRequestListener } from '@mjackson/node-fetch-server'; + * import { createRequestListener } from '@mjackson/node-fetch-server'; * - * let handler: FetchHandler = async (request) => { + * async function handler(request) { * return new Response('Hello, world!'); - * }; + * } * * let server = http.createServer( * createRequestListener(handler) @@ -46,6 +46,10 @@ export interface RequestListenerOptions { * * server.listen(3000); * ``` + * + * @param handler The fetch handler to use for processing incoming requests. + * @param options Configuration options. + * @returns A Node.js `http.RequestListener` that can be used with `http.createServer()` or `https.createServer()`. */ export function createRequestListener( handler: FetchHandler, @@ -54,12 +58,7 @@ export function createRequestListener( let onError = options?.onError ?? defaultErrorHandler; return async (req, res) => { - let controller = new AbortController(); - res.on('close', () => { - controller.abort(); - }); - - let request = createRequest(req, controller.signal, options); + let request = createRequest(req, options); let client = { address: req.socket.remoteAddress!, family: req.socket.remoteFamily! as ClientAddress['family'], @@ -78,23 +77,7 @@ export function createRequestListener( } } - // Use the rawHeaders API and iterate over response.headers so we are sure to send multiple - // Set-Cookie headers correctly. These would incorrectly be merged into a single header if we - // tried to use `Object.fromEntries(response.headers.entries())`. - let rawHeaders: string[] = []; - for (let [key, value] of response.headers) { - rawHeaders.push(key, value); - } - - res.writeHead(response.status, rawHeaders); - - if (response.body != null && req.method !== 'HEAD') { - for await (let chunk of response.body) { - res.write(chunk); - } - } - - res.end(); + await sendResponse(res, response); }; } @@ -119,11 +102,20 @@ function internalServerError(): Response { ); } -function createRequest( - req: http.IncomingMessage, - signal: AbortSignal, - options?: RequestListenerOptions, -): Request { +export type RequestOptions = Omit<RequestListenerOptions, 'onError'>; + +/** + * Creates a `Request` object from an incoming Node.js request object. + * @param req The incoming request object. + * @param options + * @returns A `Request` object. + */ +export function createRequest(req: http.IncomingMessage, options?: RequestOptions): Request { + let controller = new AbortController(); + req.on('close', () => { + controller.abort(); + }); + let method = req.method ?? 'GET'; let headers = createHeaders(req.rawHeaders); @@ -132,7 +124,7 @@ function createRequest( let host = options?.host ?? headers.get('host') ?? 'localhost'; let url = new URL(req.url!, `${protocol}//${host}`); - let init: RequestInit = { method, headers, signal }; + let init: RequestInit = { method, headers, signal: controller.signal }; if (method !== 'GET' && method !== 'HEAD') { init.body = new ReadableStream({ @@ -140,7 +132,6 @@ function createRequest( req.on('data', (chunk) => { controller.enqueue(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength)); }); - req.on('end', () => { controller.close(); }); @@ -166,3 +157,28 @@ function createHeaders(rawHeaders: string[]): Headers { return headers; } + +/** + * Sends a `Response` to the client using the Node.js response object. + * @param res The server response object. + * @param response The response to send. + */ +export async function sendResponse(res: http.ServerResponse, response: Response): Promise<void> { + // Use the rawHeaders API and iterate over response.headers so we are sure to send multiple + // Set-Cookie headers correctly. These would incorrectly be merged into a single header if we + // tried to use `Object.fromEntries(response.headers.entries())`. + let rawHeaders: string[] = []; + for (let [key, value] of response.headers) { + rawHeaders.push(key, value); + } + + res.writeHead(response.status, rawHeaders); + + if (response.body != null && res.req.method !== 'HEAD') { + for await (let chunk of response.body) { + res.write(chunk); + } + } + + res.end(); +} diff --git a/packages/node-fetch-server/src/node-fetch-server.ts b/packages/node-fetch-server/src/node-fetch-server.ts index ed50b9ca84a..b5d12130721 100644 --- a/packages/node-fetch-server/src/node-fetch-server.ts +++ b/packages/node-fetch-server/src/node-fetch-server.ts @@ -1,2 +1,8 @@ export { type ClientAddress, type ErrorHandler, type FetchHandler } from './lib/fetch-handler.js'; -export { type RequestListenerOptions, createRequestListener } from './lib/request-listener.js'; +export { + type RequestListenerOptions, + createRequestListener, + type RequestOptions, + createRequest, + sendResponse, +} from './lib/request-listener.js'; From aa522747b5f8ab78978dff4b3d18ca3f7abeb8e5 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Tue, 19 Nov 2024 17:11:06 -0800 Subject: [PATCH 482/730] Release node-fetch-server@0.3.0 --- packages/node-fetch-server/CHANGELOG.md | 2 +- packages/node-fetch-server/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 4eb00657aff..2753cc3837f 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -1,4 +1,4 @@ -## HEAD +## v0.3.0 (2024-11-20) - Added low-level `createRequest(req, options)` and `sendResponse(res, response)` exports to assist with building custom fetch servers on Node.js diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 7c473a62ef3..adacdcfbad0 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/node-fetch-server", - "version": "0.2.0", + "version": "0.3.0", "description": "Build servers for Node.js using the web fetch API", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From c58f9e46c589a2ca7bdfd3c3b33d17e4e932b60f Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 07:14:32 -0800 Subject: [PATCH 483/730] New version script --- packages/fetch-proxy/package.json | 3 +- packages/file-storage/package.json | 3 +- packages/form-data-parser/package.json | 3 +- packages/headers/package.json | 3 +- packages/lazy-file/package.json | 3 +- packages/multipart-parser/package.json | 3 +- packages/node-fetch-server/package.json | 3 +- scripts/release.ts | 77 --------------------- scripts/tsconfig.json | 5 +- scripts/utils/changes.js | 43 ++++++++++++ scripts/utils/packages.js | 90 +++++++++++++++++++++++++ scripts/utils/semver.js | 17 +++++ scripts/version.js | 73 ++++++++++++++++++++ 13 files changed, 234 insertions(+), 92 deletions(-) delete mode 100644 scripts/release.ts create mode 100644 scripts/utils/changes.js create mode 100644 scripts/utils/packages.js create mode 100644 scripts/utils/semver.js create mode 100644 scripts/version.js diff --git a/packages/fetch-proxy/package.json b/packages/fetch-proxy/package.json index 0dad5fb8a1e..cbdec6b960d 100644 --- a/packages/fetch-proxy/package.json +++ b/packages/fetch-proxy/package.json @@ -51,8 +51,7 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" + "prepare": "pnpm run build" }, "keywords": [ "fetch", diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index b3c135edad8..4ab180cbb7c 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -87,8 +87,7 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" + "prepare": "pnpm run build" }, "keywords": [ "file", diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index ede34ddcefc..81168494aa3 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -51,8 +51,7 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" + "prepare": "pnpm run build" }, "keywords": [ "form-data", diff --git a/packages/headers/package.json b/packages/headers/package.json index 016e45f12a1..698dc8763aa 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -48,8 +48,7 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" + "prepare": "pnpm run build" }, "keywords": [ "fetch", diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index 13157b8907b..0bb5cfb785e 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -69,8 +69,7 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" + "prepare": "pnpm run build" }, "keywords": [ "file", diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 3124a2b1b62..038403d6555 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -73,8 +73,7 @@ "bench:node": "node --import @swc-node/register/esm-register ./bench/runner.ts", "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" + "prepare": "pnpm run build" }, "keywords": [ "multipart", diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index adacdcfbad0..624a899c591 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -49,8 +49,7 @@ "bench": "bash ./bench/runner.sh", "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" + "prepare": "pnpm run build" }, "keywords": [ "http", diff --git a/scripts/release.ts b/scripts/release.ts deleted file mode 100644 index 0b5342ec217..00000000000 --- a/scripts/release.ts +++ /dev/null @@ -1,77 +0,0 @@ -import * as cp from 'node:child_process'; -import * as fs from 'node:fs'; -import * as path from 'node:path'; -import * as process from 'node:process'; - -import * as semver from 'semver'; - -const __dirname = path.dirname(new URL(import.meta.url).pathname); - -// This script should be run as part of an npm script ("scripts" key in package.json) -// so that it can access the package name and version from environment variables. -const packageName = process.env.npm_package_name; -const packageVersion = process.env.npm_package_version; -const releaseType = process.argv[2]; - -if (packageName === undefined || packageVersion === undefined || releaseType === undefined) { - console.error('Usage: npm run release <releaseType>'); - process.exit(1); -} - -let newVersion = semver.inc(packageVersion, releaseType as semver.ReleaseType); -let [_packageScope, packageNameWithoutScope] = packageName.split('/'); -let packageDir = path.resolve(__dirname, '..', 'packages', packageNameWithoutScope); - -// 1) Ensure git staging area is clean -let status = cp.execSync('git status --porcelain').toString(); -if (status !== '') { - console.error('Git staging area is not clean'); - process.exit(1); -} - -console.log(`Releasing ${packageNameWithoutScope}@${newVersion} ...`); -console.log(); - -function logAndExec(command: string) { - console.log(`$ ${command}`); - cp.execSync(command, { stdio: 'inherit' }); -} - -// 2) Update package.json with the new release version -let packageJsonPath = path.relative(process.cwd(), path.join(packageDir, 'package.json')); -let packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); -packageJson.version = newVersion; -fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); -logAndExec(`git add ${packageJsonPath}`); - -// 3) Swap out "## HEAD" in CHANGELOG.md with the new release version + date -let changelogPath = path.relative(process.cwd(), path.join(packageDir, 'CHANGELOG.md')); -let changelog = fs.readFileSync(changelogPath, 'utf-8'); -let match = /^## HEAD\n/m.exec(changelog); -if (match) { - let [today] = new Date().toISOString().split('T'); - - changelog = - changelog.slice(0, match.index) + - `## v${newVersion} (${today})\n` + - changelog.slice(match.index + match[0].length); - - fs.writeFileSync(changelogPath, changelog); - logAndExec(`git add ${changelogPath}`); -} - -// 4) Update jsr.json (if applicable) with the new release version -let jsrJsonPath = path.relative(process.cwd(), path.join(packageDir, 'jsr.json')); -if (fs.existsSync(jsrJsonPath)) { - let jsrJson = JSON.parse(fs.readFileSync(jsrJsonPath, 'utf-8')); - jsrJson.version = newVersion; - fs.writeFileSync(jsrJsonPath, JSON.stringify(jsrJson, null, 2) + '\n'); - logAndExec(`git add ${jsrJsonPath}`); -} - -// 5) Commit and tag -let tag = `${packageNameWithoutScope}@${newVersion}`; -logAndExec(`git commit -m "Release ${tag}"`); -logAndExec(`git tag ${tag}`); - -console.log(); diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json index d8aaef54f9d..527a5af7a81 100644 --- a/scripts/tsconfig.json +++ b/scripts/tsconfig.json @@ -3,6 +3,9 @@ "lib": ["DOM", "ES2020"], "module": "NodeNext", "moduleResolution": "NodeNext", - "strict": true + "strict": true, + "allowJs": true, + "checkJs": true, + "noEmit": true } } diff --git a/scripts/utils/changes.js b/scripts/utils/changes.js new file mode 100644 index 00000000000..677efcda327 --- /dev/null +++ b/scripts/utils/changes.js @@ -0,0 +1,43 @@ +import { hasChangelog, readChangelog } from './packages.js'; + +/** @typedef {Record<string, Changes>} AllChanges */ + +/** @type (packageName: string) => AllChanges | null */ +export function getAllChanges(packageName) { + if (!hasChangelog(packageName)) { + return null; + } + + let changelog = readChangelog(packageName); + let parser = /^## ([a-z\d\.\-]+)(?: \(([^)]+)\))?$/gim; + + /** @type {AllChanges} */ + let result = {}; + + let match; + while ((match = parser.exec(changelog))) { + let [_, versionString, dateString] = match; + let lastIndex = parser.lastIndex; + let version = versionString.startsWith('v') ? versionString.slice(1) : versionString; + let date = dateString ? new Date(dateString) : undefined; + let nextMatch = parser.exec(changelog); + let changes = changelog.slice(lastIndex, nextMatch ? nextMatch.index : undefined).trim(); + result[version] = { version, date, changes }; + parser.lastIndex = lastIndex; + } + + return result; +} + +/** @typedef {{ version: string; date?: Date; changes: string }} Changes */ + +/** @type (packageName: string, version: string) => Changes | null */ +export function getChanges(packageName, version) { + let allChanges = getAllChanges(packageName); + + if (allChanges !== null) { + return allChanges[version] ?? null; + } + + return null; +} diff --git a/scripts/utils/packages.js b/scripts/utils/packages.js new file mode 100644 index 00000000000..a70e3b1a485 --- /dev/null +++ b/scripts/utils/packages.js @@ -0,0 +1,90 @@ +import * as fs from 'node:fs'; +import * as path from 'node:path'; + +const __dirname = path.dirname(new URL(import.meta.url).pathname); + +export const packagesDir = path.relative( + process.cwd(), + path.resolve(__dirname, '..', '..', 'packages'), +); + +/** @type (packageName: string) => string */ +export function getPackageDir(packageName) { + return path.resolve(packagesDir, packageName); +} + +/** @type (packageName: string, filename: string) => string */ +export function getPackageFile(packageName, filename) { + return path.join(getPackageDir(packageName), filename); +} + +/** @type (packageName: string) => boolean */ +export function hasChangelog(packageName) { + return fs.existsSync(getPackageFile(packageName, 'CHANGELOG.md')); +} + +/** @type (packageName: string) => string */ +export function readChangelog(packageName) { + return fs.readFileSync(getPackageFile(packageName, 'CHANGELOG.md'), 'utf-8'); +} + +/** @type (packageName: string, data: string) => void */ +export function writeChangelog(packageName, data) { + fs.writeFileSync(getPackageFile(packageName, 'CHANGELOG.md'), data); +} + +/** @type (packageName: string) => boolean */ +export function hasJsrJson(packageName) { + return fs.existsSync(getPackageFile(packageName, 'jsr.json')); +} + +/** @type (packageName: string) => any */ +export function readJsrJson(packageName) { + return readJson(getPackageFile(packageName, 'jsr.json')); +} + +/** @type (packageName: string, data: any) => void */ +export function writeJsrJson(packageName, data) { + writeJson(getPackageFile(packageName, 'jsr.json'), data); +} + +/** @type (packageName: string) => boolean */ +export function hasPackageJson(packageName) { + return fs.existsSync(getPackageFile(packageName, 'package.json')); +} + +/** @type (packageName: string) => any */ +export function readPackageJson(packageName) { + return readJson(getPackageFile(packageName, 'package.json')); +} + +/** @type (packageName: string, data: any) => void */ +export function writePackageJson(packageName, data) { + writeJson(getPackageFile(packageName, 'package.json'), data); +} + +/** @type (file: string) => any */ +function readJson(file) { + try { + return JSON.parse(fs.readFileSync(file, 'utf-8')); + } catch (error) { + if (isFsError(error) && error.code === 'ENOENT') { + console.error(`Not found: "${file}"`); + process.exit(1); + } else { + throw error; + } + } +} + +/** @type (filename: string, data: any) => void */ +function writeJson(filename, data) { + fs.writeFileSync(filename, JSON.stringify(data, null, 2) + '\n'); +} + +/** @type (error: unknown) => error is { code: string } */ +function isFsError(error) { + return ( + typeof error === 'object' && error != null && 'code' in error && typeof error.code === 'string' + ); +} diff --git a/scripts/utils/semver.js b/scripts/utils/semver.js new file mode 100644 index 00000000000..c24bf3981b5 --- /dev/null +++ b/scripts/utils/semver.js @@ -0,0 +1,17 @@ +import * as semver from 'semver'; + +/** @type (version: string) => boolean */ +export function isValidVersion(version) { + return semver.valid(version) !== null; +} + +/** @type (currentVersion: string, releaseType: string) => string */ +export function getNextVersion(currentVersion, releaseType) { + let nextVersion = semver.inc(currentVersion, /** @type {semver.ReleaseType} */ (releaseType)); + + if (nextVersion == null) { + throw new Error(`Invalid version increment: ${currentVersion} + ${releaseType}`); + } + + return nextVersion; +} diff --git a/scripts/version.js b/scripts/version.js new file mode 100644 index 00000000000..e8f7e320356 --- /dev/null +++ b/scripts/version.js @@ -0,0 +1,73 @@ +import * as cp from 'node:child_process'; + +import { + getPackageFile, + readChangelog, + writeChangelog, + hasJsrJson, + readJsrJson, + writeJsrJson, + readPackageJson, + writePackageJson, +} from './utils/packages.js'; +import { getNextVersion } from './utils/semver.js'; + +const packageName = process.argv[2]; +const releaseType = process.argv[3]; + +if (packageName === undefined || releaseType === undefined) { + console.error('Usage: node version.js <packageName> <releaseType>'); + process.exit(1); +} + +const packageJson = readPackageJson(packageName); +const nextVersion = getNextVersion(packageJson.version, releaseType); +const tag = `${packageName}@${nextVersion}`; + +// 1) Ensure git staging area is clean +let status = cp.execSync('git status --porcelain').toString(); +if (status !== '') { + console.error('Git staging area is not clean'); + process.exit(1); +} + +console.log(`Releasing ${tag} ...`); +console.log(); + +/** @type (command: string) => void */ +function logAndExec(command) { + console.log(`$ ${command}`); + cp.execSync(command, { stdio: 'inherit' }); +} + +// 2) Update package.json with the new release version +writePackageJson(packageName, { ...packageJson, version: nextVersion }); +logAndExec(`git add ${getPackageFile(packageName, 'package.json')}`); + +// 4) Update jsr.json (if applicable) with the new release version +if (hasJsrJson(packageName)) { + let jsrJson = readJsrJson(packageName); + writeJsrJson(packageName, { ...jsrJson, version: nextVersion }); + logAndExec(`git add ${getPackageFile(packageName, 'jsr.json')}`); +} + +// 3) Swap out "## HEAD" in CHANGELOG.md with the new release version + date +let changelog = readChangelog(packageName); +let match = /^## HEAD\n/m.exec(changelog); +if (match) { + let [today] = new Date().toISOString().split('T'); + + changelog = + changelog.slice(0, match.index) + + `## v${nextVersion} (${today})\n` + + changelog.slice(match.index + match[0].length); + + writeChangelog(packageName, changelog); + logAndExec(`git add ${getPackageFile(packageName, 'CHANGELOG.md')}`); +} + +// 5) Commit and tag +logAndExec(`git commit -m "Release ${tag}"`); +logAndExec(`git tag ${tag}`); + +console.log(); From 8d956dffe862ce087c3237ac091dc85e908fd52e Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 07:15:19 -0800 Subject: [PATCH 484/730] Fixup changelogs --- packages/fetch-proxy/CHANGELOG.md | 4 ++++ packages/file-storage/CHANGELOG.md | 4 ++++ packages/form-data-parser/CHANGELOG.md | 4 ++++ packages/headers/CHANGELOG.md | 4 ++++ packages/lazy-file/CHANGELOG.md | 4 ++++ packages/multipart-parser/CHANGELOG.md | 4 ++++ packages/node-fetch-server/CHANGELOG.md | 4 ++++ 7 files changed, 28 insertions(+) diff --git a/packages/fetch-proxy/CHANGELOG.md b/packages/fetch-proxy/CHANGELOG.md index 78594319f91..35769b1351f 100644 --- a/packages/fetch-proxy/CHANGELOG.md +++ b/packages/fetch-proxy/CHANGELOG.md @@ -1,3 +1,7 @@ +# `fetch-proxy` CHANGELOG + +This is the changelog for [`fetch-proxy`](https://github.com/mjackson/remix-the-web/tree/main/packages/fetch-proxy). It follows [semantic versioning](https://semver.org/). + ## v0.2.0 (2024-11-14) - Added CommonJS build diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index a1c2bc83b56..c35157d499b 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -1,3 +1,7 @@ +# `file-storage` CHANGELOG + +This is the changelog for [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage). It follows [semantic versioning](https://semver.org/). + ## v0.3.0 (2024-11-14) - Added CommonJS build diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index a9d62d5fb3e..746f5b55230 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -1,3 +1,7 @@ +# `form-data-parser` CHANGELOG + +This is the changelog for [`form-data-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser). It follows [semantic versioning](https://semver.org/). + ## v0.5.0 (2024-11-14) - Added CommonJS build diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index e6783ce4a42..ecf88b7c3a1 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -1,3 +1,7 @@ +# `headers` CHANGELOG + +This is the changelog for [`headers`](https://github.com/mjackson/remix-the-web/tree/main/packages/headers). It follows [semantic versioning](https://semver.org/). + ## v0.8.0 (2024-11-14) - Added CommonJS build diff --git a/packages/lazy-file/CHANGELOG.md b/packages/lazy-file/CHANGELOG.md index bf0e2f120f1..1653b32dd0a 100644 --- a/packages/lazy-file/CHANGELOG.md +++ b/packages/lazy-file/CHANGELOG.md @@ -1,3 +1,7 @@ +# `lazy-file` CHANGELOG + +This is the changelog for [`lazy-file`](https://github.com/mjackson/remix-the-web/tree/main/packages/lazy-file). It follows [semantic versioning](https://semver.org/). + ## v3.3.0 (2024-11-14) - Added CommonJS build diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index b6cfaeb7ca8..ad68d7cf970 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -1,3 +1,7 @@ +# `multipart-parser` CHANGELOG + +This is the changelog for [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser). It follows [semantic versioning](https://semver.org/). + ## v0.7.0 (2024-11-14) - Added CommonJS build diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 2753cc3837f..77783385194 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -1,3 +1,7 @@ +# `node-fetch-server` CHANGELOG + +This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server). It follows [semantic versioning](https://semver.org/). + ## v0.3.0 (2024-11-20) - Added low-level `createRequest(req, options)` and `sendResponse(res, response)` exports to assist with building custom fetch servers on Node.js From 9e01be5e0b3037cf14a14e302f0b741c580a4473 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 07:56:23 -0800 Subject: [PATCH 485/730] Fix request abort signal firing too early --- packages/node-fetch-server/CHANGELOG.md | 6 +++++- .../node-fetch-server/src/lib/request-listener.ts | 11 ++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 77783385194..9a13d2799b9 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -2,9 +2,13 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server). It follows [semantic versioning](https://semver.org/). +## HEAD + +- BREAKING: Change new low-level API `createRequest(req, options)` to `createRequest(req, res, options)` so the abort signal fires on the `res`'s "end" event instead of `req` + ## v0.3.0 (2024-11-20) -- Added low-level `createRequest(req, options)` and `sendResponse(res, response)` exports to assist with building custom fetch servers on Node.js +- Added low-level `createRequest(req, options)` and `sendResponse(res, response)` exports to assist with building custom fetch servers ## v0.2.0 (2024-11-14) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index f88001d06c7..8dfea721303 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -58,7 +58,7 @@ export function createRequestListener( let onError = options?.onError ?? defaultErrorHandler; return async (req, res) => { - let request = createRequest(req, options); + let request = createRequest(req, res, options); let client = { address: req.socket.remoteAddress!, family: req.socket.remoteFamily! as ClientAddress['family'], @@ -107,12 +107,17 @@ export type RequestOptions = Omit<RequestListenerOptions, 'onError'>; /** * Creates a `Request` object from an incoming Node.js request object. * @param req The incoming request object. + * @param res The server response object. * @param options * @returns A `Request` object. */ -export function createRequest(req: http.IncomingMessage, options?: RequestOptions): Request { +export function createRequest( + req: http.IncomingMessage, + res: http.ServerResponse, + options?: RequestOptions, +): Request { let controller = new AbortController(); - req.on('close', () => { + res.on('close', () => { controller.abort(); }); From 5b998a070b62be5696e49a7e5018b8195ac31ce2 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 08:05:19 -0800 Subject: [PATCH 486/730] Add version script --- packages/node-fetch-server/package.json | 3 ++- scripts/version.js | 14 +++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 624a899c591..5d706b3e162 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -49,7 +49,8 @@ "bench": "bash ./bench/runner.sh", "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build" + "prepare": "pnpm run build", + "version": "node ../../scripts/version.js $npm_package_name" }, "keywords": [ "http", diff --git a/scripts/version.js b/scripts/version.js index e8f7e320356..109e54934e7 100644 --- a/scripts/version.js +++ b/scripts/version.js @@ -12,17 +12,21 @@ import { } from './utils/packages.js'; import { getNextVersion } from './utils/semver.js'; -const packageName = process.argv[2]; -const releaseType = process.argv[3]; +let packageName = process.argv[2]; +let releaseType = process.argv[3]; + +if (typeof packageName === 'string' && packageName.startsWith('@mjackson/')) { + packageName = packageName.slice('@mjackson/'.length); +} if (packageName === undefined || releaseType === undefined) { console.error('Usage: node version.js <packageName> <releaseType>'); process.exit(1); } -const packageJson = readPackageJson(packageName); -const nextVersion = getNextVersion(packageJson.version, releaseType); -const tag = `${packageName}@${nextVersion}`; +let packageJson = readPackageJson(packageName); +let nextVersion = getNextVersion(packageJson.version, releaseType); +let tag = `${packageName}@${nextVersion}`; // 1) Ensure git staging area is clean let status = cp.execSync('git status --porcelain').toString(); From 23230411a0cfece999a420bcc0f51bc6a5a59034 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 08:05:25 -0800 Subject: [PATCH 487/730] Release node-fetch-server@0.4.0 --- packages/node-fetch-server/CHANGELOG.md | 2 +- packages/node-fetch-server/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 9a13d2799b9..3e8e3f4442b 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.4.0 (2024-11-26) - BREAKING: Change new low-level API `createRequest(req, options)` to `createRequest(req, res, options)` so the abort signal fires on the `res`'s "end" event instead of `req` diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 5d706b3e162..90501025a5c 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/node-fetch-server", - "version": "0.3.0", + "version": "0.4.0", "description": "Build servers for Node.js using the web fetch API", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From ddad825d092537230dde7589f50f00e8f31c5be0 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 08:16:46 -0800 Subject: [PATCH 488/730] Add version script to all packages --- packages/fetch-proxy/package.json | 3 ++- packages/file-storage/package.json | 3 ++- packages/form-data-parser/package.json | 3 ++- packages/headers/package.json | 3 ++- packages/lazy-file/package.json | 3 ++- packages/multipart-parser/package.json | 3 ++- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/fetch-proxy/package.json b/packages/fetch-proxy/package.json index cbdec6b960d..8a7027503fe 100644 --- a/packages/fetch-proxy/package.json +++ b/packages/fetch-proxy/package.json @@ -51,7 +51,8 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build" + "prepare": "pnpm run build", + "version": "node ../../scripts/version.js $npm_package_name" }, "keywords": [ "fetch", diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index 4ab180cbb7c..2fce02ab473 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -87,7 +87,8 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build" + "prepare": "pnpm run build", + "version": "node ../../scripts/version.js $npm_package_name" }, "keywords": [ "file", diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index 81168494aa3..409ce7116e2 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -51,7 +51,8 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build" + "prepare": "pnpm run build", + "version": "node ../../scripts/version.js $npm_package_name" }, "keywords": [ "form-data", diff --git a/packages/headers/package.json b/packages/headers/package.json index 698dc8763aa..56c8ead80e3 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -48,7 +48,8 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build" + "prepare": "pnpm run build", + "version": "node ../../scripts/version.js $npm_package_name" }, "keywords": [ "fetch", diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index 0bb5cfb785e..786ec44476f 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -69,7 +69,8 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build" + "prepare": "pnpm run build", + "version": "node ../../scripts/version.js $npm_package_name" }, "keywords": [ "file", diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 038403d6555..5ae5f621df2 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -73,7 +73,8 @@ "bench:node": "node --import @swc-node/register/esm-register ./bench/runner.ts", "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build" + "prepare": "pnpm run build", + "version": "node ../../scripts/version.js $npm_package_name" }, "keywords": [ "multipart", From 13380a8c92f2e9250ccb80b0144c5fb5d9e30c28 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 07:56:48 -0800 Subject: [PATCH 489/730] wip --- scripts/publish.js | 57 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 scripts/publish.js diff --git a/scripts/publish.js b/scripts/publish.js new file mode 100644 index 00000000000..3f7d29e72f3 --- /dev/null +++ b/scripts/publish.js @@ -0,0 +1,57 @@ +import * as cp from 'node:child_process'; + +import { hasJsrJson, readJsrJson, readPackageJson } from './utils/packages.js'; +import { isValidVersion } from './utils/semver.js'; + +const tag = process.argv[2]; + +if (tag === undefined) { + console.error('Usage: node publish.js <tag>'); + process.exit(1); +} + +const [packageName, version] = tag.split('@'); + +if (packageName === undefined || packageName === '' || !isValidVersion(version)) { + console.error(`Invalid tag: ${tag}`); + process.exit(1); +} + +// 1) Ensure we are on the right tag +let currentTags = cp.execSync('git tag --points-at HEAD').toString().trim().split('\n'); +if (!currentTags.includes(tag)) { + console.error(`Tag not found: ${tag}`); + process.exit(1); +} + +// 2) Build the package +console.log(`Building ${packageName}@${version} ...`); + +// 3) Publish to npm +let packageJson = readPackageJson(packageName); +if (packageJson.version !== version) { + console.error( + `Tag does not match package.json version: ${version} !== ${packageJson.version} (${tag})`, + ); + process.exit(1); +} + +console.log(`Publishing ${packageName}@${version} to npm ...`); + +// 4) Publish to jsr (if applicable) +if (hasJsrJson(packageName)) { + let jsrJson = readJsrJson(packageName); + if (jsrJson.version !== version) { + console.error( + `Tag does not match jsr.json version: ${version} !== ${jsrJson.version} (${tag})`, + ); + process.exit(1); + } + + console.log(`Publishing ${packageName}@${version} to jsr ...`); +} + +// 5) Publish to GitHub Releases +console.log(`Publishing ${packageName}@${version} to GitHub Releases ...`); + +console.log(); From 0ede91967d738c684ff8be158c7b2cac958829ae Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 16:43:59 -0800 Subject: [PATCH 490/730] Add support for .env file --- .env.example | 2 ++ .gitignore | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 00000000000..2d545af4f9f --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +# This is needed to publish to GitHub Releases using scripts/publish.js +GITHUB_TOKEN=your_github_token diff --git a/.gitignore b/.gitignore index 74d9c201ad9..25a0b28ec3c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,4 @@ **/*.tsbuildinfo -.nx/cache -.nx/workspace-data \ No newline at end of file +.env From 3b21455d4151e2164a7c50e425dd8254ca30a4ec Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 16:49:40 -0800 Subject: [PATCH 491/730] Add publish script --- pnpm-lock.yaml | 48 ++++++++++++++++++++++++++++++++ scripts/package.json | 1 + scripts/publish.js | 39 ++++++++++++++++++-------- scripts/utils/github-releases.js | 32 +++++++++++++++++++++ scripts/utils/process.js | 7 +++++ scripts/version.js | 7 +---- 6 files changed, 116 insertions(+), 18 deletions(-) create mode 100644 scripts/utils/github-releases.js create mode 100644 scripts/utils/process.js diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7070f5818b1..f33448354c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -247,6 +247,9 @@ importers: scripts: dependencies: + '@octokit/request': + specifier: ^9.1.3 + version: 9.1.3 '@types/node': specifier: ^22.5.4 version: 22.5.4 @@ -634,6 +637,24 @@ packages: '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} + '@octokit/endpoint@10.1.1': + resolution: {integrity: sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==} + engines: {node: '>= 18'} + + '@octokit/openapi-types@22.2.0': + resolution: {integrity: sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==} + + '@octokit/request-error@6.1.5': + resolution: {integrity: sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ==} + engines: {node: '>= 18'} + + '@octokit/request@9.1.3': + resolution: {integrity: sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==} + engines: {node: '>= 18'} + + '@octokit/types@13.6.2': + resolution: {integrity: sha512-WpbZfZUcZU77DrSW4wbsSgTPfKcp286q3ItaIgvSbBpZJlu6mnYXAkjZz6LVZPXkEvLIM8McanyZejKTYUHipA==} + '@oxc-resolver/binding-darwin-arm64@1.11.0': resolution: {integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==} cpu: [arm64] @@ -1737,6 +1758,9 @@ packages: unenv-nightly@1.10.0-1717606461.a117952: resolution: {integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==} + universal-user-agent@7.0.2: + resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==} + unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} @@ -2039,6 +2063,28 @@ snapshots: '@tybys/wasm-util': 0.9.0 optional: true + '@octokit/endpoint@10.1.1': + dependencies: + '@octokit/types': 13.6.2 + universal-user-agent: 7.0.2 + + '@octokit/openapi-types@22.2.0': {} + + '@octokit/request-error@6.1.5': + dependencies: + '@octokit/types': 13.6.2 + + '@octokit/request@9.1.3': + dependencies: + '@octokit/endpoint': 10.1.1 + '@octokit/request-error': 6.1.5 + '@octokit/types': 13.6.2 + universal-user-agent: 7.0.2 + + '@octokit/types@13.6.2': + dependencies: + '@octokit/openapi-types': 22.2.0 + '@oxc-resolver/binding-darwin-arm64@1.11.0': optional: true @@ -3129,6 +3175,8 @@ snapshots: pathe: 1.1.2 ufo: 1.5.4 + universal-user-agent@7.0.2: {} + unpipe@1.0.0: {} utils-merge@1.0.1: {} diff --git a/scripts/package.json b/scripts/package.json index 18d638c99f8..abd99570688 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -3,6 +3,7 @@ "private": true, "type": "module", "dependencies": { + "@octokit/request": "^9.1.3", "@types/node": "^22.5.4", "@types/semver": "^7.5.8", "semver": "^7.6.3" diff --git a/scripts/publish.js b/scripts/publish.js index 3f7d29e72f3..04eea64a515 100644 --- a/scripts/publish.js +++ b/scripts/publish.js @@ -1,33 +1,42 @@ import * as cp from 'node:child_process'; -import { hasJsrJson, readJsrJson, readPackageJson } from './utils/packages.js'; +import { createRelease } from './utils/github-releases.js'; +import { getPackageDir, hasJsrJson, readJsrJson, readPackageJson } from './utils/packages.js'; +import { logAndExec } from './utils/process.js'; import { isValidVersion } from './utils/semver.js'; -const tag = process.argv[2]; +let tag = process.argv[2]; if (tag === undefined) { console.error('Usage: node publish.js <tag>'); process.exit(1); } -const [packageName, version] = tag.split('@'); +let [packageName, version] = tag.split('@'); if (packageName === undefined || packageName === '' || !isValidVersion(version)) { console.error(`Invalid tag: ${tag}`); process.exit(1); } -// 1) Ensure we are on the right tag +// 1) Ensure git staging area is clean +let status = cp.execSync('git status --porcelain').toString(); +if (status !== '') { + console.error('Git staging area is not clean'); + process.exit(1); +} + +// 2) Ensure we are on the right tag let currentTags = cp.execSync('git tag --points-at HEAD').toString().trim().split('\n'); if (!currentTags.includes(tag)) { - console.error(`Tag not found: ${tag}`); + console.error(`Tag "${tag}" does not point to HEAD`); process.exit(1); } -// 2) Build the package +// 3) Build the package console.log(`Building ${packageName}@${version} ...`); -// 3) Publish to npm +// 4) Publish to npm let packageJson = readPackageJson(packageName); if (packageJson.version !== version) { console.error( @@ -36,9 +45,11 @@ if (packageJson.version !== version) { process.exit(1); } -console.log(`Publishing ${packageName}@${version} to npm ...`); +logAndExec(`pnpm publish --access public`, { + cwd: getPackageDir(packageName), +}); -// 4) Publish to jsr (if applicable) +// 5) Publish to jsr (if applicable) if (hasJsrJson(packageName)) { let jsrJson = readJsrJson(packageName); if (jsrJson.version !== version) { @@ -48,10 +59,14 @@ if (hasJsrJson(packageName)) { process.exit(1); } - console.log(`Publishing ${packageName}@${version} to jsr ...`); + logAndExec(`pnpm dlx jsr publish`, { + cwd: getPackageDir(packageName), + }); } -// 5) Publish to GitHub Releases -console.log(`Publishing ${packageName}@${version} to GitHub Releases ...`); +// 6) Publish to GitHub Releases +console.log(`Publishing tag ${tag} on GitHub Releases ...`); + +await createRelease(packageName, version); console.log(); diff --git a/scripts/utils/github-releases.js b/scripts/utils/github-releases.js new file mode 100644 index 00000000000..0fd44425b9d --- /dev/null +++ b/scripts/utils/github-releases.js @@ -0,0 +1,32 @@ +import { request } from '@octokit/request'; + +import { getChanges } from './changes.js'; + +const token = process.env.GITHUB_TOKEN; + +/** @type (packageName: string, version: string) => Promise<void> */ +export async function createRelease(packageName, version) { + if (token === undefined) { + console.error('GITHUB_TOKEN environment variable is required to create a release'); + process.exit(1); + } + + let tagName = `${packageName}@${version}`; + let changes = getChanges(packageName, version); + + let response = await request('POST /repos/{owner}/{repo}/releases', { + headers: { + authorization: `token ${token}`, + }, + owner: 'mjackson', + repo: 'remix-the-web', + tag_name: tagName, + name: `${packageName} v${version}`, + body: changes?.changes ?? 'No changes.', + }); + + if (response.status !== 201) { + console.error('Failed to create release:', response); + process.exit(1); + } +} diff --git a/scripts/utils/process.js b/scripts/utils/process.js new file mode 100644 index 00000000000..63ed06bbd8e --- /dev/null +++ b/scripts/utils/process.js @@ -0,0 +1,7 @@ +import * as cp from 'node:child_process'; + +/** @type (command: string, options?: cp.ExecSyncOptions) => void */ +export function logAndExec(command, options) { + console.log(`$ ${command}`); + cp.execSync(command, { stdio: 'inherit', ...options }); +} diff --git a/scripts/version.js b/scripts/version.js index 109e54934e7..01d7ab3536b 100644 --- a/scripts/version.js +++ b/scripts/version.js @@ -10,6 +10,7 @@ import { readPackageJson, writePackageJson, } from './utils/packages.js'; +import { logAndExec } from './utils/process.js'; import { getNextVersion } from './utils/semver.js'; let packageName = process.argv[2]; @@ -38,12 +39,6 @@ if (status !== '') { console.log(`Releasing ${tag} ...`); console.log(); -/** @type (command: string) => void */ -function logAndExec(command) { - console.log(`$ ${command}`); - cp.execSync(command, { stdio: 'inherit' }); -} - // 2) Update package.json with the new release version writePackageJson(packageName, { ...packageJson, version: nextVersion }); logAndExec(`git add ${getPackageFile(packageName, 'package.json')}`); From 7bc156daec551ae0101c2abc40b3dffb3434ed73 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 16:56:07 -0800 Subject: [PATCH 492/730] Add new test package for version/publish scripts --- packages/scripts-test/CHANGELOG.md | 7 +++ packages/scripts-test/LICENSE | 21 ++++++++ packages/scripts-test/README.md | 3 ++ packages/scripts-test/package.json | 53 +++++++++++++++++++ packages/scripts-test/src/lib/scripts-test.ts | 1 + packages/scripts-test/src/scripts-test.ts | 1 + packages/scripts-test/tsconfig.json | 8 +++ packages/scripts-test/tsconfig.lib.json | 9 ++++ packages/scripts-test/tsconfig.spec.json | 8 +++ packages/scripts-test/tsup.config.ts | 11 ++++ pnpm-lock.yaml | 15 ++++++ 11 files changed, 137 insertions(+) create mode 100644 packages/scripts-test/CHANGELOG.md create mode 100644 packages/scripts-test/LICENSE create mode 100644 packages/scripts-test/README.md create mode 100644 packages/scripts-test/package.json create mode 100644 packages/scripts-test/src/lib/scripts-test.ts create mode 100644 packages/scripts-test/src/scripts-test.ts create mode 100644 packages/scripts-test/tsconfig.json create mode 100644 packages/scripts-test/tsconfig.lib.json create mode 100644 packages/scripts-test/tsconfig.spec.json create mode 100644 packages/scripts-test/tsup.config.ts diff --git a/packages/scripts-test/CHANGELOG.md b/packages/scripts-test/CHANGELOG.md new file mode 100644 index 00000000000..1f7b3e630a0 --- /dev/null +++ b/packages/scripts-test/CHANGELOG.md @@ -0,0 +1,7 @@ +# `scripts-test` CHANGELOG + +This package is only for testing the version and publish scripts. + +## HEAD + +Initial release. diff --git a/packages/scripts-test/LICENSE b/packages/scripts-test/LICENSE new file mode 100644 index 00000000000..717984c0442 --- /dev/null +++ b/packages/scripts-test/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Michael Jackson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/scripts-test/README.md b/packages/scripts-test/README.md new file mode 100644 index 00000000000..12c4014949a --- /dev/null +++ b/packages/scripts-test/README.md @@ -0,0 +1,3 @@ +# scripts-test + +This is a test package for the version/publish scripts. diff --git a/packages/scripts-test/package.json b/packages/scripts-test/package.json new file mode 100644 index 00000000000..1361eb82fea --- /dev/null +++ b/packages/scripts-test/package.json @@ -0,0 +1,53 @@ +{ + "name": "@mjackson/scripts-test", + "version": "0.0.0", + "description": "Test package for version/publish scripts", + "author": "Michael Jackson <mjijackson@gmail.com>", + "repository": { + "type": "git", + "url": "git+https://github.com/mjackson/remix-the-web.git", + "directory": "packages/scripts-test" + }, + "homepage": "https://github.com/mjackson/remix-the-web/tree/main/packages/scripts-test#readme", + "license": "MIT", + "files": [ + "dist", + "LICENSE", + "README.md" + ], + "type": "module", + "types": "./dist/scripts-test.d.ts", + "main": "./dist/scripts-test.js", + "exports": { + ".": { + "module-sync": { + "types": "./dist/scripts-test.d.ts", + "default": "./dist/scripts-test.js" + }, + "import": { + "types": "./dist/scripts-test.d.ts", + "default": "./dist/scripts-test.js" + }, + "require": { + "types": "./dist/scripts-test.d.cts", + "default": "./dist/scripts-test.cjs" + }, + "default": { + "types": "./dist/scripts-test.d.ts", + "default": "./dist/scripts-test.js" + } + }, + "./package.json": "./package.json" + }, + "devDependencies": { + "@swc-node/register": "^1.10.9", + "@types/node": "^22.5.0", + "tsup": "^8.3.5", + "typescript": "^5.6.3" + }, + "scripts": { + "build": "tsup", + "prepare": "pnpm run build", + "version": "node ../../scripts/version.js $npm_package_name" + } +} diff --git a/packages/scripts-test/src/lib/scripts-test.ts b/packages/scripts-test/src/lib/scripts-test.ts new file mode 100644 index 00000000000..51f71ea572f --- /dev/null +++ b/packages/scripts-test/src/lib/scripts-test.ts @@ -0,0 +1 @@ +export const message = 'Hello, world!'; diff --git a/packages/scripts-test/src/scripts-test.ts b/packages/scripts-test/src/scripts-test.ts new file mode 100644 index 00000000000..f9afb5968b6 --- /dev/null +++ b/packages/scripts-test/src/scripts-test.ts @@ -0,0 +1 @@ +export { message } from './lib/scripts-test.js'; diff --git a/packages/scripts-test/tsconfig.json b/packages/scripts-test/tsconfig.json new file mode 100644 index 00000000000..d8aaef54f9d --- /dev/null +++ b/packages/scripts-test/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "lib": ["DOM", "ES2020"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true + } +} diff --git a/packages/scripts-test/tsconfig.lib.json b/packages/scripts-test/tsconfig.lib.json new file mode 100644 index 00000000000..8e712f7d6c8 --- /dev/null +++ b/packages/scripts-test/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.spec.ts"], + "compilerOptions": { + "composite": true, + "rootDir": "src" + } +} diff --git a/packages/scripts-test/tsconfig.spec.json b/packages/scripts-test/tsconfig.spec.json new file mode 100644 index 00000000000..ccfefc4d957 --- /dev/null +++ b/packages/scripts-test/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.spec.ts"], + "compilerOptions": { + "composite": true, + "types": ["node"] + } +} diff --git a/packages/scripts-test/tsup.config.ts b/packages/scripts-test/tsup.config.ts new file mode 100644 index 00000000000..1af2073b066 --- /dev/null +++ b/packages/scripts-test/tsup.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig([ + { + clean: true, + dts: true, + entry: ['src/scripts-test.ts'], + format: ['cjs', 'esm'], + platform: 'neutral', + }, +]); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f33448354c5..83406ec0fbe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -245,6 +245,21 @@ importers: specifier: ^4.17.21 version: 4.17.21 + packages/scripts-test: + devDependencies: + '@swc-node/register': + specifier: ^1.10.9 + version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) + '@types/node': + specifier: ^22.5.0 + version: 22.5.4 + tsup: + specifier: ^8.3.5 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) + typescript: + specifier: ^5.6.3 + version: 5.6.3 + scripts: dependencies: '@octokit/request': From 211cae972f260a0460d582b2552c6dc7c3aa97ee Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 17:04:27 -0800 Subject: [PATCH 493/730] Add publish script --- packages/scripts-test/package.json | 3 ++- scripts/publish.js | 20 ++++++++------------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/packages/scripts-test/package.json b/packages/scripts-test/package.json index 1361eb82fea..3ddfa3224e0 100644 --- a/packages/scripts-test/package.json +++ b/packages/scripts-test/package.json @@ -48,6 +48,7 @@ "scripts": { "build": "tsup", "prepare": "pnpm run build", - "version": "node ../../scripts/version.js $npm_package_name" + "version": "node ../../scripts/version.js $npm_package_name", + "publish": "node ../../scripts/publish.js $npm_package_name $npm_package_version" } } diff --git a/scripts/publish.js b/scripts/publish.js index 04eea64a515..b24f77820b4 100644 --- a/scripts/publish.js +++ b/scripts/publish.js @@ -5,14 +5,14 @@ import { getPackageDir, hasJsrJson, readJsrJson, readPackageJson } from './utils import { logAndExec } from './utils/process.js'; import { isValidVersion } from './utils/semver.js'; -let tag = process.argv[2]; +let packageName = process.argv[2]; +let version = process.argv[3]; -if (tag === undefined) { - console.error('Usage: node publish.js <tag>'); - process.exit(1); +if (typeof packageName === 'string' && packageName.startsWith('@mjackson/')) { + packageName = packageName.slice('@mjackson/'.length); } -let [packageName, version] = tag.split('@'); +let tag = `${packageName}@${version}`; if (packageName === undefined || packageName === '' || !isValidVersion(version)) { console.error(`Invalid tag: ${tag}`); @@ -33,10 +33,7 @@ if (!currentTags.includes(tag)) { process.exit(1); } -// 3) Build the package -console.log(`Building ${packageName}@${version} ...`); - -// 4) Publish to npm +// 3) Publish to npm let packageJson = readPackageJson(packageName); if (packageJson.version !== version) { console.error( @@ -49,7 +46,7 @@ logAndExec(`pnpm publish --access public`, { cwd: getPackageDir(packageName), }); -// 5) Publish to jsr (if applicable) +// 4) Publish to jsr (if applicable) if (hasJsrJson(packageName)) { let jsrJson = readJsrJson(packageName); if (jsrJson.version !== version) { @@ -64,9 +61,8 @@ if (hasJsrJson(packageName)) { }); } -// 6) Publish to GitHub Releases +// 5) Publish to GitHub Releases console.log(`Publishing tag ${tag} on GitHub Releases ...`); - await createRelease(packageName, version); console.log(); From bdd972c9da4847d72d8a523704d27f7abce37f18 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 17:05:55 -0800 Subject: [PATCH 494/730] Release scripts-test@0.1.0 --- packages/scripts-test/CHANGELOG.md | 2 +- packages/scripts-test/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/scripts-test/CHANGELOG.md b/packages/scripts-test/CHANGELOG.md index 1f7b3e630a0..3f4d299aac4 100644 --- a/packages/scripts-test/CHANGELOG.md +++ b/packages/scripts-test/CHANGELOG.md @@ -2,6 +2,6 @@ This package is only for testing the version and publish scripts. -## HEAD +## v0.1.0 (2024-11-27) Initial release. diff --git a/packages/scripts-test/package.json b/packages/scripts-test/package.json index 3ddfa3224e0..40c83daa19f 100644 --- a/packages/scripts-test/package.json +++ b/packages/scripts-test/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/scripts-test", - "version": "0.0.0", + "version": "0.1.0", "description": "Test package for version/publish scripts", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From 3de65fa1853fa6266a7ce240496f70210c3fdf74 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 17:25:43 -0800 Subject: [PATCH 495/730] Rename publish => release --- packages/scripts-test/package.json | 2 +- scripts/{publish.js => release.js} | 7 ++++++- scripts/version.js | 8 ++++---- 3 files changed, 11 insertions(+), 6 deletions(-) rename scripts/{publish.js => release.js} (90%) diff --git a/packages/scripts-test/package.json b/packages/scripts-test/package.json index 40c83daa19f..2bfdca48bc8 100644 --- a/packages/scripts-test/package.json +++ b/packages/scripts-test/package.json @@ -49,6 +49,6 @@ "build": "tsup", "prepare": "pnpm run build", "version": "node ../../scripts/version.js $npm_package_name", - "publish": "node ../../scripts/publish.js $npm_package_name $npm_package_version" + "release": "node ../../scripts/release.js $npm_package_name $npm_package_version" } } diff --git a/scripts/publish.js b/scripts/release.js similarity index 90% rename from scripts/publish.js rename to scripts/release.js index b24f77820b4..54d0fca948d 100644 --- a/scripts/publish.js +++ b/scripts/release.js @@ -8,13 +8,18 @@ import { isValidVersion } from './utils/semver.js'; let packageName = process.argv[2]; let version = process.argv[3]; +if (packageName === undefined || version === undefined) { + console.error('Usage: node release.js <packageName> <version>'); + process.exit(1); +} + if (typeof packageName === 'string' && packageName.startsWith('@mjackson/')) { packageName = packageName.slice('@mjackson/'.length); } let tag = `${packageName}@${version}`; -if (packageName === undefined || packageName === '' || !isValidVersion(version)) { +if (packageName === '' || !isValidVersion(version)) { console.error(`Invalid tag: ${tag}`); process.exit(1); } diff --git a/scripts/version.js b/scripts/version.js index 01d7ab3536b..52b6cd914bc 100644 --- a/scripts/version.js +++ b/scripts/version.js @@ -16,15 +16,15 @@ import { getNextVersion } from './utils/semver.js'; let packageName = process.argv[2]; let releaseType = process.argv[3]; -if (typeof packageName === 'string' && packageName.startsWith('@mjackson/')) { - packageName = packageName.slice('@mjackson/'.length); -} - if (packageName === undefined || releaseType === undefined) { console.error('Usage: node version.js <packageName> <releaseType>'); process.exit(1); } +if (typeof packageName === 'string' && packageName.startsWith('@mjackson/')) { + packageName = packageName.slice('@mjackson/'.length); +} + let packageJson = readPackageJson(packageName); let nextVersion = getNextVersion(packageJson.version, releaseType); let tag = `${packageName}@${nextVersion}`; From 07d29f9a20b26d950c21f285d1ddb1f138dfe85b Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 17:26:22 -0800 Subject: [PATCH 496/730] More testing --- packages/scripts-test/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/scripts-test/CHANGELOG.md b/packages/scripts-test/CHANGELOG.md index 3f4d299aac4..24188762fe7 100644 --- a/packages/scripts-test/CHANGELOG.md +++ b/packages/scripts-test/CHANGELOG.md @@ -2,6 +2,10 @@ This package is only for testing the version and publish scripts. +## HEAD + +More testing. + ## v0.1.0 (2024-11-27) Initial release. From e1a02cd70a7f4953fcc5b19191a864fdb657eae2 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 17:26:30 -0800 Subject: [PATCH 497/730] Release scripts-test@0.2.0 --- packages/scripts-test/CHANGELOG.md | 2 +- packages/scripts-test/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/scripts-test/CHANGELOG.md b/packages/scripts-test/CHANGELOG.md index 24188762fe7..40c21be8a3a 100644 --- a/packages/scripts-test/CHANGELOG.md +++ b/packages/scripts-test/CHANGELOG.md @@ -2,7 +2,7 @@ This package is only for testing the version and publish scripts. -## HEAD +## v0.2.0 (2024-11-27) More testing. diff --git a/packages/scripts-test/package.json b/packages/scripts-test/package.json index 2bfdca48bc8..a44d8beb454 100644 --- a/packages/scripts-test/package.json +++ b/packages/scripts-test/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/scripts-test", - "version": "0.1.0", + "version": "0.2.0", "description": "Test package for version/publish scripts", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From 96272df2f45bc302c57019b23b3141046556ba41 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 17:37:18 -0800 Subject: [PATCH 498/730] More testing --- packages/scripts-test/package.json | 2 +- scripts/release.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/scripts-test/package.json b/packages/scripts-test/package.json index a44d8beb454..26a716d5be1 100644 --- a/packages/scripts-test/package.json +++ b/packages/scripts-test/package.json @@ -49,6 +49,6 @@ "build": "tsup", "prepare": "pnpm run build", "version": "node ../../scripts/version.js $npm_package_name", - "release": "node ../../scripts/release.js $npm_package_name $npm_package_version" + "release": "node --env-file ../../.env ../../scripts/release.js $npm_package_name $npm_package_version" } } diff --git a/scripts/release.js b/scripts/release.js index 54d0fca948d..8f1c286b5fc 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -67,7 +67,7 @@ if (hasJsrJson(packageName)) { } // 5) Publish to GitHub Releases -console.log(`Publishing tag ${tag} on GitHub Releases ...`); +console.log(`Publishing ${tag} on GitHub Releases ...`); await createRelease(packageName, version); console.log(); From 462e2ee42187838e239fb5dc953747ad3ff1450b Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 17:37:49 -0800 Subject: [PATCH 499/730] More testing --- packages/scripts-test/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/scripts-test/CHANGELOG.md b/packages/scripts-test/CHANGELOG.md index 40c21be8a3a..7b3b6be54e5 100644 --- a/packages/scripts-test/CHANGELOG.md +++ b/packages/scripts-test/CHANGELOG.md @@ -2,6 +2,10 @@ This package is only for testing the version and publish scripts. +## HEAD + +More testing. + ## v0.2.0 (2024-11-27) More testing. From e38633fb10198bf516977bb5e639fc4123220212 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 17:37:58 -0800 Subject: [PATCH 500/730] Release scripts-test@0.2.1 --- packages/scripts-test/CHANGELOG.md | 2 +- packages/scripts-test/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/scripts-test/CHANGELOG.md b/packages/scripts-test/CHANGELOG.md index 7b3b6be54e5..7e508a656a7 100644 --- a/packages/scripts-test/CHANGELOG.md +++ b/packages/scripts-test/CHANGELOG.md @@ -2,7 +2,7 @@ This package is only for testing the version and publish scripts. -## HEAD +## v0.2.1 (2024-11-27) More testing. diff --git a/packages/scripts-test/package.json b/packages/scripts-test/package.json index 26a716d5be1..aedcea087ff 100644 --- a/packages/scripts-test/package.json +++ b/packages/scripts-test/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/scripts-test", - "version": "0.2.0", + "version": "0.2.1", "description": "Test package for version/publish scripts", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From a25f4d67ab0828236b78de6f707c61eb40a8acef Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 18:54:23 -0800 Subject: [PATCH 501/730] More work --- scripts/version.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/version.js b/scripts/version.js index 52b6cd914bc..65cf7364266 100644 --- a/scripts/version.js +++ b/scripts/version.js @@ -36,7 +36,7 @@ if (status !== '') { process.exit(1); } -console.log(`Releasing ${tag} ...`); +console.log(`Tagging ${tag} ...`); console.log(); // 2) Update package.json with the new release version From 5e632edbcf5710e745a850a3491b367eacadbdc1 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 19:03:18 -0800 Subject: [PATCH 502/730] Add build workflow --- .github/workflows/build.yaml | 28 ++++++++++++++++++++++++++++ package.json | 3 ++- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/build.yaml diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 00000000000..64c210eb471 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,28 @@ +on: + - push + - pull_request + +jobs: + build-and-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + name: Install pnpm + with: + run_install: false + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install + + - name: Run tests + run: pnpm test diff --git a/package.json b/package.json index 8f628df8a7e..be85eb680a8 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "prettier": "^3.3.3" }, "scripts": { - "clean": "git clean -fdX ." + "clean": "git clean -fdX .", + "test": "pnpm -r --workspace-concurrency 1 test" } } From 3b02796295140d7eb1617cdd12415e6504a1d48a Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 19:04:01 -0800 Subject: [PATCH 503/730] Remove scripts-test --- packages/scripts-test/CHANGELOG.md | 15 ------ packages/scripts-test/LICENSE | 21 -------- packages/scripts-test/README.md | 3 -- packages/scripts-test/package.json | 54 ------------------- packages/scripts-test/src/lib/scripts-test.ts | 1 - packages/scripts-test/src/scripts-test.ts | 1 - packages/scripts-test/tsconfig.json | 8 --- packages/scripts-test/tsconfig.lib.json | 9 ---- packages/scripts-test/tsconfig.spec.json | 8 --- packages/scripts-test/tsup.config.ts | 11 ---- 10 files changed, 131 deletions(-) delete mode 100644 packages/scripts-test/CHANGELOG.md delete mode 100644 packages/scripts-test/LICENSE delete mode 100644 packages/scripts-test/README.md delete mode 100644 packages/scripts-test/package.json delete mode 100644 packages/scripts-test/src/lib/scripts-test.ts delete mode 100644 packages/scripts-test/src/scripts-test.ts delete mode 100644 packages/scripts-test/tsconfig.json delete mode 100644 packages/scripts-test/tsconfig.lib.json delete mode 100644 packages/scripts-test/tsconfig.spec.json delete mode 100644 packages/scripts-test/tsup.config.ts diff --git a/packages/scripts-test/CHANGELOG.md b/packages/scripts-test/CHANGELOG.md deleted file mode 100644 index 7e508a656a7..00000000000 --- a/packages/scripts-test/CHANGELOG.md +++ /dev/null @@ -1,15 +0,0 @@ -# `scripts-test` CHANGELOG - -This package is only for testing the version and publish scripts. - -## v0.2.1 (2024-11-27) - -More testing. - -## v0.2.0 (2024-11-27) - -More testing. - -## v0.1.0 (2024-11-27) - -Initial release. diff --git a/packages/scripts-test/LICENSE b/packages/scripts-test/LICENSE deleted file mode 100644 index 717984c0442..00000000000 --- a/packages/scripts-test/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Michael Jackson - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/scripts-test/README.md b/packages/scripts-test/README.md deleted file mode 100644 index 12c4014949a..00000000000 --- a/packages/scripts-test/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# scripts-test - -This is a test package for the version/publish scripts. diff --git a/packages/scripts-test/package.json b/packages/scripts-test/package.json deleted file mode 100644 index aedcea087ff..00000000000 --- a/packages/scripts-test/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@mjackson/scripts-test", - "version": "0.2.1", - "description": "Test package for version/publish scripts", - "author": "Michael Jackson <mjijackson@gmail.com>", - "repository": { - "type": "git", - "url": "git+https://github.com/mjackson/remix-the-web.git", - "directory": "packages/scripts-test" - }, - "homepage": "https://github.com/mjackson/remix-the-web/tree/main/packages/scripts-test#readme", - "license": "MIT", - "files": [ - "dist", - "LICENSE", - "README.md" - ], - "type": "module", - "types": "./dist/scripts-test.d.ts", - "main": "./dist/scripts-test.js", - "exports": { - ".": { - "module-sync": { - "types": "./dist/scripts-test.d.ts", - "default": "./dist/scripts-test.js" - }, - "import": { - "types": "./dist/scripts-test.d.ts", - "default": "./dist/scripts-test.js" - }, - "require": { - "types": "./dist/scripts-test.d.cts", - "default": "./dist/scripts-test.cjs" - }, - "default": { - "types": "./dist/scripts-test.d.ts", - "default": "./dist/scripts-test.js" - } - }, - "./package.json": "./package.json" - }, - "devDependencies": { - "@swc-node/register": "^1.10.9", - "@types/node": "^22.5.0", - "tsup": "^8.3.5", - "typescript": "^5.6.3" - }, - "scripts": { - "build": "tsup", - "prepare": "pnpm run build", - "version": "node ../../scripts/version.js $npm_package_name", - "release": "node --env-file ../../.env ../../scripts/release.js $npm_package_name $npm_package_version" - } -} diff --git a/packages/scripts-test/src/lib/scripts-test.ts b/packages/scripts-test/src/lib/scripts-test.ts deleted file mode 100644 index 51f71ea572f..00000000000 --- a/packages/scripts-test/src/lib/scripts-test.ts +++ /dev/null @@ -1 +0,0 @@ -export const message = 'Hello, world!'; diff --git a/packages/scripts-test/src/scripts-test.ts b/packages/scripts-test/src/scripts-test.ts deleted file mode 100644 index f9afb5968b6..00000000000 --- a/packages/scripts-test/src/scripts-test.ts +++ /dev/null @@ -1 +0,0 @@ -export { message } from './lib/scripts-test.js'; diff --git a/packages/scripts-test/tsconfig.json b/packages/scripts-test/tsconfig.json deleted file mode 100644 index d8aaef54f9d..00000000000 --- a/packages/scripts-test/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "lib": ["DOM", "ES2020"], - "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true - } -} diff --git a/packages/scripts-test/tsconfig.lib.json b/packages/scripts-test/tsconfig.lib.json deleted file mode 100644 index 8e712f7d6c8..00000000000 --- a/packages/scripts-test/tsconfig.lib.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts"], - "compilerOptions": { - "composite": true, - "rootDir": "src" - } -} diff --git a/packages/scripts-test/tsconfig.spec.json b/packages/scripts-test/tsconfig.spec.json deleted file mode 100644 index ccfefc4d957..00000000000 --- a/packages/scripts-test/tsconfig.spec.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.spec.ts"], - "compilerOptions": { - "composite": true, - "types": ["node"] - } -} diff --git a/packages/scripts-test/tsup.config.ts b/packages/scripts-test/tsup.config.ts deleted file mode 100644 index 1af2073b066..00000000000 --- a/packages/scripts-test/tsup.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { defineConfig } from 'tsup'; - -export default defineConfig([ - { - clean: true, - dts: true, - entry: ['src/scripts-test.ts'], - format: ['cjs', 'esm'], - platform: 'neutral', - }, -]); From 81b8ca870a4a90305373b1328bc69e90b8bc9fa3 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 26 Nov 2024 19:12:58 -0800 Subject: [PATCH 504/730] Add release workflow --- .github/workflows/release.yaml | 29 +++++++++++++++++++++++++++++ package.json | 4 ++++ 2 files changed, 33 insertions(+) create mode 100644 .github/workflows/release.yaml diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 00000000000..6ebd8178092 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,29 @@ +on: + push: + tags: + - '[a-z\-]+@[0-9]+.[0-9]+.[0-9]+' + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + name: Install pnpm + with: + run_install: false + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install + + - name: Release + run: pnpm release ${{ github.ref_name }} diff --git a/package.json b/package.json index be85eb680a8..66e0d254756 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,15 @@ "name": "remix-the-web", "private": true, "packageManager": "pnpm@9.9.0", + "engines": { + "node": ">=22" + }, "devDependencies": { "prettier": "^3.3.3" }, "scripts": { "clean": "git clean -fdX .", + "release": "node ./scripts/release.js", "test": "pnpm -r --workspace-concurrency 1 test" } } From f33166c4c446f84d79b3029cdaec7a74955fe70d Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Wed, 27 Nov 2024 01:48:03 -0800 Subject: [PATCH 505/730] Update tag/release scripts --- .github/workflows/build.yaml | 12 +++-- .github/workflows/publish.yaml | 39 ++++++++++++++ .github/workflows/release.yaml | 29 ----------- scripts/publish-release.js | 89 ++++++++++++++++++++++++++++++++ scripts/tag-release.js | 72 ++++++++++++++++++++++++++ scripts/utils/github-releases.js | 4 +- 6 files changed, 211 insertions(+), 34 deletions(-) create mode 100644 .github/workflows/publish.yaml delete mode 100644 .github/workflows/release.yaml create mode 100644 scripts/publish-release.js create mode 100644 scripts/tag-release.js diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 64c210eb471..cfcc40a7ac0 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,6 +1,10 @@ on: - - push - - pull_request + push: + branches: + - '*' + pull_request: + branches: + - '*' jobs: build-and-test: @@ -18,8 +22,8 @@ jobs: - name: Install Node.js uses: actions/setup-node@v4 with: - node-version: 20 - cache: 'pnpm' + node-version: 22 + cache: pnpm - name: Install dependencies run: pnpm install diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 00000000000..e949f4adc9c --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,39 @@ +on: + push: + tags: + - '[a-z]+@[0-9]+.[0-9]+.[0-9]+' + - '[a-z]+-[a-z]+@[0-9]+.[0-9]+.[0-9]+' + - '[a-z]+-[a-z]+-[a-z]+@[0-9]+.[0-9]+.[0-9]+' + +jobs: + release: + runs-on: ubuntu-latest + + permissions: + contents: write # Required for publishing the GitHub release. + id-token: write # The OIDC ID token is used for authentication with JSR. + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + name: Install pnpm + with: + run_install: false + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + registry-url: https://registry.npmjs.org + cache: pnpm + + - name: Install dependencies + run: pnpm install + + - name: Publish + run: pnpm publish-release-ci ${{ github.ref_name }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml deleted file mode 100644 index 6ebd8178092..00000000000 --- a/.github/workflows/release.yaml +++ /dev/null @@ -1,29 +0,0 @@ -on: - push: - tags: - - '[a-z\-]+@[0-9]+.[0-9]+.[0-9]+' - -jobs: - release: - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - name: Install pnpm - with: - run_install: false - - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install - - - name: Release - run: pnpm release ${{ github.ref_name }} diff --git a/scripts/publish-release.js b/scripts/publish-release.js new file mode 100644 index 00000000000..7176a6f2bc7 --- /dev/null +++ b/scripts/publish-release.js @@ -0,0 +1,89 @@ +import * as cp from 'node:child_process'; + +import { createRelease } from './utils/github-releases.js'; +import { getPackageDir, hasJsrJson, readJsrJson, readPackageJson } from './utils/packages.js'; +import { logAndExec } from './utils/process.js'; +import { isValidVersion } from './utils/semver.js'; + +let packageName = process.argv[2]; +let version = process.argv[3]; + +if (packageName === undefined || (!packageName.includes('@') && version === undefined)) { + console.error(`Usage: + node publish-release.js <packageName> <version> + node publish-release.js <tag>`); + process.exit(1); +} + +if (packageName.startsWith('@mjackson/')) { + packageName = packageName.slice('@mjackson/'.length); +} + +if (packageName.includes('@')) { + let split = packageName.split('@'); + packageName = split[0]; + version = split[1]; +} + +let tag = `${packageName}@${version}`; + +if (packageName === '' || !isValidVersion(version)) { + console.error(`Invalid tag: ${tag}`); + process.exit(1); +} + +// 1) Ensure git staging area is clean +let status = cp.execSync('git status --porcelain').toString(); +if (status !== '') { + console.error('Git staging area is not clean'); + process.exit(1); +} + +// 2) Ensure we are on the right tag +let currentTags = cp.execSync('git tag --points-at HEAD').toString().trim().split('\n'); +if (!currentTags.includes(tag)) { + console.error(`Tag "${tag}" does not point to HEAD`); + process.exit(1); +} + +console.log(`Publishing release ${tag} ...`); +console.log(); + +// 3) Publish to npm +let packageJson = readPackageJson(packageName); +if (packageJson.version !== version) { + console.error( + `Tag does not match package.json version: ${version} !== ${packageJson.version} (${tag})`, + ); + process.exit(1); +} + +logAndExec(`npm publish --access public`, { + cwd: getPackageDir(packageName), + env: process.env, +}); +console.log(); + +// 4) Publish to jsr (if applicable) +if (hasJsrJson(packageName)) { + let jsrJson = readJsrJson(packageName); + if (jsrJson.version !== version) { + console.error( + `Tag does not match jsr.json version: ${version} !== ${jsrJson.version} (${tag})`, + ); + process.exit(1); + } + + logAndExec(`pnpm dlx jsr publish`, { + cwd: getPackageDir(packageName), + env: process.env, + }); + console.log(); +} + +// 5) Publish to GitHub Releases +console.log(`Publishing ${tag} on GitHub Releases ...`); +let releaseUrl = await createRelease(packageName, version); +console.log(`Published at: ${releaseUrl}`); + +console.log(); diff --git a/scripts/tag-release.js b/scripts/tag-release.js new file mode 100644 index 00000000000..ff9d8425a28 --- /dev/null +++ b/scripts/tag-release.js @@ -0,0 +1,72 @@ +import * as cp from 'node:child_process'; + +import { + getPackageFile, + readChangelog, + writeChangelog, + hasJsrJson, + readJsrJson, + writeJsrJson, + readPackageJson, + writePackageJson, +} from './utils/packages.js'; +import { logAndExec } from './utils/process.js'; +import { getNextVersion } from './utils/semver.js'; + +let packageName = process.argv[2]; +let releaseType = process.argv[3]; + +if (packageName === undefined || releaseType === undefined) { + console.error('Usage: node tag-release.js <packageName> <releaseType>'); + process.exit(1); +} + +if (packageName.startsWith('@mjackson/')) { + packageName = packageName.slice('@mjackson/'.length); +} + +let packageJson = readPackageJson(packageName); +let nextVersion = getNextVersion(packageJson.version, releaseType); +let tag = `${packageName}@${nextVersion}`; + +// 1) Ensure git staging area is clean +let status = cp.execSync('git status --porcelain').toString(); +if (status !== '') { + console.error('Git staging area is not clean'); + process.exit(1); +} + +console.log(`Tagging release ${tag} ...`); +console.log(); + +// 2) Update package.json with the new release version +writePackageJson(packageName, { ...packageJson, version: nextVersion }); +logAndExec(`git add ${getPackageFile(packageName, 'package.json')}`); + +// 4) Update jsr.json (if applicable) with the new release version +if (hasJsrJson(packageName)) { + let jsrJson = readJsrJson(packageName); + writeJsrJson(packageName, { ...jsrJson, version: nextVersion }); + logAndExec(`git add ${getPackageFile(packageName, 'jsr.json')}`); +} + +// 3) Swap out "## HEAD" in CHANGELOG.md with the new release version + date +let changelog = readChangelog(packageName); +let match = /^## HEAD\n/m.exec(changelog); +if (match) { + let [today] = new Date().toISOString().split('T'); + + changelog = + changelog.slice(0, match.index) + + `## v${nextVersion} (${today})\n` + + changelog.slice(match.index + match[0].length); + + writeChangelog(packageName, changelog); + logAndExec(`git add ${getPackageFile(packageName, 'CHANGELOG.md')}`); +} + +// 5) Commit and tag +logAndExec(`git commit -m "Release ${tag}"`); +logAndExec(`git tag ${tag}`); + +console.log(); diff --git a/scripts/utils/github-releases.js b/scripts/utils/github-releases.js index 0fd44425b9d..65e2ce683cb 100644 --- a/scripts/utils/github-releases.js +++ b/scripts/utils/github-releases.js @@ -4,7 +4,7 @@ import { getChanges } from './changes.js'; const token = process.env.GITHUB_TOKEN; -/** @type (packageName: string, version: string) => Promise<void> */ +/** @type (packageName: string, version: string) => Promise<string> */ export async function createRelease(packageName, version) { if (token === undefined) { console.error('GITHUB_TOKEN environment variable is required to create a release'); @@ -29,4 +29,6 @@ export async function createRelease(packageName, version) { console.error('Failed to create release:', response); process.exit(1); } + + return response.data.html_url; } From 83f40c8869435cb8385b90d8fe4e65619bb0a09c Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Wed, 27 Nov 2024 01:53:47 -0800 Subject: [PATCH 506/730] Remove version scripts --- packages/fetch-proxy/package.json | 3 +- packages/file-storage/package.json | 3 +- packages/form-data-parser/package.json | 3 +- packages/headers/package.json | 3 +- packages/lazy-file/package.json | 3 +- packages/multipart-parser/package.json | 3 +- packages/node-fetch-server/package.json | 3 +- pnpm-lock.yaml | 15 ----- scripts/release.js | 73 ------------------------- scripts/version.js | 72 ------------------------ 10 files changed, 7 insertions(+), 174 deletions(-) delete mode 100644 scripts/release.js delete mode 100644 scripts/version.js diff --git a/packages/fetch-proxy/package.json b/packages/fetch-proxy/package.json index 8a7027503fe..cbdec6b960d 100644 --- a/packages/fetch-proxy/package.json +++ b/packages/fetch-proxy/package.json @@ -51,8 +51,7 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "version": "node ../../scripts/version.js $npm_package_name" + "prepare": "pnpm run build" }, "keywords": [ "fetch", diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index 2fce02ab473..4ab180cbb7c 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -87,8 +87,7 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "version": "node ../../scripts/version.js $npm_package_name" + "prepare": "pnpm run build" }, "keywords": [ "file", diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index 409ce7116e2..81168494aa3 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -51,8 +51,7 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "version": "node ../../scripts/version.js $npm_package_name" + "prepare": "pnpm run build" }, "keywords": [ "form-data", diff --git a/packages/headers/package.json b/packages/headers/package.json index 56c8ead80e3..698dc8763aa 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -48,8 +48,7 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "version": "node ../../scripts/version.js $npm_package_name" + "prepare": "pnpm run build" }, "keywords": [ "fetch", diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index 786ec44476f..0bb5cfb785e 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -69,8 +69,7 @@ "scripts": { "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "version": "node ../../scripts/version.js $npm_package_name" + "prepare": "pnpm run build" }, "keywords": [ "file", diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 5ae5f621df2..038403d6555 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -73,8 +73,7 @@ "bench:node": "node --import @swc-node/register/esm-register ./bench/runner.ts", "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "version": "node ../../scripts/version.js $npm_package_name" + "prepare": "pnpm run build" }, "keywords": [ "multipart", diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 90501025a5c..0f354fefa49 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -49,8 +49,7 @@ "bench": "bash ./bench/runner.sh", "build": "tsup", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "version": "node ../../scripts/version.js $npm_package_name" + "prepare": "pnpm run build" }, "keywords": [ "http", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 83406ec0fbe..f33448354c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -245,21 +245,6 @@ importers: specifier: ^4.17.21 version: 4.17.21 - packages/scripts-test: - devDependencies: - '@swc-node/register': - specifier: ^1.10.9 - version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) - '@types/node': - specifier: ^22.5.0 - version: 22.5.4 - tsup: - specifier: ^8.3.5 - version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) - typescript: - specifier: ^5.6.3 - version: 5.6.3 - scripts: dependencies: '@octokit/request': diff --git a/scripts/release.js b/scripts/release.js deleted file mode 100644 index 8f1c286b5fc..00000000000 --- a/scripts/release.js +++ /dev/null @@ -1,73 +0,0 @@ -import * as cp from 'node:child_process'; - -import { createRelease } from './utils/github-releases.js'; -import { getPackageDir, hasJsrJson, readJsrJson, readPackageJson } from './utils/packages.js'; -import { logAndExec } from './utils/process.js'; -import { isValidVersion } from './utils/semver.js'; - -let packageName = process.argv[2]; -let version = process.argv[3]; - -if (packageName === undefined || version === undefined) { - console.error('Usage: node release.js <packageName> <version>'); - process.exit(1); -} - -if (typeof packageName === 'string' && packageName.startsWith('@mjackson/')) { - packageName = packageName.slice('@mjackson/'.length); -} - -let tag = `${packageName}@${version}`; - -if (packageName === '' || !isValidVersion(version)) { - console.error(`Invalid tag: ${tag}`); - process.exit(1); -} - -// 1) Ensure git staging area is clean -let status = cp.execSync('git status --porcelain').toString(); -if (status !== '') { - console.error('Git staging area is not clean'); - process.exit(1); -} - -// 2) Ensure we are on the right tag -let currentTags = cp.execSync('git tag --points-at HEAD').toString().trim().split('\n'); -if (!currentTags.includes(tag)) { - console.error(`Tag "${tag}" does not point to HEAD`); - process.exit(1); -} - -// 3) Publish to npm -let packageJson = readPackageJson(packageName); -if (packageJson.version !== version) { - console.error( - `Tag does not match package.json version: ${version} !== ${packageJson.version} (${tag})`, - ); - process.exit(1); -} - -logAndExec(`pnpm publish --access public`, { - cwd: getPackageDir(packageName), -}); - -// 4) Publish to jsr (if applicable) -if (hasJsrJson(packageName)) { - let jsrJson = readJsrJson(packageName); - if (jsrJson.version !== version) { - console.error( - `Tag does not match jsr.json version: ${version} !== ${jsrJson.version} (${tag})`, - ); - process.exit(1); - } - - logAndExec(`pnpm dlx jsr publish`, { - cwd: getPackageDir(packageName), - }); -} - -// 5) Publish to GitHub Releases -console.log(`Publishing ${tag} on GitHub Releases ...`); -await createRelease(packageName, version); - -console.log(); diff --git a/scripts/version.js b/scripts/version.js deleted file mode 100644 index 65cf7364266..00000000000 --- a/scripts/version.js +++ /dev/null @@ -1,72 +0,0 @@ -import * as cp from 'node:child_process'; - -import { - getPackageFile, - readChangelog, - writeChangelog, - hasJsrJson, - readJsrJson, - writeJsrJson, - readPackageJson, - writePackageJson, -} from './utils/packages.js'; -import { logAndExec } from './utils/process.js'; -import { getNextVersion } from './utils/semver.js'; - -let packageName = process.argv[2]; -let releaseType = process.argv[3]; - -if (packageName === undefined || releaseType === undefined) { - console.error('Usage: node version.js <packageName> <releaseType>'); - process.exit(1); -} - -if (typeof packageName === 'string' && packageName.startsWith('@mjackson/')) { - packageName = packageName.slice('@mjackson/'.length); -} - -let packageJson = readPackageJson(packageName); -let nextVersion = getNextVersion(packageJson.version, releaseType); -let tag = `${packageName}@${nextVersion}`; - -// 1) Ensure git staging area is clean -let status = cp.execSync('git status --porcelain').toString(); -if (status !== '') { - console.error('Git staging area is not clean'); - process.exit(1); -} - -console.log(`Tagging ${tag} ...`); -console.log(); - -// 2) Update package.json with the new release version -writePackageJson(packageName, { ...packageJson, version: nextVersion }); -logAndExec(`git add ${getPackageFile(packageName, 'package.json')}`); - -// 4) Update jsr.json (if applicable) with the new release version -if (hasJsrJson(packageName)) { - let jsrJson = readJsrJson(packageName); - writeJsrJson(packageName, { ...jsrJson, version: nextVersion }); - logAndExec(`git add ${getPackageFile(packageName, 'jsr.json')}`); -} - -// 3) Swap out "## HEAD" in CHANGELOG.md with the new release version + date -let changelog = readChangelog(packageName); -let match = /^## HEAD\n/m.exec(changelog); -if (match) { - let [today] = new Date().toISOString().split('T'); - - changelog = - changelog.slice(0, match.index) + - `## v${nextVersion} (${today})\n` + - changelog.slice(match.index + match[0].length); - - writeChangelog(packageName, changelog); - logAndExec(`git add ${getPackageFile(packageName, 'CHANGELOG.md')}`); -} - -// 5) Commit and tag -logAndExec(`git commit -m "Release ${tag}"`); -logAndExec(`git tag ${tag}`); - -console.log(); From 7e76acd82047be305c5193238579ea1bce32bfe5 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Wed, 27 Nov 2024 01:56:34 -0800 Subject: [PATCH 507/730] Add top-level scripts --- package.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 66e0d254756..3cff036befe 100644 --- a/package.json +++ b/package.json @@ -2,15 +2,14 @@ "name": "remix-the-web", "private": true, "packageManager": "pnpm@9.9.0", - "engines": { - "node": ">=22" - }, "devDependencies": { "prettier": "^3.3.3" }, "scripts": { "clean": "git clean -fdX .", - "release": "node ./scripts/release.js", + "publish-release": "node --env-file .env ./scripts/publish-release.js", + "publish-release-ci": "node ./scripts/publish-release.js", + "tag-release": "node ./scripts/tag-release.js", "test": "pnpm -r --workspace-concurrency 1 test" } } From 26974f7e7d87dfe33173be2b69e772b42e83e3c4 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Wed, 27 Nov 2024 10:44:30 -0800 Subject: [PATCH 508/730] Some small tweaks to scripts --- scripts/publish-release.js | 15 ++++---- scripts/tag-release.js | 35 ++++++++---------- scripts/utils/fs.js | 42 ++++++++++++++++++++++ scripts/utils/packages.js | 72 -------------------------------------- 4 files changed, 66 insertions(+), 98 deletions(-) create mode 100644 scripts/utils/fs.js diff --git a/scripts/publish-release.js b/scripts/publish-release.js index 7176a6f2bc7..3d0cb846829 100644 --- a/scripts/publish-release.js +++ b/scripts/publish-release.js @@ -1,7 +1,8 @@ import * as cp from 'node:child_process'; +import { fileExists, readJson } from './utils/fs.js'; import { createRelease } from './utils/github-releases.js'; -import { getPackageDir, hasJsrJson, readJsrJson, readPackageJson } from './utils/packages.js'; +import { getPackageDir, getPackageFile } from './utils/packages.js'; import { logAndExec } from './utils/process.js'; import { isValidVersion } from './utils/semver.js'; @@ -50,7 +51,8 @@ console.log(`Publishing release ${tag} ...`); console.log(); // 3) Publish to npm -let packageJson = readPackageJson(packageName); +let packageJsonFile = getPackageFile(packageName, 'package.json'); +let packageJson = readJson(packageJsonFile); if (packageJson.version !== version) { console.error( `Tag does not match package.json version: ${version} !== ${packageJson.version} (${tag})`, @@ -65,8 +67,9 @@ logAndExec(`npm publish --access public`, { console.log(); // 4) Publish to jsr (if applicable) -if (hasJsrJson(packageName)) { - let jsrJson = readJsrJson(packageName); +let jsrJsonFile = getPackageFile(packageName, 'jsr.json'); +if (fileExists(jsrJsonFile)) { + let jsrJson = readJson(jsrJsonFile); if (jsrJson.version !== version) { console.error( `Tag does not match jsr.json version: ${version} !== ${jsrJson.version} (${tag})`, @@ -74,7 +77,7 @@ if (hasJsrJson(packageName)) { process.exit(1); } - logAndExec(`pnpm dlx jsr publish`, { + logAndExec(`npx jsr publish`, { cwd: getPackageDir(packageName), env: process.env, }); @@ -84,6 +87,6 @@ if (hasJsrJson(packageName)) { // 5) Publish to GitHub Releases console.log(`Publishing ${tag} on GitHub Releases ...`); let releaseUrl = await createRelease(packageName, version); -console.log(`Published at: ${releaseUrl}`); +console.log(`Done, see ${releaseUrl}`); console.log(); diff --git a/scripts/tag-release.js b/scripts/tag-release.js index ff9d8425a28..a4e7657bfe5 100644 --- a/scripts/tag-release.js +++ b/scripts/tag-release.js @@ -1,15 +1,7 @@ import * as cp from 'node:child_process'; -import { - getPackageFile, - readChangelog, - writeChangelog, - hasJsrJson, - readJsrJson, - writeJsrJson, - readPackageJson, - writePackageJson, -} from './utils/packages.js'; +import { fileExists, readFile, readJson, writeFile, writeJson } from './utils/fs.js'; +import { getPackageFile } from './utils/packages.js'; import { logAndExec } from './utils/process.js'; import { getNextVersion } from './utils/semver.js'; @@ -25,7 +17,8 @@ if (packageName.startsWith('@mjackson/')) { packageName = packageName.slice('@mjackson/'.length); } -let packageJson = readPackageJson(packageName); +let packageJsonFile = getPackageFile(packageName, 'package.json'); +let packageJson = readJson(packageJsonFile); let nextVersion = getNextVersion(packageJson.version, releaseType); let tag = `${packageName}@${nextVersion}`; @@ -40,18 +33,20 @@ console.log(`Tagging release ${tag} ...`); console.log(); // 2) Update package.json with the new release version -writePackageJson(packageName, { ...packageJson, version: nextVersion }); -logAndExec(`git add ${getPackageFile(packageName, 'package.json')}`); +writeJson(packageJsonFile, { ...packageJson, version: nextVersion }); +logAndExec(`git add ${packageJsonFile}`); // 4) Update jsr.json (if applicable) with the new release version -if (hasJsrJson(packageName)) { - let jsrJson = readJsrJson(packageName); - writeJsrJson(packageName, { ...jsrJson, version: nextVersion }); - logAndExec(`git add ${getPackageFile(packageName, 'jsr.json')}`); +let jsrJsonFile = getPackageFile(packageName, 'jsr.json'); +if (fileExists(jsrJsonFile)) { + let jsrJson = readJson(jsrJsonFile); + writeJson(jsrJsonFile, { ...jsrJson, version: nextVersion }); + logAndExec(`git add ${jsrJsonFile}`); } // 3) Swap out "## HEAD" in CHANGELOG.md with the new release version + date -let changelog = readChangelog(packageName); +let changelogFile = getPackageFile(packageName, 'CHANGELOG.md'); +let changelog = readFile(packageName); let match = /^## HEAD\n/m.exec(changelog); if (match) { let [today] = new Date().toISOString().split('T'); @@ -61,8 +56,8 @@ if (match) { `## v${nextVersion} (${today})\n` + changelog.slice(match.index + match[0].length); - writeChangelog(packageName, changelog); - logAndExec(`git add ${getPackageFile(packageName, 'CHANGELOG.md')}`); + writeFile(changelogFile, changelog); + logAndExec(`git add ${changelogFile}`); } // 5) Commit and tag diff --git a/scripts/utils/fs.js b/scripts/utils/fs.js new file mode 100644 index 00000000000..d69d83a67c9 --- /dev/null +++ b/scripts/utils/fs.js @@ -0,0 +1,42 @@ +import * as fs from 'node:fs'; + +/** @type (filename: string) => boolean */ +export function fileExists(filename) { + return fs.existsSync(filename); +} + +/** @type (filename: string) => string */ +export function readFile(filename) { + try { + return fs.readFileSync(filename, 'utf-8'); + } catch (error) { + if (isFsError(error) && error.code === 'ENOENT') { + console.error(`Not found: "${filename}"`); + process.exit(1); + } else { + throw error; + } + } +} + +/** @type (filename: string, data: string) => void */ +export function writeFile(filename, data) { + fs.writeFileSync(filename, data); +} + +/** @type (filename: string) => any */ +export function readJson(filename) { + return JSON.parse(readFile(filename)); +} + +/** @type (filename: string, data: any) => void */ +export function writeJson(filename, data) { + writeFile(filename, JSON.stringify(data, null, 2) + '\n'); +} + +/** @type (error: unknown) => error is { code: string } */ +function isFsError(error) { + return ( + typeof error === 'object' && error != null && 'code' in error && typeof error.code === 'string' + ); +} diff --git a/scripts/utils/packages.js b/scripts/utils/packages.js index a70e3b1a485..d0cd2bcad78 100644 --- a/scripts/utils/packages.js +++ b/scripts/utils/packages.js @@ -1,4 +1,3 @@ -import * as fs from 'node:fs'; import * as path from 'node:path'; const __dirname = path.dirname(new URL(import.meta.url).pathname); @@ -17,74 +16,3 @@ export function getPackageDir(packageName) { export function getPackageFile(packageName, filename) { return path.join(getPackageDir(packageName), filename); } - -/** @type (packageName: string) => boolean */ -export function hasChangelog(packageName) { - return fs.existsSync(getPackageFile(packageName, 'CHANGELOG.md')); -} - -/** @type (packageName: string) => string */ -export function readChangelog(packageName) { - return fs.readFileSync(getPackageFile(packageName, 'CHANGELOG.md'), 'utf-8'); -} - -/** @type (packageName: string, data: string) => void */ -export function writeChangelog(packageName, data) { - fs.writeFileSync(getPackageFile(packageName, 'CHANGELOG.md'), data); -} - -/** @type (packageName: string) => boolean */ -export function hasJsrJson(packageName) { - return fs.existsSync(getPackageFile(packageName, 'jsr.json')); -} - -/** @type (packageName: string) => any */ -export function readJsrJson(packageName) { - return readJson(getPackageFile(packageName, 'jsr.json')); -} - -/** @type (packageName: string, data: any) => void */ -export function writeJsrJson(packageName, data) { - writeJson(getPackageFile(packageName, 'jsr.json'), data); -} - -/** @type (packageName: string) => boolean */ -export function hasPackageJson(packageName) { - return fs.existsSync(getPackageFile(packageName, 'package.json')); -} - -/** @type (packageName: string) => any */ -export function readPackageJson(packageName) { - return readJson(getPackageFile(packageName, 'package.json')); -} - -/** @type (packageName: string, data: any) => void */ -export function writePackageJson(packageName, data) { - writeJson(getPackageFile(packageName, 'package.json'), data); -} - -/** @type (file: string) => any */ -function readJson(file) { - try { - return JSON.parse(fs.readFileSync(file, 'utf-8')); - } catch (error) { - if (isFsError(error) && error.code === 'ENOENT') { - console.error(`Not found: "${file}"`); - process.exit(1); - } else { - throw error; - } - } -} - -/** @type (filename: string, data: any) => void */ -function writeJson(filename, data) { - fs.writeFileSync(filename, JSON.stringify(data, null, 2) + '\n'); -} - -/** @type (error: unknown) => error is { code: string } */ -function isFsError(error) { - return ( - typeof error === 'object' && error != null && 'code' in error && typeof error.code === 'string' - ); -} From ae011d0ebfb69f5408a0d51dcea366c501930899 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Wed, 27 Nov 2024 20:16:03 -0800 Subject: [PATCH 509/730] Some small script updates --- scripts/utils/changes.js | 16 +++++++++------- scripts/utils/fs.js | 6 +++--- scripts/utils/github-releases.js | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/scripts/utils/changes.js b/scripts/utils/changes.js index 677efcda327..a44e5171b50 100644 --- a/scripts/utils/changes.js +++ b/scripts/utils/changes.js @@ -1,14 +1,18 @@ -import { hasChangelog, readChangelog } from './packages.js'; +import { getPackageFile } from './packages.js'; +import { fileExists, readFile } from './fs.js'; +/** @typedef {{ version: string; date?: Date; body: string }} Changes */ /** @typedef {Record<string, Changes>} AllChanges */ /** @type (packageName: string) => AllChanges | null */ export function getAllChanges(packageName) { - if (!hasChangelog(packageName)) { + let changelogFile = getPackageFile(packageName, 'CHANGELOG.md'); + + if (!fileExists(changelogFile)) { return null; } - let changelog = readChangelog(packageName); + let changelog = readFile(changelogFile); let parser = /^## ([a-z\d\.\-]+)(?: \(([^)]+)\))?$/gim; /** @type {AllChanges} */ @@ -21,16 +25,14 @@ export function getAllChanges(packageName) { let version = versionString.startsWith('v') ? versionString.slice(1) : versionString; let date = dateString ? new Date(dateString) : undefined; let nextMatch = parser.exec(changelog); - let changes = changelog.slice(lastIndex, nextMatch ? nextMatch.index : undefined).trim(); - result[version] = { version, date, changes }; + let body = changelog.slice(lastIndex, nextMatch ? nextMatch.index : undefined).trim(); + result[version] = { version, date, body }; parser.lastIndex = lastIndex; } return result; } -/** @typedef {{ version: string; date?: Date; changes: string }} Changes */ - /** @type (packageName: string, version: string) => Changes | null */ export function getChanges(packageName, version) { let allChanges = getAllChanges(packageName); diff --git a/scripts/utils/fs.js b/scripts/utils/fs.js index d69d83a67c9..958e06bcf32 100644 --- a/scripts/utils/fs.js +++ b/scripts/utils/fs.js @@ -5,10 +5,10 @@ export function fileExists(filename) { return fs.existsSync(filename); } -/** @type (filename: string) => string */ -export function readFile(filename) { +/** @type (filename: string, encoding?: BufferEncoding) => string */ +export function readFile(filename, encoding = 'utf-8') { try { - return fs.readFileSync(filename, 'utf-8'); + return fs.readFileSync(filename, encoding); } catch (error) { if (isFsError(error) && error.code === 'ENOENT') { console.error(`Not found: "${filename}"`); diff --git a/scripts/utils/github-releases.js b/scripts/utils/github-releases.js index 65e2ce683cb..22fe0233fdd 100644 --- a/scripts/utils/github-releases.js +++ b/scripts/utils/github-releases.js @@ -22,7 +22,7 @@ export async function createRelease(packageName, version) { repo: 'remix-the-web', tag_name: tagName, name: `${packageName} v${version}`, - body: changes?.changes ?? 'No changes.', + body: changes?.body ?? 'No changes.', }); if (response.status !== 201) { From 0df41783fbeecbf45c6b6cede0b7a419b01eb51b Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 3 Dec 2024 09:41:24 -0800 Subject: [PATCH 510/730] Small tweaks --- .env.example | 2 +- package.json | 3 +++ scripts/utils/github-releases.js | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index 2d545af4f9f..f22ee913c0c 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,2 @@ -# This is needed to publish to GitHub Releases using scripts/publish.js +# This is needed to publish GitHub Releases GITHUB_TOKEN=your_github_token diff --git a/package.json b/package.json index 3cff036befe..7f467290f5a 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,9 @@ "devDependencies": { "prettier": "^3.3.3" }, + "engines": { + "node": ">=22" + }, "scripts": { "clean": "git clean -fdX .", "publish-release": "node --env-file .env ./scripts/publish-release.js", diff --git a/scripts/utils/github-releases.js b/scripts/utils/github-releases.js index 22fe0233fdd..459fe27de86 100644 --- a/scripts/utils/github-releases.js +++ b/scripts/utils/github-releases.js @@ -7,7 +7,7 @@ const token = process.env.GITHUB_TOKEN; /** @type (packageName: string, version: string) => Promise<string> */ export async function createRelease(packageName, version) { if (token === undefined) { - console.error('GITHUB_TOKEN environment variable is required to create a release'); + console.error('GITHUB_TOKEN environment variable is required to create a GitHub release'); process.exit(1); } From 21d147b078e82f411c54ae9c2a36d5b7af4849c5 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 3 Dec 2024 15:59:25 -0800 Subject: [PATCH 511/730] Fix example in README --- packages/node-fetch-server/CHANGELOG.md | 6 +++++- packages/node-fetch-server/README.md | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 3e8e3f4442b..50c2fe444b4 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -2,9 +2,13 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Fix low-level API example in the README + ## v0.4.0 (2024-11-26) -- BREAKING: Change new low-level API `createRequest(req, options)` to `createRequest(req, res, options)` so the abort signal fires on the `res`'s "end" event instead of `req` +- BREAKING: Change `createRequest` signature to `createRequest(req, res, options)` so the abort signal fires on the `res`'s "end" event instead of `req` ## v0.3.0 (2024-11-20) diff --git a/packages/node-fetch-server/README.md b/packages/node-fetch-server/README.md index ef3dddb3ef5..cbbf8914a54 100644 --- a/packages/node-fetch-server/README.md +++ b/packages/node-fetch-server/README.md @@ -72,7 +72,7 @@ let handler: FetchHandler = (request, client) => { In addition to the high-level `createRequestListener()` API, this package also provides 2 low-level APIs that are useful when building custom `fetch`-based servers in Node.js: -- `createRequest(req: http.IncomingMessage, options: RequestOptions): Request` +- `createRequest(req: http.IncomingMessage, res: http.ServerResponse, options: RequestOptions): Request` - `sendResponse(res: http.ServerResponse, response: Response): Promise<void>` These two functions serve as an efficient, minimal translation layer between Node.js `req`/`res` objects and fetch `Request`/`Response` objects. You could build your own custom server like this: @@ -82,7 +82,7 @@ import * as http from 'node:http'; import { createRequest, sendResponse } from '@mjackson/node-fetch-server'; let server = http.createServer(async (req, res) => { - let request = createRequest(req, { host: process.env.HOST }); + let request = createRequest(req, res, { host: process.env.HOST }); try { let response = await customAppLogic(request); From 65b19b7c3836aa6b3dbfc8b07021d84a5439f4f4 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 3 Dec 2024 16:19:47 -0800 Subject: [PATCH 512/730] No need to strip scope from package name --- scripts/publish-release.js | 4 ---- scripts/tag-release.js | 4 ---- 2 files changed, 8 deletions(-) diff --git a/scripts/publish-release.js b/scripts/publish-release.js index 3d0cb846829..29da73151fa 100644 --- a/scripts/publish-release.js +++ b/scripts/publish-release.js @@ -16,10 +16,6 @@ if (packageName === undefined || (!packageName.includes('@') && version === unde process.exit(1); } -if (packageName.startsWith('@mjackson/')) { - packageName = packageName.slice('@mjackson/'.length); -} - if (packageName.includes('@')) { let split = packageName.split('@'); packageName = split[0]; diff --git a/scripts/tag-release.js b/scripts/tag-release.js index a4e7657bfe5..c2f11b8bb52 100644 --- a/scripts/tag-release.js +++ b/scripts/tag-release.js @@ -13,10 +13,6 @@ if (packageName === undefined || releaseType === undefined) { process.exit(1); } -if (packageName.startsWith('@mjackson/')) { - packageName = packageName.slice('@mjackson/'.length); -} - let packageJsonFile = getPackageFile(packageName, 'package.json'); let packageJson = readJson(packageJsonFile); let nextVersion = getNextVersion(packageJson.version, releaseType); From daf5f247cb89fdec3f192c706e04093f28dfce07 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 3 Dec 2024 16:20:55 -0800 Subject: [PATCH 513/730] Read changelog file --- scripts/tag-release.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/tag-release.js b/scripts/tag-release.js index c2f11b8bb52..aa932cbd03c 100644 --- a/scripts/tag-release.js +++ b/scripts/tag-release.js @@ -42,7 +42,7 @@ if (fileExists(jsrJsonFile)) { // 3) Swap out "## HEAD" in CHANGELOG.md with the new release version + date let changelogFile = getPackageFile(packageName, 'CHANGELOG.md'); -let changelog = readFile(packageName); +let changelog = readFile(changelogFile); let match = /^## HEAD\n/m.exec(changelog); if (match) { let [today] = new Date().toISOString().split('T'); From 34e1b1d36379e1eeb5d00cdf8619edf09dac2a81 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 3 Dec 2024 16:21:09 -0800 Subject: [PATCH 514/730] Release node-fetch-server@0.4.1 --- packages/node-fetch-server/CHANGELOG.md | 2 +- packages/node-fetch-server/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 50c2fe444b4..361f3400ac6 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.4.1 (2024-12-04) - Fix low-level API example in the README diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 0f354fefa49..b17532df7a7 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/node-fetch-server", - "version": "0.4.0", + "version": "0.4.1", "description": "Build servers for Node.js using the web fetch API", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From 06a3ca203998970fe451becf4d57016818180e4f Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Wed, 4 Dec 2024 15:38:08 -0800 Subject: [PATCH 515/730] Add createHeaders API to node-fetch-server --- packages/node-fetch-server/CHANGELOG.md | 6 +++- .../src/lib/request-listener.ts | 34 ++++++++++++++----- .../src/node-fetch-server.ts | 1 + 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 361f3400ac6..d162adb01fc 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -2,6 +2,10 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Expose `createHeaders(req: http.IncomingMessage): Headers` API for creating headers from the headers of incoming request objects. + ## v0.4.1 (2024-12-04) - Fix low-level API example in the README @@ -12,7 +16,7 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remi ## v0.3.0 (2024-11-20) -- Added low-level `createRequest(req, options)` and `sendResponse(res, response)` exports to assist with building custom fetch servers +- Added `createRequest(req: http.IncomingMessage, options): Request` and `sendResponse(res: http.ServerResponse, response: Response): Promise<void>` exports to assist with building custom fetch servers ## v0.2.0 (2024-11-14) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 8dfea721303..dc47eb44960 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -30,7 +30,10 @@ export interface RequestListenerOptions { /** * Wraps a fetch handler in a Node.js `http.RequestListener` that can be used with - * `http.createServer()` or `https.createServer()`. + * [`http.createServer()`](https://nodejs.org/api/http.html#httpcreateserveroptions-requestlistener) or + * [`https.createServer()`](https://nodejs.org/api/https.html#httpscreateserveroptions-requestlistener). + * + * Example: * * ```ts * import * as http from 'node:http'; @@ -48,8 +51,8 @@ export interface RequestListenerOptions { * ``` * * @param handler The fetch handler to use for processing incoming requests. - * @param options Configuration options. - * @returns A Node.js `http.RequestListener` that can be used with `http.createServer()` or `https.createServer()`. + * @param options Request listener options. + * @returns A Node.js request listener function. */ export function createRequestListener( handler: FetchHandler, @@ -105,11 +108,14 @@ function internalServerError(): Response { export type RequestOptions = Omit<RequestListenerOptions, 'onError'>; /** - * Creates a `Request` object from an incoming Node.js request object. + * Creates a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) object from a Node.js + * [`http.IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage) and + * [`http.ServerResponse`](https://nodejs.org/api/http.html#class-httpserverresponse) pair. + * * @param req The incoming request object. * @param res The server response object. * @param options - * @returns A `Request` object. + * @returns A request object. */ export function createRequest( req: http.IncomingMessage, @@ -122,11 +128,11 @@ export function createRequest( }); let method = req.method ?? 'GET'; - let headers = createHeaders(req.rawHeaders); + let headers = createHeaders(req); let protocol = options?.protocol ?? ('encrypted' in req.socket && req.socket.encrypted ? 'https:' : 'http:'); - let host = options?.host ?? headers.get('host') ?? 'localhost'; + let host = options?.host ?? headers.get('Host') ?? 'localhost'; let url = new URL(req.url!, `${protocol}//${host}`); let init: RequestInit = { method, headers, signal: controller.signal }; @@ -153,9 +159,17 @@ export function createRequest( return new Request(url, init); } -function createHeaders(rawHeaders: string[]): Headers { +/** + * Creates a [`Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers) object from the headers + * in a Node.js [`http.IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage). + * + * @param req The incoming request object. + * @returns A headers object. + */ +export function createHeaders(req: http.IncomingMessage): Headers { let headers = new Headers(); + let rawHeaders = req.rawHeaders; for (let i = 0; i < rawHeaders.length; i += 2) { headers.append(rawHeaders[i], rawHeaders[i + 1]); } @@ -164,7 +178,9 @@ function createHeaders(rawHeaders: string[]): Headers { } /** - * Sends a `Response` to the client using the Node.js response object. + * Sends a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) to the client using the + * Node.js [`http.ServerResponse`](https://nodejs.org/api/http.html#class-httpserverresponse) object. + * * @param res The server response object. * @param response The response to send. */ diff --git a/packages/node-fetch-server/src/node-fetch-server.ts b/packages/node-fetch-server/src/node-fetch-server.ts index b5d12130721..3825deb9063 100644 --- a/packages/node-fetch-server/src/node-fetch-server.ts +++ b/packages/node-fetch-server/src/node-fetch-server.ts @@ -4,5 +4,6 @@ export { createRequestListener, type RequestOptions, createRequest, + createHeaders, sendResponse, } from './lib/request-listener.js'; From e3d7b08edb0db189221b44063680c2dda1e2e251 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 5 Dec 2024 16:40:30 -0800 Subject: [PATCH 516/730] Upgrade to TypeScript 5.7.2 Also, use node's built-in type stripping instead of @swc-node/register. Also, add support for node:test runner VS Code plugin. --- .vscode/settings.json | 9 +- package.json | 3 +- packages/fetch-proxy/package.json | 6 +- packages/fetch-proxy/src/fetch-proxy.ts | 2 +- ...etch-proxy.spec.ts => fetch-proxy.test.ts} | 2 +- packages/fetch-proxy/tsconfig.json | 12 +- packages/fetch-proxy/tsconfig.lib.json | 9 - packages/fetch-proxy/tsconfig.spec.json | 7 - packages/file-storage/{src => }/global.d.ts | 0 packages/file-storage/package.json | 6 +- ...age.spec.ts => local-file-storage.test.ts} | 2 +- .../src/lib/local-file-storage.ts | 2 +- ...ge.spec.ts => memory-file-storage.test.ts} | 2 +- .../src/lib/memory-file-storage.ts | 2 +- packages/file-storage/tsconfig.json | 12 +- packages/file-storage/tsconfig.lib.json | 9 - packages/file-storage/tsconfig.spec.json | 8 - packages/form-data-parser/package.json | 6 +- .../form-data-parser/src/form-data-parser.ts | 2 +- .../{form-data.spec.ts => form-data.test.ts} | 2 +- .../form-data-parser/src/lib/form-data.ts | 2 +- packages/form-data-parser/tsconfig.json | 12 +- packages/form-data-parser/tsconfig.lib.json | 9 - packages/form-data-parser/tsconfig.spec.json | 8 - packages/headers/package.json | 6 +- packages/headers/src/headers.ts | 18 +- ...nguage.spec.ts => accept-language.test.ts} | 2 +- packages/headers/src/lib/accept-language.ts | 6 +- ...-control.spec.ts => cache-control.test.ts} | 2 +- packages/headers/src/lib/cache-control.ts | 4 +- ...on.spec.ts => content-disposition.test.ts} | 2 +- .../headers/src/lib/content-disposition.ts | 4 +- ...tent-type.spec.ts => content-type.test.ts} | 2 +- packages/headers/src/lib/content-type.ts | 4 +- .../lib/{cookie.spec.ts => cookie.test.ts} | 2 +- packages/headers/src/lib/cookie.ts | 6 +- ...der-names.spec.ts => header-names.test.ts} | 2 +- ...am-values.spec.ts => param-values.test.ts} | 2 +- ...{set-cookie.spec.ts => set-cookie.test.ts} | 2 +- packages/headers/src/lib/set-cookie.ts | 6 +- ...-headers.spec.ts => super-headers.test.ts} | 12 +- packages/headers/src/lib/super-headers.ts | 18 +- packages/headers/tsconfig.json | 10 +- packages/headers/tsconfig.lib.json | 9 - packages/headers/tsconfig.spec.json | 7 - packages/lazy-file/{src => }/global.d.ts | 0 packages/lazy-file/package.json | 6 +- packages/lazy-file/src/fs.ts | 2 +- packages/lazy-file/src/lazy-file.ts | 4 +- ...{byte-range.spec.ts => byte-range.test.ts} | 2 +- .../{lazy-file.spec.ts => lazy-file.test.ts} | 2 +- packages/lazy-file/src/lib/lazy-file.ts | 2 +- packages/lazy-file/tsconfig.json | 12 +- packages/lazy-file/tsconfig.lib.json | 9 - packages/lazy-file/tsconfig.spec.json | 8 - packages/multipart-parser/README.md | 8 +- packages/multipart-parser/bench/messages.ts | 2 +- packages/multipart-parser/bench/package.json | 3 +- .../multipart-parser/bench/parsers/busboy.ts | 2 +- .../bench/parsers/fastify-busboy.ts | 4 +- .../bench/parsers/multipart-parser.ts | 2 +- .../bench/parsers/multipasta.ts | 2 +- packages/multipart-parser/bench/runner.ts | 10 +- packages/multipart-parser/bench/tsconfig.json | 8 - .../examples/bun/package.json | 2 +- .../examples/cf-workers/package.json | 2 +- .../examples/deno/package.json | 2 +- .../examples/node/package.json | 2 +- .../multipart-parser/{bench => }/global.d.ts | 0 packages/multipart-parser/package.json | 8 +- ...rt.node.spec.ts => multipart.node.test.ts} | 6 +- .../src/lib/multipart.node.ts | 14 +- .../{multipart.spec.ts => multipart.test.ts} | 4 +- .../multipart-parser/src/lib/multipart.ts | 46 ++- .../lib/{search.spec.ts => search.test.ts} | 2 +- .../src/multipart-parser.node.ts | 2 +- .../multipart-parser/src/multipart-parser.ts | 2 +- packages/multipart-parser/test/utils.node.ts | 10 +- packages/multipart-parser/tsconfig.json | 12 +- packages/multipart-parser/tsconfig.lib.json | 9 - packages/multipart-parser/tsconfig.spec.json | 8 - packages/node-fetch-server/bench/runner.sh | 6 +- .../node-fetch-server/bench/tsconfig.json | 8 - .../src => node-fetch-server}/global.d.ts | 0 packages/node-fetch-server/package.json | 6 +- packages/node-fetch-server/src/global.d.ts | 6 - ...tener.spec.ts => request-listener.test.ts} | 4 +- .../src/lib/request-listener.ts | 4 +- .../src/node-fetch-server.ts | 4 +- packages/node-fetch-server/tsconfig.json | 10 +- packages/node-fetch-server/tsconfig.lib.json | 9 - packages/node-fetch-server/tsconfig.spec.json | 8 - packages/node-fetch-server/tsup.config.ts | 2 +- pnpm-lock.yaml | 300 ++---------------- 94 files changed, 243 insertions(+), 603 deletions(-) rename packages/fetch-proxy/src/lib/{fetch-proxy.spec.ts => fetch-proxy.test.ts} (98%) delete mode 100644 packages/fetch-proxy/tsconfig.lib.json delete mode 100644 packages/fetch-proxy/tsconfig.spec.json rename packages/file-storage/{src => }/global.d.ts (100%) rename packages/file-storage/src/lib/{local-file-storage.spec.ts => local-file-storage.test.ts} (95%) rename packages/file-storage/src/lib/{memory-file-storage.spec.ts => memory-file-storage.test.ts} (92%) delete mode 100644 packages/file-storage/tsconfig.lib.json delete mode 100644 packages/file-storage/tsconfig.spec.json rename packages/form-data-parser/src/lib/{form-data.spec.ts => form-data.test.ts} (98%) delete mode 100644 packages/form-data-parser/tsconfig.lib.json delete mode 100644 packages/form-data-parser/tsconfig.spec.json rename packages/headers/src/lib/{accept-language.spec.ts => accept-language.test.ts} (98%) rename packages/headers/src/lib/{cache-control.spec.ts => cache-control.test.ts} (97%) rename packages/headers/src/lib/{content-disposition.spec.ts => content-disposition.test.ts} (99%) rename packages/headers/src/lib/{content-type.spec.ts => content-type.test.ts} (98%) rename packages/headers/src/lib/{cookie.spec.ts => cookie.test.ts} (99%) rename packages/headers/src/lib/{header-names.spec.ts => header-names.test.ts} (98%) rename packages/headers/src/lib/{param-values.spec.ts => param-values.test.ts} (98%) rename packages/headers/src/lib/{set-cookie.spec.ts => set-cookie.test.ts} (99%) rename packages/headers/src/lib/{super-headers.spec.ts => super-headers.test.ts} (97%) delete mode 100644 packages/headers/tsconfig.lib.json delete mode 100644 packages/headers/tsconfig.spec.json rename packages/lazy-file/{src => }/global.d.ts (100%) rename packages/lazy-file/src/lib/{byte-range.spec.ts => byte-range.test.ts} (95%) rename packages/lazy-file/src/lib/{lazy-file.spec.ts => lazy-file.test.ts} (98%) delete mode 100644 packages/lazy-file/tsconfig.lib.json delete mode 100644 packages/lazy-file/tsconfig.spec.json delete mode 100644 packages/multipart-parser/bench/tsconfig.json rename packages/multipart-parser/{bench => }/global.d.ts (100%) rename packages/multipart-parser/src/lib/{multipart.node.spec.ts => multipart.node.test.ts} (93%) rename packages/multipart-parser/src/lib/{multipart.spec.ts => multipart.test.ts} (99%) rename packages/multipart-parser/src/lib/{search.spec.ts => search.test.ts} (99%) delete mode 100644 packages/multipart-parser/tsconfig.lib.json delete mode 100644 packages/multipart-parser/tsconfig.spec.json delete mode 100644 packages/node-fetch-server/bench/tsconfig.json rename packages/{multipart-parser/src => node-fetch-server}/global.d.ts (100%) delete mode 100644 packages/node-fetch-server/src/global.d.ts rename packages/node-fetch-server/src/lib/{request-listener.spec.ts => request-listener.test.ts} (98%) delete mode 100644 packages/node-fetch-server/tsconfig.lib.json delete mode 100644 packages/node-fetch-server/tsconfig.spec.json diff --git a/.vscode/settings.json b/.vscode/settings.json index dbc6d7ee2df..95486a455ae 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,10 @@ { - "deno.enablePaths": ["./packages/multipart-parser/examples/deno"] + "deno.enablePaths": ["./packages/multipart-parser/examples/deno"], + "nodejs-testing.extensions": [ + { + "extensions": ["ts"], + "parameters": ["--experimental-strip-types", "--disable-warning=ExperimentalWarning"] + } + ], + "typescript.tsdk": "node_modules/typescript/lib" } diff --git a/package.json b/package.json index 7f467290f5a..5636d9bfcc2 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,8 @@ "private": true, "packageManager": "pnpm@9.9.0", "devDependencies": { - "prettier": "^3.3.3" + "prettier": "^3.3.3", + "typescript": "^5.7.2" }, "engines": { "node": ">=22" diff --git a/packages/fetch-proxy/package.json b/packages/fetch-proxy/package.json index cbdec6b960d..c8bd3617dd4 100644 --- a/packages/fetch-proxy/package.json +++ b/packages/fetch-proxy/package.json @@ -43,14 +43,12 @@ "@mjackson/headers": "workspace:^" }, "devDependencies": { - "@swc-node/register": "^1.10.9", "@types/node": "^20.14.10", - "tsup": "^8.3.5", - "typescript": "^5.6.3" + "tsup": "^8.3.5" }, "scripts": { "build": "tsup", - "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", + "test": "node --experimental-strip-types --disable-warning=ExperimentalWarning --test ./src/**/*.test.ts", "prepare": "pnpm run build" }, "keywords": [ diff --git a/packages/fetch-proxy/src/fetch-proxy.ts b/packages/fetch-proxy/src/fetch-proxy.ts index 877a9decfd9..3cccccd5ed9 100644 --- a/packages/fetch-proxy/src/fetch-proxy.ts +++ b/packages/fetch-proxy/src/fetch-proxy.ts @@ -1 +1 @@ -export { type FetchProxyOptions, type FetchProxy, createFetchProxy } from './lib/fetch-proxy.js'; +export { type FetchProxyOptions, type FetchProxy, createFetchProxy } from './lib/fetch-proxy.ts'; diff --git a/packages/fetch-proxy/src/lib/fetch-proxy.spec.ts b/packages/fetch-proxy/src/lib/fetch-proxy.test.ts similarity index 98% rename from packages/fetch-proxy/src/lib/fetch-proxy.spec.ts rename to packages/fetch-proxy/src/lib/fetch-proxy.test.ts index 29c56d173ec..ac4c577c18a 100644 --- a/packages/fetch-proxy/src/lib/fetch-proxy.spec.ts +++ b/packages/fetch-proxy/src/lib/fetch-proxy.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { FetchProxyOptions, createFetchProxy } from './fetch-proxy.js'; +import { type FetchProxyOptions, createFetchProxy } from './fetch-proxy.ts'; async function runProxy( request: Request, diff --git a/packages/fetch-proxy/tsconfig.json b/packages/fetch-proxy/tsconfig.json index d8aaef54f9d..745cb65a640 100644 --- a/packages/fetch-proxy/tsconfig.json +++ b/packages/fetch-proxy/tsconfig.json @@ -1,8 +1,12 @@ { "compilerOptions": { - "lib": ["DOM", "ES2020"], - "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true + "strict": true, + "lib": ["DOM", "DOM.Iterable", "ES2020"], + "module": "ES2022", + "moduleResolution": "Bundler", + "target": "ESNext", + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + "verbatimModuleSyntax": true } } diff --git a/packages/fetch-proxy/tsconfig.lib.json b/packages/fetch-proxy/tsconfig.lib.json deleted file mode 100644 index 8e712f7d6c8..00000000000 --- a/packages/fetch-proxy/tsconfig.lib.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts"], - "compilerOptions": { - "composite": true, - "rootDir": "src" - } -} diff --git a/packages/fetch-proxy/tsconfig.spec.json b/packages/fetch-proxy/tsconfig.spec.json deleted file mode 100644 index 456f4c46cca..00000000000 --- a/packages/fetch-proxy/tsconfig.spec.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.spec.ts"], - "compilerOptions": { - "types": ["node"] - } -} diff --git a/packages/file-storage/src/global.d.ts b/packages/file-storage/global.d.ts similarity index 100% rename from packages/file-storage/src/global.d.ts rename to packages/file-storage/global.d.ts diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index 4ab180cbb7c..c299dbc4ed8 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -79,14 +79,12 @@ "@mjackson/lazy-file": "workspace:^" }, "devDependencies": { - "@swc-node/register": "^1.10.9", "@types/node": "^20.14.10", - "tsup": "^8.3.5", - "typescript": "^5.6.3" + "tsup": "^8.3.5" }, "scripts": { "build": "tsup", - "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", + "test": "node --experimental-strip-types --disable-warning=ExperimentalWarning --test ./src/**/*.test.ts", "prepare": "pnpm run build" }, "keywords": [ diff --git a/packages/file-storage/src/lib/local-file-storage.spec.ts b/packages/file-storage/src/lib/local-file-storage.test.ts similarity index 95% rename from packages/file-storage/src/lib/local-file-storage.spec.ts rename to packages/file-storage/src/lib/local-file-storage.test.ts index 5ca4c61d0c5..2d5dfd250cc 100644 --- a/packages/file-storage/src/lib/local-file-storage.spec.ts +++ b/packages/file-storage/src/lib/local-file-storage.test.ts @@ -3,7 +3,7 @@ import { after, describe, it } from 'node:test'; import * as fs from 'node:fs'; import * as path from 'node:path'; -import { LocalFileStorage } from './local-file-storage.js'; +import { LocalFileStorage } from './local-file-storage.ts'; const __dirname = new URL('.', import.meta.url).pathname; diff --git a/packages/file-storage/src/lib/local-file-storage.ts b/packages/file-storage/src/lib/local-file-storage.ts index 355555df644..de4203c469a 100644 --- a/packages/file-storage/src/lib/local-file-storage.ts +++ b/packages/file-storage/src/lib/local-file-storage.ts @@ -3,7 +3,7 @@ import * as fsp from 'node:fs/promises'; import * as path from 'node:path'; import { openFile, writeFile } from '@mjackson/lazy-file/fs'; -import { FileStorage } from './file-storage.js'; +import { type FileStorage } from './file-storage.ts'; /** * A `FileStorage` that is backed by the local filesystem. diff --git a/packages/file-storage/src/lib/memory-file-storage.spec.ts b/packages/file-storage/src/lib/memory-file-storage.test.ts similarity index 92% rename from packages/file-storage/src/lib/memory-file-storage.spec.ts rename to packages/file-storage/src/lib/memory-file-storage.test.ts index fdf094b3965..da0e1f66af5 100644 --- a/packages/file-storage/src/lib/memory-file-storage.spec.ts +++ b/packages/file-storage/src/lib/memory-file-storage.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { MemoryFileStorage } from './memory-file-storage.js'; +import { MemoryFileStorage } from './memory-file-storage.ts'; describe('MemoryFileStorage', () => { it('stores and retrieves files', async () => { diff --git a/packages/file-storage/src/lib/memory-file-storage.ts b/packages/file-storage/src/lib/memory-file-storage.ts index eeb5a5ebeb9..13ece16a3d4 100644 --- a/packages/file-storage/src/lib/memory-file-storage.ts +++ b/packages/file-storage/src/lib/memory-file-storage.ts @@ -1,4 +1,4 @@ -import { FileStorage } from './file-storage.js'; +import { type FileStorage } from './file-storage.ts'; /** * A simple, in-memory implementation of the `FileStorage` interface. diff --git a/packages/file-storage/tsconfig.json b/packages/file-storage/tsconfig.json index d8aaef54f9d..745cb65a640 100644 --- a/packages/file-storage/tsconfig.json +++ b/packages/file-storage/tsconfig.json @@ -1,8 +1,12 @@ { "compilerOptions": { - "lib": ["DOM", "ES2020"], - "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true + "strict": true, + "lib": ["DOM", "DOM.Iterable", "ES2020"], + "module": "ES2022", + "moduleResolution": "Bundler", + "target": "ESNext", + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + "verbatimModuleSyntax": true } } diff --git a/packages/file-storage/tsconfig.lib.json b/packages/file-storage/tsconfig.lib.json deleted file mode 100644 index c9819aa7ed5..00000000000 --- a/packages/file-storage/tsconfig.lib.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts", "src/test/**/*.ts"], - "compilerOptions": { - "composite": true, - "rootDir": "src" - } -} diff --git a/packages/file-storage/tsconfig.spec.json b/packages/file-storage/tsconfig.spec.json deleted file mode 100644 index 0dcc65f3ce6..00000000000 --- a/packages/file-storage/tsconfig.spec.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.spec.ts", "src/test/**/*.ts"], - "compilerOptions": { - "composite": true, - "types": ["node"] - } -} diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index 81168494aa3..7bac8a977b0 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -43,14 +43,12 @@ "@mjackson/multipart-parser": "workspace:^" }, "devDependencies": { - "@swc-node/register": "^1.10.9", "@types/node": "^22.4.1", - "tsup": "^8.3.5", - "typescript": "^5.6.3" + "tsup": "^8.3.5" }, "scripts": { "build": "tsup", - "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", + "test": "node --experimental-strip-types --disable-warning=ExperimentalWarning --test ./src/**/*.test.ts", "prepare": "pnpm run build" }, "keywords": [ diff --git a/packages/form-data-parser/src/form-data-parser.ts b/packages/form-data-parser/src/form-data-parser.ts index e57a4d6d872..56a43048563 100644 --- a/packages/form-data-parser/src/form-data-parser.ts +++ b/packages/form-data-parser/src/form-data-parser.ts @@ -1 +1 @@ -export { FileUpload, type FileUploadHandler, parseFormData } from './lib/form-data.js'; +export { FileUpload, type FileUploadHandler, parseFormData } from './lib/form-data.ts'; diff --git a/packages/form-data-parser/src/lib/form-data.spec.ts b/packages/form-data-parser/src/lib/form-data.test.ts similarity index 98% rename from packages/form-data-parser/src/lib/form-data.spec.ts rename to packages/form-data-parser/src/lib/form-data.test.ts index e9464c6c18c..85ef43cc183 100644 --- a/packages/form-data-parser/src/lib/form-data.spec.ts +++ b/packages/form-data-parser/src/lib/form-data.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it, mock } from 'node:test'; -import { FileUploadHandler, parseFormData } from './form-data.js'; +import { type FileUploadHandler, parseFormData } from './form-data.ts'; describe('parseFormData', () => { it('parses a application/x-www-form-urlencoded request', async () => { diff --git a/packages/form-data-parser/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts index 2651a0096cf..902e98b4598 100644 --- a/packages/form-data-parser/src/lib/form-data.ts +++ b/packages/form-data-parser/src/lib/form-data.ts @@ -1,7 +1,7 @@ import { isMultipartRequest, parseMultipartRequest, - MultipartParserOptions, + type MultipartParserOptions, MultipartPart, } from '@mjackson/multipart-parser'; diff --git a/packages/form-data-parser/tsconfig.json b/packages/form-data-parser/tsconfig.json index d8aaef54f9d..745cb65a640 100644 --- a/packages/form-data-parser/tsconfig.json +++ b/packages/form-data-parser/tsconfig.json @@ -1,8 +1,12 @@ { "compilerOptions": { - "lib": ["DOM", "ES2020"], - "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true + "strict": true, + "lib": ["DOM", "DOM.Iterable", "ES2020"], + "module": "ES2022", + "moduleResolution": "Bundler", + "target": "ESNext", + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + "verbatimModuleSyntax": true } } diff --git a/packages/form-data-parser/tsconfig.lib.json b/packages/form-data-parser/tsconfig.lib.json deleted file mode 100644 index 8e712f7d6c8..00000000000 --- a/packages/form-data-parser/tsconfig.lib.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts"], - "compilerOptions": { - "composite": true, - "rootDir": "src" - } -} diff --git a/packages/form-data-parser/tsconfig.spec.json b/packages/form-data-parser/tsconfig.spec.json deleted file mode 100644 index ccfefc4d957..00000000000 --- a/packages/form-data-parser/tsconfig.spec.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.spec.ts"], - "compilerOptions": { - "composite": true, - "types": ["node"] - } -} diff --git a/packages/headers/package.json b/packages/headers/package.json index 698dc8763aa..f4a61e3efee 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -40,14 +40,12 @@ "./package.json": "./package.json" }, "devDependencies": { - "@swc-node/register": "^1.10.9", "@types/node": "^20.14.10", - "tsup": "^8.3.5", - "typescript": "^5.6.3" + "tsup": "^8.3.5" }, "scripts": { "build": "tsup", - "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", + "test": "node --experimental-strip-types --disable-warning=ExperimentalWarning --test ./src/**/*.test.ts", "prepare": "pnpm run build" }, "keywords": [ diff --git a/packages/headers/src/headers.ts b/packages/headers/src/headers.ts index e8a5376a279..a2d4bce3d16 100644 --- a/packages/headers/src/headers.ts +++ b/packages/headers/src/headers.ts @@ -1,8 +1,12 @@ -export { AcceptLanguageInit, AcceptLanguage } from './lib/accept-language.js'; -export { CacheControlInit, CacheControl } from './lib/cache-control.js'; -export { ContentDispositionInit, ContentDisposition } from './lib/content-disposition.js'; -export { ContentTypeInit, ContentType } from './lib/content-type.js'; -export { CookieInit, Cookie } from './lib/cookie.js'; -export { SetCookieInit, SetCookie } from './lib/set-cookie.js'; +export { type AcceptLanguageInit, AcceptLanguage } from './lib/accept-language.ts'; +export { type CacheControlInit, CacheControl } from './lib/cache-control.ts'; +export { type ContentDispositionInit, ContentDisposition } from './lib/content-disposition.ts'; +export { type ContentTypeInit, ContentType } from './lib/content-type.ts'; +export { type CookieInit, Cookie } from './lib/cookie.ts'; +export { type SetCookieInit, SetCookie } from './lib/set-cookie.ts'; -export { SuperHeaders as default, SuperHeadersInit, SuperHeaders } from './lib/super-headers.js'; +export { + type SuperHeadersInit, + SuperHeaders, + SuperHeaders as default, +} from './lib/super-headers.ts'; diff --git a/packages/headers/src/lib/accept-language.spec.ts b/packages/headers/src/lib/accept-language.test.ts similarity index 98% rename from packages/headers/src/lib/accept-language.spec.ts rename to packages/headers/src/lib/accept-language.test.ts index f1ca9c96b67..cbfb6ee7fde 100644 --- a/packages/headers/src/lib/accept-language.spec.ts +++ b/packages/headers/src/lib/accept-language.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { AcceptLanguage } from './accept-language.js'; +import { AcceptLanguage } from './accept-language.ts'; describe('Accept-Language', () => { it('initializes with an empty string', () => { diff --git a/packages/headers/src/lib/accept-language.ts b/packages/headers/src/lib/accept-language.ts index fa94f3e67f7..0a0eda42e30 100644 --- a/packages/headers/src/lib/accept-language.ts +++ b/packages/headers/src/lib/accept-language.ts @@ -1,6 +1,6 @@ -import { HeaderValue } from './header-value.js'; -import { parseParams } from './param-values.js'; -import { isIterable } from './utils.js'; +import { type HeaderValue } from './header-value.ts'; +import { parseParams } from './param-values.ts'; +import { isIterable } from './utils.ts'; export type AcceptLanguageInit = | Iterable<string | [string] | [string, number | undefined]> diff --git a/packages/headers/src/lib/cache-control.spec.ts b/packages/headers/src/lib/cache-control.test.ts similarity index 97% rename from packages/headers/src/lib/cache-control.spec.ts rename to packages/headers/src/lib/cache-control.test.ts index 2bf72ebe207..f141f25a0b9 100644 --- a/packages/headers/src/lib/cache-control.spec.ts +++ b/packages/headers/src/lib/cache-control.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { CacheControl } from './cache-control.js'; +import { CacheControl } from './cache-control.ts'; describe('CacheControl', () => { it('initializes with an empty string', () => { diff --git a/packages/headers/src/lib/cache-control.ts b/packages/headers/src/lib/cache-control.ts index 3f617db85e8..81fb83ac295 100644 --- a/packages/headers/src/lib/cache-control.ts +++ b/packages/headers/src/lib/cache-control.ts @@ -1,5 +1,5 @@ -import { HeaderValue } from './header-value.js'; -import { parseParams } from './param-values.js'; +import { type HeaderValue } from './header-value.ts'; +import { parseParams } from './param-values.ts'; // Taken from https://github.com/jjenzz/pretty-cache-header by jjenzz // License: MIT https://github.com/jjenzz/pretty-cache-header/blob/main/LICENSE diff --git a/packages/headers/src/lib/content-disposition.spec.ts b/packages/headers/src/lib/content-disposition.test.ts similarity index 99% rename from packages/headers/src/lib/content-disposition.spec.ts rename to packages/headers/src/lib/content-disposition.test.ts index c4a561029df..7acb5f604c3 100644 --- a/packages/headers/src/lib/content-disposition.spec.ts +++ b/packages/headers/src/lib/content-disposition.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { ContentDisposition } from './content-disposition.js'; +import { ContentDisposition } from './content-disposition.ts'; describe('ContentDisposition', () => { it('initializes with an empty string', () => { diff --git a/packages/headers/src/lib/content-disposition.ts b/packages/headers/src/lib/content-disposition.ts index 1c38ce68178..86335f41b2a 100644 --- a/packages/headers/src/lib/content-disposition.ts +++ b/packages/headers/src/lib/content-disposition.ts @@ -1,5 +1,5 @@ -import { HeaderValue } from './header-value.js'; -import { parseParams, quote } from './param-values.js'; +import { type HeaderValue } from './header-value.ts'; +import { parseParams, quote } from './param-values.ts'; export interface ContentDispositionInit { /** diff --git a/packages/headers/src/lib/content-type.spec.ts b/packages/headers/src/lib/content-type.test.ts similarity index 98% rename from packages/headers/src/lib/content-type.spec.ts rename to packages/headers/src/lib/content-type.test.ts index f84a39220f3..8f29cce6c35 100644 --- a/packages/headers/src/lib/content-type.spec.ts +++ b/packages/headers/src/lib/content-type.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { ContentType } from './content-type.js'; +import { ContentType } from './content-type.ts'; describe('ContentType', () => { it('initializes with an empty string', () => { diff --git a/packages/headers/src/lib/content-type.ts b/packages/headers/src/lib/content-type.ts index 3ba2575bce1..a8360da8594 100644 --- a/packages/headers/src/lib/content-type.ts +++ b/packages/headers/src/lib/content-type.ts @@ -1,5 +1,5 @@ -import { HeaderValue } from './header-value.js'; -import { parseParams, quote } from './param-values.js'; +import { type HeaderValue } from './header-value.ts'; +import { parseParams, quote } from './param-values.ts'; export interface ContentTypeInit { /** diff --git a/packages/headers/src/lib/cookie.spec.ts b/packages/headers/src/lib/cookie.test.ts similarity index 99% rename from packages/headers/src/lib/cookie.spec.ts rename to packages/headers/src/lib/cookie.test.ts index fed21aa3b70..3d2d35bb1e6 100644 --- a/packages/headers/src/lib/cookie.spec.ts +++ b/packages/headers/src/lib/cookie.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { Cookie } from './cookie.js'; +import { Cookie } from './cookie.ts'; describe('Cookie', () => { it('initializes with an empty string', () => { diff --git a/packages/headers/src/lib/cookie.ts b/packages/headers/src/lib/cookie.ts index f778435ec0d..3bfd8da9451 100644 --- a/packages/headers/src/lib/cookie.ts +++ b/packages/headers/src/lib/cookie.ts @@ -1,6 +1,6 @@ -import { HeaderValue } from './header-value.js'; -import { parseParams, quote } from './param-values.js'; -import { isIterable } from './utils.js'; +import { type HeaderValue } from './header-value.ts'; +import { parseParams, quote } from './param-values.ts'; +import { isIterable } from './utils.ts'; export type CookieInit = Iterable<[string, string]> | Record<string, string>; diff --git a/packages/headers/src/lib/header-names.spec.ts b/packages/headers/src/lib/header-names.test.ts similarity index 98% rename from packages/headers/src/lib/header-names.spec.ts rename to packages/headers/src/lib/header-names.test.ts index 403ee6f98fa..cc3dc876dfc 100644 --- a/packages/headers/src/lib/header-names.spec.ts +++ b/packages/headers/src/lib/header-names.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { canonicalHeaderName } from './header-names.js'; +import { canonicalHeaderName } from './header-names.ts'; describe('normalizeHeaderName', () => { it('handles common headers correctly', () => { diff --git a/packages/headers/src/lib/param-values.spec.ts b/packages/headers/src/lib/param-values.test.ts similarity index 98% rename from packages/headers/src/lib/param-values.spec.ts rename to packages/headers/src/lib/param-values.test.ts index 9286c65470a..75e898b9f10 100644 --- a/packages/headers/src/lib/param-values.spec.ts +++ b/packages/headers/src/lib/param-values.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { parseParams } from './param-values.js'; +import { parseParams } from './param-values.ts'; describe('parseParams', () => { it('correctly parses a string of parameters for a Content-Type header', () => { diff --git a/packages/headers/src/lib/set-cookie.spec.ts b/packages/headers/src/lib/set-cookie.test.ts similarity index 99% rename from packages/headers/src/lib/set-cookie.spec.ts rename to packages/headers/src/lib/set-cookie.test.ts index fd96f2b655c..91ef68baee7 100644 --- a/packages/headers/src/lib/set-cookie.spec.ts +++ b/packages/headers/src/lib/set-cookie.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { SetCookie } from './set-cookie.js'; +import { SetCookie } from './set-cookie.ts'; describe('SetCookie', () => { it('initializes with an empty string', () => { diff --git a/packages/headers/src/lib/set-cookie.ts b/packages/headers/src/lib/set-cookie.ts index c9a51b5c946..c5f6c7ed7dc 100644 --- a/packages/headers/src/lib/set-cookie.ts +++ b/packages/headers/src/lib/set-cookie.ts @@ -1,6 +1,6 @@ -import { HeaderValue } from './header-value.js'; -import { parseParams, quote } from './param-values.js'; -import { capitalize, isValidDate } from './utils.js'; +import { type HeaderValue } from './header-value.ts'; +import { parseParams, quote } from './param-values.ts'; +import { capitalize, isValidDate } from './utils.ts'; type SameSiteValue = 'Strict' | 'Lax' | 'None'; diff --git a/packages/headers/src/lib/super-headers.spec.ts b/packages/headers/src/lib/super-headers.test.ts similarity index 97% rename from packages/headers/src/lib/super-headers.spec.ts rename to packages/headers/src/lib/super-headers.test.ts index 3f61bdccf45..642418646f3 100644 --- a/packages/headers/src/lib/super-headers.spec.ts +++ b/packages/headers/src/lib/super-headers.test.ts @@ -1,12 +1,12 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { AcceptLanguage } from './accept-language.js'; -import { CacheControl } from './cache-control.js'; -import { ContentDisposition } from './content-disposition.js'; -import { ContentType } from './content-type.js'; -import { Cookie } from './cookie.js'; -import { SuperHeaders } from './super-headers.js'; +import { AcceptLanguage } from './accept-language.ts'; +import { CacheControl } from './cache-control.ts'; +import { ContentDisposition } from './content-disposition.ts'; +import { ContentType } from './content-type.ts'; +import { Cookie } from './cookie.ts'; +import { SuperHeaders } from './super-headers.ts'; describe('SuperHeaders', () => { it('is an instance of Headers', () => { diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index ee0a92af63f..226e3a34a96 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -1,12 +1,12 @@ -import { AcceptLanguageInit, AcceptLanguage } from './accept-language.js'; -import { CacheControlInit, CacheControl } from './cache-control.js'; -import { ContentDispositionInit, ContentDisposition } from './content-disposition.js'; -import { ContentTypeInit, ContentType } from './content-type.js'; -import { CookieInit, Cookie } from './cookie.js'; -import { canonicalHeaderName } from './header-names.js'; -import { HeaderValue } from './header-value.js'; -import { SetCookieInit, SetCookie } from './set-cookie.js'; -import { isIterable, isValidDate } from './utils.js'; +import { type AcceptLanguageInit, AcceptLanguage } from './accept-language.ts'; +import { type CacheControlInit, CacheControl } from './cache-control.ts'; +import { type ContentDispositionInit, ContentDisposition } from './content-disposition.ts'; +import { type ContentTypeInit, ContentType } from './content-type.ts'; +import { type CookieInit, Cookie } from './cookie.ts'; +import { canonicalHeaderName } from './header-names.ts'; +import { type HeaderValue } from './header-value.ts'; +import { type SetCookieInit, SetCookie } from './set-cookie.ts'; +import { isIterable, isValidDate } from './utils.ts'; const CRLF = '\r\n'; const SetCookieKey = 'set-cookie'; diff --git a/packages/headers/tsconfig.json b/packages/headers/tsconfig.json index 4f02f2c73c9..745cb65a640 100644 --- a/packages/headers/tsconfig.json +++ b/packages/headers/tsconfig.json @@ -1,8 +1,12 @@ { "compilerOptions": { + "strict": true, "lib": ["DOM", "DOM.Iterable", "ES2020"], - "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true + "module": "ES2022", + "moduleResolution": "Bundler", + "target": "ESNext", + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + "verbatimModuleSyntax": true } } diff --git a/packages/headers/tsconfig.lib.json b/packages/headers/tsconfig.lib.json deleted file mode 100644 index 8e712f7d6c8..00000000000 --- a/packages/headers/tsconfig.lib.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts"], - "compilerOptions": { - "composite": true, - "rootDir": "src" - } -} diff --git a/packages/headers/tsconfig.spec.json b/packages/headers/tsconfig.spec.json deleted file mode 100644 index 456f4c46cca..00000000000 --- a/packages/headers/tsconfig.spec.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.spec.ts"], - "compilerOptions": { - "types": ["node"] - } -} diff --git a/packages/lazy-file/src/global.d.ts b/packages/lazy-file/global.d.ts similarity index 100% rename from packages/lazy-file/src/global.d.ts rename to packages/lazy-file/global.d.ts diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index 0bb5cfb785e..3a2a534774d 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -61,14 +61,12 @@ "mrmime": "^2.0.0" }, "devDependencies": { - "@swc-node/register": "^1.10.9", "@types/node": "^22.5.0", - "tsup": "^8.3.5", - "typescript": "^5.6.3" + "tsup": "^8.3.5" }, "scripts": { "build": "tsup", - "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", + "test": "node --experimental-strip-types --disable-warning=ExperimentalWarning --test ./src/**/*.test.ts", "prepare": "pnpm run build" }, "keywords": [ diff --git a/packages/lazy-file/src/fs.ts b/packages/lazy-file/src/fs.ts index 2f91f0130e2..f30e03c2209 100644 --- a/packages/lazy-file/src/fs.ts +++ b/packages/lazy-file/src/fs.ts @@ -2,7 +2,7 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; import { lookup } from 'mrmime'; -import { LazyContent, LazyFile } from './lib/lazy-file.js'; +import { type LazyContent, LazyFile } from './lib/lazy-file.ts'; export interface OpenFileOptions { /** diff --git a/packages/lazy-file/src/lazy-file.ts b/packages/lazy-file/src/lazy-file.ts index 8b85430c825..d7440c05519 100644 --- a/packages/lazy-file/src/lazy-file.ts +++ b/packages/lazy-file/src/lazy-file.ts @@ -1,8 +1,8 @@ -export { type ByteRange, getByteLength, getIndexes } from './lib/byte-range.js'; +export { type ByteRange, getByteLength, getIndexes } from './lib/byte-range.ts'; export { type LazyContent, type LazyBlobOptions, LazyBlob, type LazyFileOptions, LazyFile, -} from './lib/lazy-file.js'; +} from './lib/lazy-file.ts'; diff --git a/packages/lazy-file/src/lib/byte-range.spec.ts b/packages/lazy-file/src/lib/byte-range.test.ts similarity index 95% rename from packages/lazy-file/src/lib/byte-range.spec.ts rename to packages/lazy-file/src/lib/byte-range.test.ts index 8bcab887b39..1db58a8dba7 100644 --- a/packages/lazy-file/src/lib/byte-range.spec.ts +++ b/packages/lazy-file/src/lib/byte-range.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { ByteRange, getByteLength, getIndexes } from './byte-range.js'; +import { type ByteRange, getByteLength, getIndexes } from './byte-range.ts'; describe('getByteLength', () => { it('returns the correct length', () => { diff --git a/packages/lazy-file/src/lib/lazy-file.spec.ts b/packages/lazy-file/src/lib/lazy-file.test.ts similarity index 98% rename from packages/lazy-file/src/lib/lazy-file.spec.ts rename to packages/lazy-file/src/lib/lazy-file.test.ts index 08f5251739e..b81e62fb64a 100644 --- a/packages/lazy-file/src/lib/lazy-file.spec.ts +++ b/packages/lazy-file/src/lib/lazy-file.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { LazyContent, LazyFile } from './lazy-file.js'; +import { type LazyContent, LazyFile } from './lazy-file.ts'; function createLazyContent(value = ''): LazyContent { let buffer = new TextEncoder().encode(value); diff --git a/packages/lazy-file/src/lib/lazy-file.ts b/packages/lazy-file/src/lib/lazy-file.ts index 91cd8c3e5d9..c66595f06ab 100644 --- a/packages/lazy-file/src/lib/lazy-file.ts +++ b/packages/lazy-file/src/lib/lazy-file.ts @@ -1,4 +1,4 @@ -import { ByteRange, getByteLength, getIndexes } from './byte-range.js'; +import { type ByteRange, getByteLength, getIndexes } from './byte-range.ts'; /** * A streaming interface for blob/file content. diff --git a/packages/lazy-file/tsconfig.json b/packages/lazy-file/tsconfig.json index d8aaef54f9d..745cb65a640 100644 --- a/packages/lazy-file/tsconfig.json +++ b/packages/lazy-file/tsconfig.json @@ -1,8 +1,12 @@ { "compilerOptions": { - "lib": ["DOM", "ES2020"], - "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true + "strict": true, + "lib": ["DOM", "DOM.Iterable", "ES2020"], + "module": "ES2022", + "moduleResolution": "Bundler", + "target": "ESNext", + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + "verbatimModuleSyntax": true } } diff --git a/packages/lazy-file/tsconfig.lib.json b/packages/lazy-file/tsconfig.lib.json deleted file mode 100644 index 8e712f7d6c8..00000000000 --- a/packages/lazy-file/tsconfig.lib.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts"], - "compilerOptions": { - "composite": true, - "rootDir": "src" - } -} diff --git a/packages/lazy-file/tsconfig.spec.json b/packages/lazy-file/tsconfig.spec.json deleted file mode 100644 index ccfefc4d957..00000000000 --- a/packages/lazy-file/tsconfig.spec.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.spec.ts"], - "compilerOptions": { - "composite": true, - "types": ["node"] - } -} diff --git a/packages/multipart-parser/README.md b/packages/multipart-parser/README.md index 1a24d18e885..5abfddbeee3 100644 --- a/packages/multipart-parser/README.md +++ b/packages/multipart-parser/README.md @@ -32,7 +32,7 @@ deno add @mjackson/multipart-parser The most common use case for `multipart-parser` is handling file uploads when you're building a web server. For this case, the `parseMultipartRequest` function is your friend. It will automatically validate the request is `multipart/form-data`, extract the multipart boundary from the `Content-Type` header, parse all fields and files in the `request.body` stream, and `yield` each one to you as a `MultipartPart` object so you can save it to disk or upload it somewhere. -```typescript +```ts import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser'; async function handleMultipartRequest(request: Request): void { @@ -62,7 +62,7 @@ The main module (`import from "@mjackson/multipart-parser"`) assumes you're work If however you're building a server for Node.js that relies on node-specific APIs like `http.IncomingMessage`, `stream.Readable`, and `buffer.Buffer` (ala Express or `http.createServer`), `multipart-parser` ships with an additional module that works directly with these APIs. -```typescript +```ts import * as http from 'node:http'; import { MultipartParseError } from '@mjackson/multipart-parser'; @@ -94,7 +94,7 @@ server.listen(8080); If you're working directly with multipart boundaries and buffers/streams of multipart data that are not necessarily part of a request, `multipart-parser` provides a lower-level API that you can use directly: -```typescript +```ts import { parseMultipart } from '@mjackson/multipart-parser'; // Get the multipart data from some API, filesystem, etc. @@ -112,7 +112,7 @@ for await (let part of parseMultipart(multipartMessage, boundary)) { If you'd prefer a callback-based API, instantiate your own `MultipartParser` and go for it: -```typescript +```ts import { MultipartParseError, MultipartParser } from '@mjackson/multipart-parser'; let multipartMessage = new Uint8Array(); // or ReadableStream<Uint8Array>, etc. diff --git a/packages/multipart-parser/bench/messages.ts b/packages/multipart-parser/bench/messages.ts index ea6edbcd60a..51d26e9bff0 100644 --- a/packages/multipart-parser/bench/messages.ts +++ b/packages/multipart-parser/bench/messages.ts @@ -1,4 +1,4 @@ -import { concat, getRandomBytes } from './utils.js'; +import { concat, getRandomBytes } from './utils.ts'; const NodeDefaultHighWaterMark = 65536; diff --git a/packages/multipart-parser/bench/package.json b/packages/multipart-parser/bench/package.json index f516f7af336..4bb5e8ce417 100644 --- a/packages/multipart-parser/bench/package.json +++ b/packages/multipart-parser/bench/package.json @@ -10,7 +10,6 @@ }, "devDependencies": { "@types/bun": "^1.1.6", - "@types/busboy": "^1.5.4", - "typescript": "^5.6.3" + "@types/busboy": "^1.5.4" } } diff --git a/packages/multipart-parser/bench/parsers/busboy.ts b/packages/multipart-parser/bench/parsers/busboy.ts index ed3dfc7fced..e612b61c31f 100644 --- a/packages/multipart-parser/bench/parsers/busboy.ts +++ b/packages/multipart-parser/bench/parsers/busboy.ts @@ -1,7 +1,7 @@ import { Readable } from 'node:stream'; import busboy from 'busboy'; -import { MultipartMessage } from '../messages.js'; +import { MultipartMessage } from '../messages.ts'; export function parse(message: MultipartMessage): Promise<number> { let stream = new Readable({ diff --git a/packages/multipart-parser/bench/parsers/fastify-busboy.ts b/packages/multipart-parser/bench/parsers/fastify-busboy.ts index 7bb3cbdd962..7956d19c93a 100644 --- a/packages/multipart-parser/bench/parsers/fastify-busboy.ts +++ b/packages/multipart-parser/bench/parsers/fastify-busboy.ts @@ -1,7 +1,7 @@ import { Readable } from 'node:stream'; -import busboy from '@fastify/busboy'; +import * as busboy from '@fastify/busboy'; -import { MultipartMessage } from '../messages.js'; +import { MultipartMessage } from '../messages.ts'; export function parse(message: MultipartMessage): Promise<number> { let stream = new Readable({ diff --git a/packages/multipart-parser/bench/parsers/multipart-parser.ts b/packages/multipart-parser/bench/parsers/multipart-parser.ts index b3c7216ff7b..681af5b7fcf 100644 --- a/packages/multipart-parser/bench/parsers/multipart-parser.ts +++ b/packages/multipart-parser/bench/parsers/multipart-parser.ts @@ -1,6 +1,6 @@ import { MultipartParser } from '@mjackson/multipart-parser'; -import { MultipartMessage } from '../messages.js'; +import { MultipartMessage } from '../messages.ts'; export async function parse(message: MultipartMessage): Promise<number> { let start = performance.now(); diff --git a/packages/multipart-parser/bench/parsers/multipasta.ts b/packages/multipart-parser/bench/parsers/multipasta.ts index 37b0b2e5237..78d7cde8af3 100644 --- a/packages/multipart-parser/bench/parsers/multipasta.ts +++ b/packages/multipart-parser/bench/parsers/multipasta.ts @@ -1,6 +1,6 @@ import * as Multipasta from 'multipasta'; -import { MultipartMessage } from '../messages.js'; +import { MultipartMessage } from '../messages.ts'; export function parse(message: MultipartMessage): Promise<number> { return new Promise((resolve, reject) => { diff --git a/packages/multipart-parser/bench/runner.ts b/packages/multipart-parser/bench/runner.ts index 14f4739784c..618795d9d56 100644 --- a/packages/multipart-parser/bench/runner.ts +++ b/packages/multipart-parser/bench/runner.ts @@ -1,11 +1,11 @@ import * as os from 'node:os'; import * as process from 'node:process'; -import * as messages from './messages.js'; -import * as busboy from './parsers/busboy.js'; -import * as fastifyBusboy from './parsers/fastify-busboy.js'; -import * as multipartParser from './parsers/multipart-parser.js'; -import * as multipasta from './parsers/multipasta.js'; +import * as messages from './messages.ts'; +import * as busboy from './parsers/busboy.ts'; +import * as fastifyBusboy from './parsers/fastify-busboy.ts'; +import * as multipartParser from './parsers/multipart-parser.ts'; +import * as multipasta from './parsers/multipasta.ts'; const benchmarks = [ { name: '1 small file', message: messages.oneSmallFile }, diff --git a/packages/multipart-parser/bench/tsconfig.json b/packages/multipart-parser/bench/tsconfig.json deleted file mode 100644 index d8aaef54f9d..00000000000 --- a/packages/multipart-parser/bench/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "lib": ["DOM", "ES2020"], - "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true - } -} diff --git a/packages/multipart-parser/examples/bun/package.json b/packages/multipart-parser/examples/bun/package.json index 1218f42e702..b17e970f54a 100644 --- a/packages/multipart-parser/examples/bun/package.json +++ b/packages/multipart-parser/examples/bun/package.json @@ -8,7 +8,7 @@ "devDependencies": { "@types/bun": "^1.1.6", "@types/tmp": "^0.2.6", - "typescript": "^5.6.3" + "typescript": "^5.7.2" }, "scripts": { "start": "bun run server.ts" diff --git a/packages/multipart-parser/examples/cf-workers/package.json b/packages/multipart-parser/examples/cf-workers/package.json index 76c24e93065..132c498ca26 100644 --- a/packages/multipart-parser/examples/cf-workers/package.json +++ b/packages/multipart-parser/examples/cf-workers/package.json @@ -6,7 +6,7 @@ }, "devDependencies": { "@cloudflare/workers-types": "^4.20240725.0", - "typescript": "^5.6.3", + "typescript": "^5.7.2", "wrangler": "^3.60.3" }, "scripts": { diff --git a/packages/multipart-parser/examples/deno/package.json b/packages/multipart-parser/examples/deno/package.json index 3769ccad3d4..1491dcfda68 100644 --- a/packages/multipart-parser/examples/deno/package.json +++ b/packages/multipart-parser/examples/deno/package.json @@ -7,7 +7,7 @@ }, "devDependencies": { "@types/tmp": "^0.2.6", - "typescript": "^5.6.3" + "typescript": "^5.7.2" }, "scripts": { "start": "deno --unstable-byonm run --allow-all main.ts" diff --git a/packages/multipart-parser/examples/node/package.json b/packages/multipart-parser/examples/node/package.json index 9962681886e..3bf77548a28 100644 --- a/packages/multipart-parser/examples/node/package.json +++ b/packages/multipart-parser/examples/node/package.json @@ -9,7 +9,7 @@ "devDependencies": { "@types/node": "^20.14.10", "@types/tmp": "^0.2.6", - "typescript": "^5.6.3" + "typescript": "^5.7.2" }, "scripts": { "start": "node server.js" diff --git a/packages/multipart-parser/bench/global.d.ts b/packages/multipart-parser/global.d.ts similarity index 100% rename from packages/multipart-parser/bench/global.d.ts rename to packages/multipart-parser/global.d.ts diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 038403d6555..b8dd858508a 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -61,18 +61,16 @@ "@mjackson/headers": "workspace:^" }, "devDependencies": { - "@swc-node/register": "^1.10.9", "@types/node": "^20.14.10", - "tsup": "^8.3.5", - "typescript": "^5.6.3" + "tsup": "^8.3.5" }, "scripts": { "bench": "pnpm run bench:node && pnpm run bench:bun && pnpm run bench:deno", "bench:bun": "bun run ./bench/runner.ts", "bench:deno": "deno --unstable-byonm --unstable-sloppy-imports run --allow-sys ./bench/runner.ts", - "bench:node": "node --import @swc-node/register/esm-register ./bench/runner.ts", + "bench:node": "node --experimental-strip-types --disable-warning=ExperimentalWarning ./bench/runner.ts", "build": "tsup", - "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", + "test": "node --experimental-strip-types --disable-warning=ExperimentalWarning --test ./src/**/*.test.ts", "prepare": "pnpm run build" }, "keywords": [ diff --git a/packages/multipart-parser/src/lib/multipart.node.spec.ts b/packages/multipart-parser/src/lib/multipart.node.test.ts similarity index 93% rename from packages/multipart-parser/src/lib/multipart.node.spec.ts rename to packages/multipart-parser/src/lib/multipart.node.test.ts index 490d80fc01e..b3a14b15ff8 100644 --- a/packages/multipart-parser/src/lib/multipart.node.spec.ts +++ b/packages/multipart-parser/src/lib/multipart.node.test.ts @@ -1,10 +1,10 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { getRandomBytes } from '../../test/utils.js'; -import { createMultipartMockRequest } from '../../test/utils.node.js'; +import { getRandomBytes } from '../../test/utils.ts'; +import { createMultipartMockRequest } from '../../test/utils.node.ts'; -import { parseMultipartRequest } from './multipart.node.js'; +import { parseMultipartRequest } from './multipart.node.ts'; describe('parseMultipartRequest (node)', () => { let boundary = 'boundary123'; diff --git a/packages/multipart-parser/src/lib/multipart.node.ts b/packages/multipart-parser/src/lib/multipart.node.ts index 7e5a303e3c3..a550a1da8ab 100644 --- a/packages/multipart-parser/src/lib/multipart.node.ts +++ b/packages/multipart-parser/src/lib/multipart.node.ts @@ -1,13 +1,13 @@ -import * as http from 'node:http'; +import type * as http from 'node:http'; import { Readable } from 'node:stream'; import { getMultipartBoundary, parseMultipart as parseMultipartWeb, MultipartParseError, - MultipartParserOptions, + type MultipartParserOptions, MultipartPart, -} from './multipart.js'; +} from './multipart.ts'; /** * Returns true if the given request is a multipart request. @@ -18,7 +18,7 @@ export function isMultipartRequest(request: http.IncomingMessage): boolean { } /** - * Parse a multipart node.js request and yield each part as a `MultipartPart` object. + * Parse a multipart Node.js request and yield each part as a `MultipartPart` object. */ export async function* parseMultipartRequest( request: http.IncomingMessage, @@ -50,6 +50,10 @@ export async function* parseMultipart( if (data instanceof Readable) { yield* parseMultipartWeb(Readable.toWeb(data), boundary, options); } else { - yield* parseMultipartWeb(data, boundary, options); + yield* parseMultipartWeb( + data as Uint8Array | Iterable<Uint8Array> | AsyncIterable<Uint8Array>, + boundary, + options, + ); } } diff --git a/packages/multipart-parser/src/lib/multipart.spec.ts b/packages/multipart-parser/src/lib/multipart.test.ts similarity index 99% rename from packages/multipart-parser/src/lib/multipart.spec.ts rename to packages/multipart-parser/src/lib/multipart.test.ts index 61a400fb5e8..4866415fc95 100644 --- a/packages/multipart-parser/src/lib/multipart.spec.ts +++ b/packages/multipart-parser/src/lib/multipart.test.ts @@ -1,14 +1,14 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { createMockRequest, createMultipartMockRequest, getRandomBytes } from '../../test/utils.js'; +import { createMockRequest, createMultipartMockRequest, getRandomBytes } from '../../test/utils.ts'; import { isMultipartRequest, parseMultipartRequest, MultipartParseError, getMultipartBoundary, -} from './multipart.js'; +} from './multipart.ts'; const CRLF = '\r\n'; diff --git a/packages/multipart-parser/src/lib/multipart.ts b/packages/multipart-parser/src/lib/multipart.ts index a5ad3c91f18..e2604cc0b7d 100644 --- a/packages/multipart-parser/src/lib/multipart.ts +++ b/packages/multipart-parser/src/lib/multipart.ts @@ -1,11 +1,11 @@ import Headers from '@mjackson/headers'; import { - SearchFunction, + type SearchFunction, createSearch, - PartialTailSearchFunction, + type PartialTailSearchFunction, createPartialTailSearch, -} from './search.js'; +} from './search.ts'; /** * Extracts the boundary string from a `multipart/*` content type. @@ -116,13 +116,11 @@ export interface MultipartParserOptions { maxFileSize?: number; } -const enum MultipartParserState { - Start, - AfterBoundary, - Header, - Body, - Done, -} +const MultipartParserStateStart = 0; +const MultipartParserStateAfterBoundary = 1; +const MultipartParserStateHeader = 2; +const MultipartParserStateBody = 3; +const MultipartParserStateDone = 4; /** * A parser for `multipart/*` HTTP messages. @@ -139,7 +137,7 @@ export class MultipartParser { #findPartialTailBoundary: PartialTailSearchFunction; #boundaryLength: number; - #state = MultipartParserState.Start; + #state = MultipartParserStateStart; #buffer: Uint8Array | null = null; #bodyController: ReadableStreamDefaultController<Uint8Array> | null = null; #bodyLength = 0; @@ -169,7 +167,7 @@ export class MultipartParser { | AsyncIterable<Uint8Array>, handler: (part: MultipartPart) => void, ): Promise<void> { - if (this.#state !== MultipartParserState.Start) { + if (this.#state !== MultipartParserStateStart) { this.#reset(); } @@ -193,7 +191,7 @@ export class MultipartParser { throw new TypeError('Cannot parse multipart message; expected a stream or buffer'); } - if (this.#state !== MultipartParserState.Done) { + if (this.#state !== MultipartParserStateDone) { throw new MultipartParseError('Unexpected end of stream'); } @@ -201,14 +199,14 @@ export class MultipartParser { } #reset(): void { - this.#state = MultipartParserState.Start; + this.#state = MultipartParserStateStart; this.#buffer = null; this.#bodyController = null; this.#bodyLength = 0; } #write(chunk: Uint8Array, handler: (part: MultipartPart) => void): void { - if (this.#state === MultipartParserState.Done) { + if (this.#state === MultipartParserStateDone) { throw new MultipartParseError('Unexpected data after end of stream'); } @@ -225,7 +223,7 @@ export class MultipartParser { } while (true) { - if (this.#state === MultipartParserState.Body) { + if (this.#state === MultipartParserStateBody) { if (chunkLength - index < this.#boundaryLength) { this.#buffer = chunk.subarray(index); break; @@ -252,26 +250,26 @@ export class MultipartParser { index = boundaryIndex + this.#boundaryLength; - this.#state = MultipartParserState.AfterBoundary; + this.#state = MultipartParserStateAfterBoundary; } - if (this.#state === MultipartParserState.AfterBoundary) { + if (this.#state === MultipartParserStateAfterBoundary) { if (chunkLength - index < 2) { this.#buffer = chunk.subarray(index); break; } if (chunk[index] === 45 && chunk[index + 1] === 45) { - this.#state = MultipartParserState.Done; + this.#state = MultipartParserStateDone; break; } index += 2; // Skip \r\n after boundary - this.#state = MultipartParserState.Header; + this.#state = MultipartParserStateHeader; } - if (this.#state === MultipartParserState.Header) { + if (this.#state === MultipartParserStateHeader) { if (chunkLength - index < 4) { this.#buffer = chunk.subarray(index); break; @@ -310,12 +308,12 @@ export class MultipartParser { index = headerEndIndex + 4; // Skip header + \r\n\r\n - this.#state = MultipartParserState.Body; + this.#state = MultipartParserStateBody; continue; } - if (this.#state === MultipartParserState.Start) { + if (this.#state === MultipartParserStateStart) { if (chunkLength < this.#openingBoundaryLength) { this.#buffer = chunk; break; @@ -327,7 +325,7 @@ export class MultipartParser { index = this.#openingBoundaryLength; - this.#state = MultipartParserState.AfterBoundary; + this.#state = MultipartParserStateAfterBoundary; } } } diff --git a/packages/multipart-parser/src/lib/search.spec.ts b/packages/multipart-parser/src/lib/search.test.ts similarity index 99% rename from packages/multipart-parser/src/lib/search.spec.ts rename to packages/multipart-parser/src/lib/search.test.ts index f8ead797f9f..d805a737c4c 100644 --- a/packages/multipart-parser/src/lib/search.spec.ts +++ b/packages/multipart-parser/src/lib/search.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { createSearch, createPartialTailSearch } from './search.js'; +import { createSearch, createPartialTailSearch } from './search.ts'; function buf(string: string): Uint8Array { return new TextEncoder().encode(string); diff --git a/packages/multipart-parser/src/multipart-parser.node.ts b/packages/multipart-parser/src/multipart-parser.node.ts index 4b80d285e0f..44d317b8e0d 100644 --- a/packages/multipart-parser/src/multipart-parser.node.ts +++ b/packages/multipart-parser/src/multipart-parser.node.ts @@ -1 +1 @@ -export { isMultipartRequest, parseMultipartRequest, parseMultipart } from './lib/multipart.node.js'; +export { isMultipartRequest, parseMultipartRequest, parseMultipart } from './lib/multipart.node.ts'; diff --git a/packages/multipart-parser/src/multipart-parser.ts b/packages/multipart-parser/src/multipart-parser.ts index 6b24ef81e3b..6357e0d4a2b 100644 --- a/packages/multipart-parser/src/multipart-parser.ts +++ b/packages/multipart-parser/src/multipart-parser.ts @@ -7,4 +7,4 @@ export { type MultipartParserOptions, MultipartParser, MultipartPart, -} from './lib/multipart.js'; +} from './lib/multipart.ts'; diff --git a/packages/multipart-parser/test/utils.node.ts b/packages/multipart-parser/test/utils.node.ts index ddf8321e4d4..6e358fe7dbf 100644 --- a/packages/multipart-parser/test/utils.node.ts +++ b/packages/multipart-parser/test/utils.node.ts @@ -1,12 +1,12 @@ -import * as http from 'node:http'; -import * as stream from 'node:stream'; +import type * as http from 'node:http'; +import { Readable } from 'node:stream'; -import { PartValue, createMultipartBody } from './utils.js'; +import { type PartValue, createMultipartBody } from './utils.ts'; -export function createReadable(content: Uint8Array, chunkSize = 16 * 1024): stream.Readable { +export function createReadable(content: Uint8Array, chunkSize = 16 * 1024): Readable { let i = 0; - return new stream.Readable({ + return new Readable({ read() { if (i < content.length) { this.push(content.subarray(i, i + chunkSize)); diff --git a/packages/multipart-parser/tsconfig.json b/packages/multipart-parser/tsconfig.json index d8aaef54f9d..745cb65a640 100644 --- a/packages/multipart-parser/tsconfig.json +++ b/packages/multipart-parser/tsconfig.json @@ -1,8 +1,12 @@ { "compilerOptions": { - "lib": ["DOM", "ES2020"], - "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true + "strict": true, + "lib": ["DOM", "DOM.Iterable", "ES2020"], + "module": "ES2022", + "moduleResolution": "Bundler", + "target": "ESNext", + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + "verbatimModuleSyntax": true } } diff --git a/packages/multipart-parser/tsconfig.lib.json b/packages/multipart-parser/tsconfig.lib.json deleted file mode 100644 index 8e712f7d6c8..00000000000 --- a/packages/multipart-parser/tsconfig.lib.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts"], - "compilerOptions": { - "composite": true, - "rootDir": "src" - } -} diff --git a/packages/multipart-parser/tsconfig.spec.json b/packages/multipart-parser/tsconfig.spec.json deleted file mode 100644 index 547e6dabbd4..00000000000 --- a/packages/multipart-parser/tsconfig.spec.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.spec.ts", "test/**/*.ts"], - "compilerOptions": { - "composite": true, - "types": ["node"] - } -} diff --git a/packages/node-fetch-server/bench/runner.sh b/packages/node-fetch-server/bench/runner.sh index a86b26d2629..be3d5dc1412 100755 --- a/packages/node-fetch-server/bench/runner.sh +++ b/packages/node-fetch-server/bench/runner.sh @@ -31,14 +31,14 @@ echo $(node -e 'console.log(`Date: ${new Date().toLocaleString()}`)') NODE_VERSION=$(node -e 'console.log(process.version.slice(1))') run_benchmark "node:http@$NODE_VERSION" \ - "node --import @swc-node/register/esm-register ./servers/node-http.ts" + "node --experimental-strip-types --disable-warning=ExperimentalWarning ./servers/node-http.ts" NODE_FETCH_SERVER_VERSION=$(node -e 'console.log(require("../package.json").version)') run_benchmark "node-fetch-server@$NODE_FETCH_SERVER_VERSION" \ - "node --import @swc-node/register/esm-register ./servers/node-fetch-server.ts" + "node --experimental-strip-types --disable-warning=ExperimentalWarning ./servers/node-fetch-server.ts" EXPRESS_VERSION=$(node -e 'console.log(require("express/package.json").version)') run_benchmark "express@$EXPRESS_VERSION" \ - "node --import @swc-node/register/esm-register ./servers/express.ts" + "node --experimental-strip-types --disable-warning=ExperimentalWarning ./servers/express.ts" popd > /dev/null diff --git a/packages/node-fetch-server/bench/tsconfig.json b/packages/node-fetch-server/bench/tsconfig.json deleted file mode 100644 index d8aaef54f9d..00000000000 --- a/packages/node-fetch-server/bench/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "lib": ["DOM", "ES2020"], - "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true - } -} diff --git a/packages/multipart-parser/src/global.d.ts b/packages/node-fetch-server/global.d.ts similarity index 100% rename from packages/multipart-parser/src/global.d.ts rename to packages/node-fetch-server/global.d.ts diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index b17532df7a7..ad2b161e435 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -40,15 +40,13 @@ "./package.json": "./package.json" }, "devDependencies": { - "@swc-node/register": "^1.10.9", "@types/node": "^22.5.0", - "tsup": "^8.3.5", - "typescript": "^5.6.3" + "tsup": "^8.3.5" }, "scripts": { "bench": "bash ./bench/runner.sh", "build": "tsup", - "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", + "test": "node --experimental-strip-types --disable-warning=ExperimentalWarning --test ./src/**/*.test.ts", "prepare": "pnpm run build" }, "keywords": [ diff --git a/packages/node-fetch-server/src/global.d.ts b/packages/node-fetch-server/src/global.d.ts deleted file mode 100644 index b8041179bc5..00000000000 --- a/packages/node-fetch-server/src/global.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -// See https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62651 - -interface ReadableStream<R = any> { - values(options?: { preventCancel?: boolean }): AsyncIterableIterator<R>; - [Symbol.asyncIterator](): AsyncIterableIterator<R>; -} diff --git a/packages/node-fetch-server/src/lib/request-listener.spec.ts b/packages/node-fetch-server/src/lib/request-listener.test.ts similarity index 98% rename from packages/node-fetch-server/src/lib/request-listener.spec.ts rename to packages/node-fetch-server/src/lib/request-listener.test.ts index 2b6c793d46c..2edc7ec52ef 100644 --- a/packages/node-fetch-server/src/lib/request-listener.spec.ts +++ b/packages/node-fetch-server/src/lib/request-listener.test.ts @@ -4,8 +4,8 @@ import { describe, it, mock } from 'node:test'; import * as http from 'node:http'; import * as stream from 'node:stream'; -import { FetchHandler } from './fetch-handler.js'; -import { createRequestListener } from './request-listener.js'; +import { type FetchHandler } from './fetch-handler.ts'; +import { createRequestListener } from './request-listener.ts'; describe('createRequestListener', () => { it('returns a request listener', async () => { diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index dc47eb44960..800a5fa68cb 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -1,6 +1,6 @@ -import * as http from 'node:http'; +import type * as http from 'node:http'; -import { ClientAddress, ErrorHandler, FetchHandler } from './fetch-handler.js'; +import { type ClientAddress, type ErrorHandler, type FetchHandler } from './fetch-handler.ts'; export interface RequestListenerOptions { /** diff --git a/packages/node-fetch-server/src/node-fetch-server.ts b/packages/node-fetch-server/src/node-fetch-server.ts index 3825deb9063..611baf0510c 100644 --- a/packages/node-fetch-server/src/node-fetch-server.ts +++ b/packages/node-fetch-server/src/node-fetch-server.ts @@ -1,4 +1,4 @@ -export { type ClientAddress, type ErrorHandler, type FetchHandler } from './lib/fetch-handler.js'; +export { type ClientAddress, type ErrorHandler, type FetchHandler } from './lib/fetch-handler.ts'; export { type RequestListenerOptions, createRequestListener, @@ -6,4 +6,4 @@ export { createRequest, createHeaders, sendResponse, -} from './lib/request-listener.js'; +} from './lib/request-listener.ts'; diff --git a/packages/node-fetch-server/tsconfig.json b/packages/node-fetch-server/tsconfig.json index 4f02f2c73c9..745cb65a640 100644 --- a/packages/node-fetch-server/tsconfig.json +++ b/packages/node-fetch-server/tsconfig.json @@ -1,8 +1,12 @@ { "compilerOptions": { + "strict": true, "lib": ["DOM", "DOM.Iterable", "ES2020"], - "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true + "module": "ES2022", + "moduleResolution": "Bundler", + "target": "ESNext", + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + "verbatimModuleSyntax": true } } diff --git a/packages/node-fetch-server/tsconfig.lib.json b/packages/node-fetch-server/tsconfig.lib.json deleted file mode 100644 index 8e712f7d6c8..00000000000 --- a/packages/node-fetch-server/tsconfig.lib.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts"], - "compilerOptions": { - "composite": true, - "rootDir": "src" - } -} diff --git a/packages/node-fetch-server/tsconfig.spec.json b/packages/node-fetch-server/tsconfig.spec.json deleted file mode 100644 index ccfefc4d957..00000000000 --- a/packages/node-fetch-server/tsconfig.spec.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.spec.ts"], - "compilerOptions": { - "composite": true, - "types": ["node"] - } -} diff --git a/packages/node-fetch-server/tsup.config.ts b/packages/node-fetch-server/tsup.config.ts index 8b826dd4eb6..4003c2b0aef 100644 --- a/packages/node-fetch-server/tsup.config.ts +++ b/packages/node-fetch-server/tsup.config.ts @@ -5,5 +5,5 @@ export default defineConfig({ dts: true, entry: ['src/node-fetch-server.ts'], format: ['cjs', 'esm'], - platform: 'neutral', + platform: 'node', }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f33448354c5..6c2e11d296c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: prettier: specifier: ^3.3.3 version: 3.3.3 + typescript: + specifier: ^5.7.2 + version: 5.7.2 packages/fetch-proxy: dependencies: @@ -18,18 +21,12 @@ importers: specifier: workspace:^ version: link:../headers devDependencies: - '@swc-node/register': - specifier: ^1.10.9 - version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^20.14.10 version: 20.16.1 tsup: specifier: ^8.3.5 - version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) - typescript: - specifier: ^5.6.3 - version: 5.6.3 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.7.2) packages/file-storage: dependencies: @@ -37,18 +34,12 @@ importers: specifier: workspace:^ version: link:../lazy-file devDependencies: - '@swc-node/register': - specifier: ^1.10.9 - version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^20.14.10 version: 20.16.1 tsup: specifier: ^8.3.5 - version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) - typescript: - specifier: ^5.6.3 - version: 5.6.3 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.7.2) packages/form-data-parser: dependencies: @@ -56,33 +47,21 @@ importers: specifier: workspace:^ version: link:../multipart-parser devDependencies: - '@swc-node/register': - specifier: ^1.10.9 - version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^22.4.1 version: 22.5.0 tsup: specifier: ^8.3.5 - version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) - typescript: - specifier: ^5.6.3 - version: 5.6.3 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.7.2) packages/headers: devDependencies: - '@swc-node/register': - specifier: ^1.10.9 - version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^20.14.10 version: 20.16.1 tsup: specifier: ^8.3.5 - version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) - typescript: - specifier: ^5.6.3 - version: 5.6.3 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.7.2) packages/lazy-file: dependencies: @@ -90,18 +69,12 @@ importers: specifier: ^2.0.0 version: 2.0.0 devDependencies: - '@swc-node/register': - specifier: ^1.10.9 - version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^22.5.0 version: 22.5.0 tsup: specifier: ^8.3.5 - version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) - typescript: - specifier: ^5.6.3 - version: 5.6.3 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.7.2) packages/multipart-parser: dependencies: @@ -109,18 +82,12 @@ importers: specifier: workspace:^ version: link:../headers devDependencies: - '@swc-node/register': - specifier: ^1.10.9 - version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^20.14.10 version: 20.16.1 tsup: specifier: ^8.3.5 - version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) - typescript: - specifier: ^5.6.3 - version: 5.6.3 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.7.2) packages/multipart-parser/bench: dependencies: @@ -143,9 +110,6 @@ importers: '@types/busboy': specifier: ^1.5.4 version: 1.5.4 - typescript: - specifier: ^5.6.3 - version: 5.6.3 packages/multipart-parser/examples/bun: dependencies: @@ -163,8 +127,8 @@ importers: specifier: ^0.2.6 version: 0.2.6 typescript: - specifier: ^5.6.3 - version: 5.6.3 + specifier: ^5.7.2 + version: 5.7.2 packages/multipart-parser/examples/cf-workers: dependencies: @@ -176,8 +140,8 @@ importers: specifier: ^4.20240725.0 version: 4.20240821.1 typescript: - specifier: ^5.6.3 - version: 5.6.3 + specifier: ^5.7.2 + version: 5.7.2 wrangler: specifier: ^3.60.3 version: 3.72.3(@cloudflare/workers-types@4.20240821.1) @@ -195,8 +159,8 @@ importers: specifier: ^0.2.6 version: 0.2.6 typescript: - specifier: ^5.6.3 - version: 5.6.3 + specifier: ^5.7.2 + version: 5.7.2 packages/multipart-parser/examples/node: dependencies: @@ -214,23 +178,17 @@ importers: specifier: ^0.2.6 version: 0.2.6 typescript: - specifier: ^5.6.3 - version: 5.6.3 + specifier: ^5.7.2 + version: 5.7.2 packages/node-fetch-server: devDependencies: - '@swc-node/register': - specifier: ^1.10.9 - version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^22.5.0 version: 22.5.0 tsup: specifier: ^8.3.5 - version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3) - typescript: - specifier: ^5.6.3 - version: 5.6.3 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.7.2) packages/node-fetch-server/bench: dependencies: @@ -307,15 +265,6 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} - '@emnapi/core@1.2.0': - resolution: {integrity: sha512-E7Vgw78I93we4ZWdYCb4DGAwRROGkMIXk7/y87UmANR+J6qsWusmC3gLt0H+O0KOt5e6O38U8oJamgbudrES/w==} - - '@emnapi/runtime@1.2.0': - resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==} - - '@emnapi/wasi-threads@1.0.1': - resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} - '@esbuild-plugins/node-globals-polyfill@0.2.3': resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} peerDependencies: @@ -634,9 +583,6 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@napi-rs/wasm-runtime@0.2.4': - resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} - '@octokit/endpoint@10.1.1': resolution: {integrity: sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==} engines: {node: '>= 18'} @@ -655,61 +601,6 @@ packages: '@octokit/types@13.6.2': resolution: {integrity: sha512-WpbZfZUcZU77DrSW4wbsSgTPfKcp286q3ItaIgvSbBpZJlu6mnYXAkjZz6LVZPXkEvLIM8McanyZejKTYUHipA==} - '@oxc-resolver/binding-darwin-arm64@1.11.0': - resolution: {integrity: sha512-jjhTgaTMhJ5lpE/OiqF5eX7Nhy5gPZBjZNqwmZstbHmqujfVs1MGiTEXHWgKUrcFdLnENWtuoIR3Kmdp3/vuqw==} - cpu: [arm64] - os: [darwin] - - '@oxc-resolver/binding-darwin-x64@1.11.0': - resolution: {integrity: sha512-w/svTRKnuRinojYAVsWRozVoPar7XUPlJhpfnsYlReRjls6A53/ziTzHfpmcKjdBrP/AXPcDVJDnM4pOSsvWvA==} - cpu: [x64] - os: [darwin] - - '@oxc-resolver/binding-freebsd-x64@1.11.0': - resolution: {integrity: sha512-thGp8g8maYUx7vYJqD0vSsuUO95vWNJwKS2AXchq212J5dQ0Dybq4gjt2O2N9iU+lxj1QzmIDXGw7q5HCagOiw==} - cpu: [x64] - os: [freebsd] - - '@oxc-resolver/binding-linux-arm-gnueabihf@1.11.0': - resolution: {integrity: sha512-8G99bs4cnwpJRjRK2cEJXiJVyLogzPJq4JgLlcMEKSGhdkoMV1Ia0dghLk9lAFog33U4lWIwKmPgqQzTO6JM8g==} - cpu: [arm] - os: [linux] - - '@oxc-resolver/binding-linux-arm64-gnu@1.11.0': - resolution: {integrity: sha512-hNcB/wbuCFbsspg4h9+Nz5gSL8PbRW7zG/eVvmEpzGhmVubzDFuNmlYtmaUaZ6b9jzOrrqTkYCt9t7Q2TDHnBA==} - cpu: [arm64] - os: [linux] - - '@oxc-resolver/binding-linux-arm64-musl@1.11.0': - resolution: {integrity: sha512-H9rjqCcNQT9aip1VLrtsiyj9So0DEKUoutMNu1oL9UuD3H5lWIaxhDlHTAFsobWeUHCnuaCbizhGb9wyLRHSuA==} - cpu: [arm64] - os: [linux] - - '@oxc-resolver/binding-linux-x64-gnu@1.11.0': - resolution: {integrity: sha512-6hdv/kmaGysK3/hUaGTYG07yX+nvk6hGoWombmOuc0vBnGLRtSjqvvgDBdAs9/iIcOSQI2YNUEiJvTyy6eb5GA==} - cpu: [x64] - os: [linux] - - '@oxc-resolver/binding-linux-x64-musl@1.11.0': - resolution: {integrity: sha512-AYUvI4VwQkBq0rcYI3Z7a9+BpllbllbxQCD30ZRgHghvqXvDECWfP8r98iynz7u0oKGO8ZPf15d/l9VrkRtiuQ==} - cpu: [x64] - os: [linux] - - '@oxc-resolver/binding-wasm32-wasi@1.11.0': - resolution: {integrity: sha512-vhXnOs34q8p7QhqQ04bIGy7ZzLEHBaBTsqh2wpAzSBCmjL7MmTpM8KWwXFPFB+Wj0P7/parjGDHzbZG20pEePg==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@oxc-resolver/binding-win32-arm64-msvc@1.11.0': - resolution: {integrity: sha512-5XMm8EELDkAVQoMGv4QKqi+SjWnhcU1aq5B9q59iqiXIBNAs72f0d3LAldLrqE2XomP2QweorpsoxuGuIk2Cnw==} - cpu: [arm64] - os: [win32] - - '@oxc-resolver/binding-win32-x64-msvc@1.11.0': - resolution: {integrity: sha512-rVKiZSTgao4SBWyqWvStxDhKmwbKEN/E8+H3CJzIP4FcsL7MQtWH2HT86bmoefkyRe1yO+m2/mG7j3TfADh/Fg==} - cpu: [x64] - os: [win32] - '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -804,22 +695,6 @@ packages: cpu: [x64] os: [win32] - '@swc-node/core@1.13.3': - resolution: {integrity: sha512-OGsvXIid2Go21kiNqeTIn79jcaX4l0G93X2rAnas4LFoDyA9wAwVK7xZdm+QsKoMn5Mus2yFLCc4OtX2dD/PWA==} - engines: {node: '>= 10'} - peerDependencies: - '@swc/core': '>= 1.4.13' - '@swc/types': '>= 0.1' - - '@swc-node/register@1.10.9': - resolution: {integrity: sha512-iXy2sjP0phPEpK2yivjRC3PAgoLaT4sjSk0LDWCTdcTBJmR4waEog0E6eJbvoOkLkOtWw37SB8vCkl/bbh4+8A==} - peerDependencies: - '@swc/core': '>= 1.4.13' - typescript: '>= 4.3' - - '@swc-node/sourcemap-support@0.5.1': - resolution: {integrity: sha512-JxIvIo/Hrpv0JCHSyRpetAdQ6lB27oFYhv0PKCNf1g2gUXOjpeR1exrXccRxLMuAV5WAmGFBwRnNOJqN38+qtg==} - '@swc/core-darwin-arm64@1.5.29': resolution: {integrity: sha512-6F/sSxpHaq3nzg2ADv9FHLi4Fu2A8w8vP8Ich8gIl16D2htStlwnaPmCLjRswO+cFkzgVqy/l01gzNGWd4DFqA==} engines: {node: '>=10'} @@ -898,9 +773,6 @@ packages: '@swc/types@0.1.12': resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==} - '@tybys/wasm-util@0.9.0': - resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} - '@types/body-parser@1.19.5': resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} @@ -1027,9 +899,6 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - bun-types@1.1.26: resolution: {integrity: sha512-n7jDe62LsB2+WE8Q8/mT3azkPaatKlj/2MyP6hi3mKvPz9oPpB6JW/Ll6JHtNLudasFFuvfgklYSE+rreGvBjw==} @@ -1073,9 +942,6 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - colorette@2.0.20: - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -1448,9 +1314,6 @@ packages: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} - oxc-resolver@1.11.0: - resolution: {integrity: sha512-N3qMse2AM7uST8PaiUMXZkcACyGAMN073tomyvzHTICSzaOqKHvVS0IZ3vj/OqoE140QP4CyOiWmgC1Hw5Urmg==} - package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} @@ -1620,9 +1483,6 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} @@ -1737,8 +1597,8 @@ packages: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} - typescript@5.6.3: - resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + typescript@5.7.2: + resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} engines: {node: '>=14.17'} hasBin: true @@ -1857,22 +1717,6 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 - '@emnapi/core@1.2.0': - dependencies: - '@emnapi/wasi-threads': 1.0.1 - tslib: 2.7.0 - optional: true - - '@emnapi/runtime@1.2.0': - dependencies: - tslib: 2.7.0 - optional: true - - '@emnapi/wasi-threads@1.0.1': - dependencies: - tslib: 2.7.0 - optional: true - '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': dependencies: esbuild: 0.17.19 @@ -2056,13 +1900,6 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@napi-rs/wasm-runtime@0.2.4': - dependencies: - '@emnapi/core': 1.2.0 - '@emnapi/runtime': 1.2.0 - '@tybys/wasm-util': 0.9.0 - optional: true - '@octokit/endpoint@10.1.1': dependencies: '@octokit/types': 13.6.2 @@ -2085,41 +1922,6 @@ snapshots: dependencies: '@octokit/openapi-types': 22.2.0 - '@oxc-resolver/binding-darwin-arm64@1.11.0': - optional: true - - '@oxc-resolver/binding-darwin-x64@1.11.0': - optional: true - - '@oxc-resolver/binding-freebsd-x64@1.11.0': - optional: true - - '@oxc-resolver/binding-linux-arm-gnueabihf@1.11.0': - optional: true - - '@oxc-resolver/binding-linux-arm64-gnu@1.11.0': - optional: true - - '@oxc-resolver/binding-linux-arm64-musl@1.11.0': - optional: true - - '@oxc-resolver/binding-linux-x64-gnu@1.11.0': - optional: true - - '@oxc-resolver/binding-linux-x64-musl@1.11.0': - optional: true - - '@oxc-resolver/binding-wasm32-wasi@1.11.0': - dependencies: - '@napi-rs/wasm-runtime': 0.2.4 - optional: true - - '@oxc-resolver/binding-win32-arm64-msvc@1.11.0': - optional: true - - '@oxc-resolver/binding-win32-x64-msvc@1.11.0': - optional: true - '@pkgjs/parseargs@0.11.0': optional: true @@ -2177,31 +1979,6 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.26.0': optional: true - '@swc-node/core@1.13.3(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)': - dependencies: - '@swc/core': 1.5.29(@swc/helpers@0.5.12) - '@swc/types': 0.1.12 - - '@swc-node/register@1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3)': - dependencies: - '@swc-node/core': 1.13.3(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12) - '@swc-node/sourcemap-support': 0.5.1 - '@swc/core': 1.5.29(@swc/helpers@0.5.12) - colorette: 2.0.20 - debug: 4.3.7 - oxc-resolver: 1.11.0 - pirates: 4.0.6 - tslib: 2.7.0 - typescript: 5.6.3 - transitivePeerDependencies: - - '@swc/types' - - supports-color - - '@swc-node/sourcemap-support@0.5.1': - dependencies: - source-map-support: 0.5.21 - tslib: 2.7.0 - '@swc/core-darwin-arm64@1.5.29': optional: true @@ -2248,8 +2025,10 @@ snapshots: '@swc/core-win32-ia32-msvc': 1.5.29 '@swc/core-win32-x64-msvc': 1.5.29 '@swc/helpers': 0.5.12 + optional: true - '@swc/counter@0.1.3': {} + '@swc/counter@0.1.3': + optional: true '@swc/helpers@0.5.12': dependencies: @@ -2259,10 +2038,6 @@ snapshots: '@swc/types@0.1.12': dependencies: '@swc/counter': 0.1.3 - - '@tybys/wasm-util@0.9.0': - dependencies: - tslib: 2.7.0 optional: true '@types/body-parser@1.19.5': @@ -2410,8 +2185,6 @@ snapshots: dependencies: fill-range: 7.1.1 - buffer-from@1.1.2: {} - bun-types@1.1.26: dependencies: '@types/node': 20.12.14 @@ -2467,8 +2240,6 @@ snapshots: color-name@1.1.4: {} - colorette@2.0.20: {} - commander@4.1.1: {} consola@3.2.3: {} @@ -2846,20 +2617,6 @@ snapshots: dependencies: ee-first: 1.1.1 - oxc-resolver@1.11.0: - optionalDependencies: - '@oxc-resolver/binding-darwin-arm64': 1.11.0 - '@oxc-resolver/binding-darwin-x64': 1.11.0 - '@oxc-resolver/binding-freebsd-x64': 1.11.0 - '@oxc-resolver/binding-linux-arm-gnueabihf': 1.11.0 - '@oxc-resolver/binding-linux-arm64-gnu': 1.11.0 - '@oxc-resolver/binding-linux-arm64-musl': 1.11.0 - '@oxc-resolver/binding-linux-x64-gnu': 1.11.0 - '@oxc-resolver/binding-linux-x64-musl': 1.11.0 - '@oxc-resolver/binding-wasm32-wasi': 1.11.0 - '@oxc-resolver/binding-win32-arm64-msvc': 1.11.0 - '@oxc-resolver/binding-win32-x64-msvc': 1.11.0 - package-json-from-dist@1.0.1: {} parseurl@1.3.3: {} @@ -3033,11 +2790,6 @@ snapshots: signal-exit@4.1.0: {} - source-map-support@0.5.21: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - source-map@0.6.1: {} source-map@0.8.0-beta.0: @@ -3122,7 +2874,7 @@ snapshots: tslib@2.7.0: {} - tsup@8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.6.3): + tsup@8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.7.2): dependencies: bundle-require: 5.0.0(esbuild@0.24.0) cac: 6.7.14 @@ -3142,7 +2894,7 @@ snapshots: tree-kill: 1.2.2 optionalDependencies: '@swc/core': 1.5.29(@swc/helpers@0.5.12) - typescript: 5.6.3 + typescript: 5.7.2 transitivePeerDependencies: - jiti - supports-color @@ -3154,7 +2906,7 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 - typescript@5.6.3: {} + typescript@5.7.2: {} ufo@1.5.4: {} From 0ca5c147353081beb4a9580e9816263b055fc3fb Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 5 Dec 2024 17:02:23 -0800 Subject: [PATCH 517/730] Update contributing doc --- CONTRIBUTING.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fe9eb7eca9e..41e56ea12f7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,42 @@ +Welcome to `remix-the-web`! + +## Setting Up Your Environment + +First off, [install `pnpm`](https://pnpm.io/installation) somewhere globally on your machine. It's the tool we use to manage dependencies and run tasks in this workspace. + +If you're using [VS Code](https://code.visualstudio.com/) you should also install [the `node:test runner` extension](https://marketplace.visualstudio.com/items?itemName=connor4312.nodejs-testing) which provides an integrated experience when running the tests. + +When you've done that, run `pnpm install` to install all dependencies and run a build. You can also run `pnpm test` to run all tests in the repo. + ## Making Changes +You can find all packages in [the `packages` directory](https://github.com/mjackson/remix-the-web/tree/main/packages). Inside each package you'll find a few common files including: + +- `CHANGELOG.md` +- `package.json` +- `README.md` + +When you make changes to a package, please make sure you add a few relevant tests and run the whole test suite to make sure everything still works. Then, add a human-friendly description of your change in the changelog and [make a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). We will take a look at it as soon as we can. + ## Releases + +Cutting releases is a 2-step process: + +- Update versions in package.json, jsr.json (if applicable), and the changelog and create a git tag +- Publish new packages to npm/JSR and create a GitHub Release + +This repo includes a script for each step. + +To update versions and create a tag, use `pnpm run tag-release <packageName> <releaseType>`. For example, to create a `minor` release of the `headers` package, run: + +```sh +pnpm run tag-release headers minor +``` + +To publish the release you just tagged, use `pnpm run publish-release <tag>`. For example, if the tag that was created in the previous step was `headers@1.0.0`, you'd run `pnpm run publish-release headers@1.0.0`. + +The publish step runs in GitHub Actions if you just push the tag to GitHub: + +```sh +git push origin main --tags +``` From 24a78a077986010e1fd324be45effd9bdee81a5e Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 6 Dec 2024 08:38:41 -0800 Subject: [PATCH 518/730] Add some links to doc comments --- packages/lazy-file/src/lib/lazy-file.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/lazy-file/src/lib/lazy-file.ts b/packages/lazy-file/src/lib/lazy-file.ts index c66595f06ab..d04484fc6bd 100644 --- a/packages/lazy-file/src/lib/lazy-file.ts +++ b/packages/lazy-file/src/lib/lazy-file.ts @@ -30,8 +30,9 @@ export interface LazyBlobOptions { } /** - * A `Blob` that may be backed by a stream of data. This is useful for working with large blobs that - * would be impractical to load into memory all at once. + * A [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) that may be backed by a stream + * of data. This is useful for working with large blobs that would be impractical to load into + * memory all at once. * * This class is an extension of JavaScript's built-in `Blob` class with the following additions: * @@ -52,7 +53,7 @@ export class LazyBlob extends Blob { } /** - * Returns the blob's contents as an `ArrayBuffer`. + * Returns the blob's contents as an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer). * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer) */ @@ -79,7 +80,7 @@ export class LazyBlob extends Blob { } /** - * Returns a new `Blob` that contains the data in the specified range. + * Returns a new [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) that contains the data in the specified range. * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) */ @@ -116,8 +117,9 @@ export interface LazyFileOptions extends LazyBlobOptions { } /** - * A `File` that may be backed by a stream of data. This is useful for working with large files that - * would be impractical to load into memory all at once. + * A [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) that may be backed by a stream + * of data. This is useful for working with large files that would be impractical to load into + * memory all at once. * * This class is an extension of JavaScript's built-in `File` class with the following additions: * @@ -138,7 +140,7 @@ export class LazyFile extends File { } /** - * Returns the file's content as an `ArrayBuffer`. + * Returns the file's content as an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer). * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer) */ @@ -165,7 +167,7 @@ export class LazyFile extends File { } /** - * Returns a new `Blob` that contains the data in the specified range. + * Returns a new [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) that contains the data in the specified range. * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) */ From f319fa4e70ab4f4fde83d0c2b5c56050002b7bc9 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Fri, 4 Oct 2024 03:55:33 +0200 Subject: [PATCH 519/730] Initial commit of tar-parser --- packages/tar-parser/CHANGELOG.md | 3 + packages/tar-parser/LICENSE | 21 + packages/tar-parser/README.md | 221 ++++++++ packages/tar-parser/bench/global.d.ts | 8 + packages/tar-parser/bench/messages.ts | 63 +++ packages/tar-parser/bench/package.json | 15 + packages/tar-parser/bench/parsers/busboy.ts | 38 ++ .../bench/parsers/fastify-busboy.ts | 38 ++ .../bench/parsers/multipart-parser.ts | 13 + .../tar-parser/bench/parsers/multipasta.ts | 24 + packages/tar-parser/bench/runner.ts | 90 ++++ packages/tar-parser/bench/tsconfig.json | 8 + packages/tar-parser/bench/utils.ts | 28 + packages/tar-parser/package.json | 41 ++ packages/tar-parser/src/global.d.ts | 6 + packages/tar-parser/src/lib/multipart.spec.ts | 293 +++++++++++ packages/tar-parser/src/lib/multipart.ts | 478 ++++++++++++++++++ packages/tar-parser/src/lib/tar.ts | 320 ++++++++++++ packages/tar-parser/src/tar-parser.ts | 6 + packages/tar-parser/src/test/utils.node.ts | 33 ++ packages/tar-parser/src/test/utils.ts | 149 ++++++ packages/tar-parser/tsconfig.json | 8 + packages/tar-parser/tsconfig.lib.json | 9 + packages/tar-parser/tsconfig.spec.json | 8 + 24 files changed, 1921 insertions(+) create mode 100644 packages/tar-parser/CHANGELOG.md create mode 100644 packages/tar-parser/LICENSE create mode 100644 packages/tar-parser/README.md create mode 100644 packages/tar-parser/bench/global.d.ts create mode 100644 packages/tar-parser/bench/messages.ts create mode 100644 packages/tar-parser/bench/package.json create mode 100644 packages/tar-parser/bench/parsers/busboy.ts create mode 100644 packages/tar-parser/bench/parsers/fastify-busboy.ts create mode 100644 packages/tar-parser/bench/parsers/multipart-parser.ts create mode 100644 packages/tar-parser/bench/parsers/multipasta.ts create mode 100644 packages/tar-parser/bench/runner.ts create mode 100644 packages/tar-parser/bench/tsconfig.json create mode 100644 packages/tar-parser/bench/utils.ts create mode 100644 packages/tar-parser/package.json create mode 100644 packages/tar-parser/src/global.d.ts create mode 100644 packages/tar-parser/src/lib/multipart.spec.ts create mode 100644 packages/tar-parser/src/lib/multipart.ts create mode 100644 packages/tar-parser/src/lib/tar.ts create mode 100644 packages/tar-parser/src/tar-parser.ts create mode 100644 packages/tar-parser/src/test/utils.node.ts create mode 100644 packages/tar-parser/src/test/utils.ts create mode 100644 packages/tar-parser/tsconfig.json create mode 100644 packages/tar-parser/tsconfig.lib.json create mode 100644 packages/tar-parser/tsconfig.spec.json diff --git a/packages/tar-parser/CHANGELOG.md b/packages/tar-parser/CHANGELOG.md new file mode 100644 index 00000000000..d4a40e60478 --- /dev/null +++ b/packages/tar-parser/CHANGELOG.md @@ -0,0 +1,3 @@ +## HEAD + +- Initial release diff --git a/packages/tar-parser/LICENSE b/packages/tar-parser/LICENSE new file mode 100644 index 00000000000..717984c0442 --- /dev/null +++ b/packages/tar-parser/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Michael Jackson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/tar-parser/README.md b/packages/tar-parser/README.md new file mode 100644 index 00000000000..1a24d18e885 --- /dev/null +++ b/packages/tar-parser/README.md @@ -0,0 +1,221 @@ +# multipart-parser + +`multipart-parser` is a fast, efficient parser for multipart streams. It can be used in any JavaScript environment (not just node.js) for a variety of use cases including: + +- Handling file uploads (`multipart/form-data` requests) +- Parsing `multipart/mixed` messages (email attachments, API responses, etc.) +- Parsing email messages with both plain text and HTML versions (`multipart/alternative`) + +## Features + +- Runs anywhere JavaScript runs (see [examples for Node.js, Bun, Deno, and Cloudflare Workers](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples)) +- Built on the standard [web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) +- Supports the entire spectrum of `multipart/*` message types +- Memory efficient and does not buffer anything in normal usage +- [As fast or faster than](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser#benchmark) other popular multipart libraries + +## Installation + +Install from [npm](https://www.npmjs.com/): + +```sh +npm install @mjackson/multipart-parser +``` + +Or install from [JSR](https://jsr.io/): + +```sh +deno add @mjackson/multipart-parser +``` + +## Usage + +The most common use case for `multipart-parser` is handling file uploads when you're building a web server. For this case, the `parseMultipartRequest` function is your friend. It will automatically validate the request is `multipart/form-data`, extract the multipart boundary from the `Content-Type` header, parse all fields and files in the `request.body` stream, and `yield` each one to you as a `MultipartPart` object so you can save it to disk or upload it somewhere. + +```typescript +import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser'; + +async function handleMultipartRequest(request: Request): void { + try { + // The parser `yield`s each MultipartPart as it becomes available + for await (let part of parseMultipartRequest(request)) { + console.log(part.name); + console.log(part.filename); + + if (/^text\//.test(part.mediaType)) { + console.log(await part.text()); + } else { + // TODO: part.body is a ReadableStream<Uint8Array>, stream it to a file + } + } + } catch (error) { + if (error instanceof MultipartParseError) { + console.error('Failed to parse multipart request:', error.message); + } else { + console.error('An unexpected error occurred:', error); + } + } +} +``` + +The main module (`import from "@mjackson/multipart-parser"`) assumes you're working with [the fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) (`Request`, `ReadableStream`, etc). Support for these interfaces was added to Node.js by the [undici](https://github.com/nodejs/undici) project in [version 16.5.0](https://nodejs.org/en/blog/release/v16.5.0). + +If however you're building a server for Node.js that relies on node-specific APIs like `http.IncomingMessage`, `stream.Readable`, and `buffer.Buffer` (ala Express or `http.createServer`), `multipart-parser` ships with an additional module that works directly with these APIs. + +```typescript +import * as http from 'node:http'; + +import { MultipartParseError } from '@mjackson/multipart-parser'; +// Note: Import from multipart-parser/node for node-specific APIs +import { parseMultipartRequest } from '@mjackson/multipart-parser/node'; + +const server = http.createServer(async (req, res) => { + try { + for await (let part of parseMultipartRequest(req)) { + console.log(part.name); + console.log(part.filename); + console.log(part.mediaType); + + // ... + } + } catch (error) { + if (error instanceof MultipartParseError) { + console.error('Failed to parse multipart request:', error.message); + } else { + console.error('An unexpected error occurred:', error); + } + } +}); + +server.listen(8080); +``` + +## Low-level API + +If you're working directly with multipart boundaries and buffers/streams of multipart data that are not necessarily part of a request, `multipart-parser` provides a lower-level API that you can use directly: + +```typescript +import { parseMultipart } from '@mjackson/multipart-parser'; + +// Get the multipart data from some API, filesystem, etc. +let multipartMessage = new Uint8Array(); +// can also be a stream or any Iterable/AsyncIterable +// let multipartMessage = new ReadableStream(...); +// let multipartMessage = [new Uint8Array(...), new Uint8Array(...)]; + +let boundary = '----WebKitFormBoundary56eac3x'; + +for await (let part of parseMultipart(multipartMessage, boundary)) { + // Do whatever you want with the part... +} +``` + +If you'd prefer a callback-based API, instantiate your own `MultipartParser` and go for it: + +```typescript +import { MultipartParseError, MultipartParser } from '@mjackson/multipart-parser'; + +let multipartMessage = new Uint8Array(); // or ReadableStream<Uint8Array>, etc. +let boundary = '...'; + +let parser = new MultipartParser(boundary); + +try { + // parse() resolves once the parse is finished and all your callbacks are done + await parser.parse(multipartMessage, async (part) => { + // Do whatever you need... + }); +} catch (error) { + if (error instanceof MultipartParseError) { + // The parse failed + } else { + // One of your handlers failed + } +} +``` + +## Examples + +The [`examples` directory](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples) contains a few working examples of how you can use this library: + +- [`examples/bun`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples/bun) - using multipart-parser in Bun +- [`examples/cf-workers`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples/cf-workers) - using multipart-parser in a Cloudflare Worker and storing file uploads in R2 +- [`examples/deno`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples/deno) - using multipart-parser in Deno +- [`examples/node`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples/node) - using multipart-parser in Node.js + +## Benchmark + +`multipart-parser` is designed to be as efficient as possible, operating mainly on streams of data and rarely buffering in common usage. This design yields exceptional performance when handling multipart payloads of any size. In most benchmarks, `multipart-parser` is as fast or faster than `busboy`. + +Important: Benchmarking can be tricky, and results vary greatly depending on platform, parameters, and other factors. So take these results with a grain of salt. The main point of this library is to be portable between JavaScript runtimes. To this end, we run the benchmarks on three major open source JavaScript runtimes: Node.js, Bun, and Deno. + +The results of running the benchmarks on my laptop: + +``` +> @mjackson/multipart-parser@0.6.1 bench:node /Users/michael/Projects/multipart-parser +> node --import tsimp/import ./bench/runner.ts + +Platform: Darwin (23.5.0) +CPU: Apple M1 Pro +Date: 8/18/2024, 4:18:39 PM +Node.js v22.1.0 +┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ +│ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ +├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ +│ multipart-parser │ '0.01 ms ± 0.03' │ '1.06 ms ± 0.04' │ '0.10 ms ± 0.03' │ '10.60 ms ± 0.22' │ +│ multipasta │ '0.01 ms ± 0.03' │ '1.06 ms ± 0.03' │ '0.15 ms ± 0.02' │ '10.70 ms ± 2.70' │ +│ busboy │ '0.03 ms ± 0.09' │ '3.01 ms ± 0.08' │ '0.22 ms ± 0.03' │ '29.91 ms ± 0.91' │ +│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.20 ms ± 0.08' │ '0.39 ms ± 0.07' │ '11.86 ms ± 0.17' │ +└──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ + +> @mjackson/multipart-parser@0.6.1 bench:bun /Users/michael/Projects/multipart-parser +> bun run ./bench/runner.ts + +Platform: Darwin (23.5.0) +CPU: Apple M1 Pro +Date: 8/18/2024, 4:20:58 PM +Bun 1.1.21 +┌──────────────────┬────────────────┬────────────────┬─────────────────┬─────────────────┐ +│ │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ +├──────────────────┼────────────────┼────────────────┼─────────────────┼─────────────────┤ +│ multipart-parser │ 0.01 ms ± 0.04 │ 0.91 ms ± 0.09 │ 0.11 ms ± 0.05 │ 8.23 ms ± 0.18 │ +│ multipasta │ 0.01 ms ± 0.03 │ 0.87 ms ± 0.08 │ 0.22 ms ± 0.15 │ 8.09 ms ± 0.15 │ +│ busboy │ 0.03 ms ± 0.07 │ 3.59 ms ± 0.13 │ 0.36 ms ± 0.17 │ 35.26 ms ± 0.39 │ +│ @fastify/busboy │ 0.04 ms ± 0.11 │ 7.23 ms ± 0.15 │ 0.63 ms ± 0.15 │ 71.86 ms ± 0.53 │ +└──────────────────┴────────────────┴────────────────┴─────────────────┴─────────────────┘ + +> @mjackson/multipart-parser@0.6.1 bench:deno /Users/michael/Projects/multipart-parser +> deno --unstable-byonm --unstable-sloppy-imports run --allow-sys ./bench/runner.ts + +Platform: Darwin (23.5.0) +CPU: Apple M1 Pro +Date: 8/18/2024, 4:24:16 PM +Deno 1.45.5 +┌──────────────────┬──────────────────┬───────────────────┬──────────────────┬────────────────────┐ +│ (idx) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ +├──────────────────┼──────────────────┼───────────────────┼──────────────────┼────────────────────┤ +│ multipart-parser │ "0.01 ms ± 0.15" │ "1.00 ms ± 1.00" │ "0.08 ms ± 0.39" │ "10.08 ms ± 0.41" │ +│ multipasta │ "0.01 ms ± 0.14" │ "1.02 ms ± 1.00" │ "0.17 ms ± 0.56" │ "14.59 ms ± 0.92" │ +│ busboy │ "0.04 ms ± 0.28" │ "3.04 ms ± 1.00" │ "0.30 ms ± 0.71" │ "29.86 ms ± 0.83" │ +│ @fastify/busboy │ "0.05 ms ± 0.31" │ "12.36 ms ± 0.78" │ "0.78 ms ± 0.98" │ "123.54 ms ± 5.04" │ +└──────────────────┴──────────────────┴───────────────────┴──────────────────┴────────────────────┘ +``` + +I encourage you to run the benchmarks yourself. You'll probably get different results! + +```sh +pnpm run bench +``` + +## Related Packages + +- [`form-data-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser) - Uses `multipart-parser` internally to parse multipart requests and generate `FileUpload`s for storage +- [`headers`](https://github.com/mjackson/remix-the-web/tree/main/packages/headers) - Used internally to parse HTTP headers and get metadata (filename, content type) for each `MultipartPart` + +## Credits + +Thanks to Jacob Ebey who gave me several code reviews on this project prior to publishing. + +## License + +See [LICENSE](https://github.com/mjackson/remix-the-web/blob/main/LICENSE) diff --git a/packages/tar-parser/bench/global.d.ts b/packages/tar-parser/bench/global.d.ts new file mode 100644 index 00000000000..dbb97336eb9 --- /dev/null +++ b/packages/tar-parser/bench/global.d.ts @@ -0,0 +1,8 @@ +declare var Deno: { version: { deno: string } } | undefined; + +// See https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62651 + +interface ReadableStream<R = any> { + values(options?: { preventCancel?: boolean }): AsyncIterableIterator<R>; + [Symbol.asyncIterator](): AsyncIterableIterator<R>; +} diff --git a/packages/tar-parser/bench/messages.ts b/packages/tar-parser/bench/messages.ts new file mode 100644 index 00000000000..ea6edbcd60a --- /dev/null +++ b/packages/tar-parser/bench/messages.ts @@ -0,0 +1,63 @@ +import { concat, getRandomBytes } from './utils.js'; + +const NodeDefaultHighWaterMark = 65536; + +export class MultipartMessage { + boundary: string; + content: Uint8Array; + + constructor(boundary: string, partSizes: number[]) { + this.boundary = boundary; + + let chunks: Uint8Array[] = []; + + function pushString(string: string): void { + chunks.push(new TextEncoder().encode(string)); + } + + function pushLine(line = ''): void { + pushString(line + '\r\n'); + } + + for (let i = 0; i < partSizes.length; i++) { + pushLine(`--${boundary}`); + pushLine(`Content-Disposition: form-data; name="file${i}"; filename="file${i}.dat"`); + pushLine('Content-Type: application/octet-stream'); + pushLine(); + chunks.push(getRandomBytes(partSizes[i])); + pushLine(); + } + + pushString(`--${boundary}--`); + + this.content = concat(chunks); + } + + *generateChunks(chunkSize = NodeDefaultHighWaterMark): Generator<Uint8Array> { + for (let i = 0; i < this.content.length; i += chunkSize) { + yield this.content.subarray(i, i + chunkSize); + } + } +} + +const oneKb = 1024; +const oneMb = 1024 * oneKb; + +export const oneSmallFile = new MultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [oneKb]); + +export const oneLargeFile = new MultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [ + 10 * oneMb, +]); + +export const oneHundredSmallFiles = new MultipartMessage( + '----WebKitFormBoundaryzv0Og5zWtGjvzP2A', + Array(100).fill(oneKb), +); + +export const fiveLargeFiles = new MultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [ + 10 * oneMb, + 10 * oneMb, + 10 * oneMb, + 20 * oneMb, + 50 * oneMb, +]); diff --git a/packages/tar-parser/bench/package.json b/packages/tar-parser/bench/package.json new file mode 100644 index 00000000000..4bb5e8ce417 --- /dev/null +++ b/packages/tar-parser/bench/package.json @@ -0,0 +1,15 @@ +{ + "name": "multipart-parser-bench", + "private": true, + "type": "module", + "dependencies": { + "@fastify/busboy": "^3.0.0", + "@mjackson/multipart-parser": "workspace:*", + "busboy": "^1.6.0", + "multipasta": "^0.2.4" + }, + "devDependencies": { + "@types/bun": "^1.1.6", + "@types/busboy": "^1.5.4" + } +} diff --git a/packages/tar-parser/bench/parsers/busboy.ts b/packages/tar-parser/bench/parsers/busboy.ts new file mode 100644 index 00000000000..ed3dfc7fced --- /dev/null +++ b/packages/tar-parser/bench/parsers/busboy.ts @@ -0,0 +1,38 @@ +import { Readable } from 'node:stream'; +import busboy from 'busboy'; + +import { MultipartMessage } from '../messages.js'; + +export function parse(message: MultipartMessage): Promise<number> { + let stream = new Readable({ + read() { + for (let chunk of message.generateChunks()) { + this.push(chunk); + } + this.push(null); + }, + }); + + return new Promise((resolve, reject) => { + let start = performance.now(); + + let bb = busboy({ + headers: { 'content-type': `multipart/form-data; boundary=${message.boundary}` }, + limits: { fileSize: Infinity }, + }); + + bb.on('field', () => {}); + + bb.on('file', (_name, stream) => { + stream.resume(); + }); + + bb.on('error', reject); + + bb.on('close', () => { + resolve(performance.now() - start); + }); + + stream.pipe(bb); + }); +} diff --git a/packages/tar-parser/bench/parsers/fastify-busboy.ts b/packages/tar-parser/bench/parsers/fastify-busboy.ts new file mode 100644 index 00000000000..7bb3cbdd962 --- /dev/null +++ b/packages/tar-parser/bench/parsers/fastify-busboy.ts @@ -0,0 +1,38 @@ +import { Readable } from 'node:stream'; +import busboy from '@fastify/busboy'; + +import { MultipartMessage } from '../messages.js'; + +export function parse(message: MultipartMessage): Promise<number> { + let stream = new Readable({ + read() { + for (let chunk of message.generateChunks()) { + this.push(chunk); + } + this.push(null); + }, + }); + + return new Promise((resolve, reject) => { + let start = performance.now(); + + let bb = new busboy.Busboy({ + headers: { 'content-type': `multipart/form-data; boundary=${message.boundary}` }, + limits: { fileSize: Infinity }, + }); + + bb.on('field', () => {}); + + bb.on('file', (_name, stream) => { + stream.resume(); + }); + + bb.on('error', reject); + + bb.on('finish', () => { + resolve(performance.now() - start); + }); + + stream.pipe(bb); + }); +} diff --git a/packages/tar-parser/bench/parsers/multipart-parser.ts b/packages/tar-parser/bench/parsers/multipart-parser.ts new file mode 100644 index 00000000000..b3c7216ff7b --- /dev/null +++ b/packages/tar-parser/bench/parsers/multipart-parser.ts @@ -0,0 +1,13 @@ +import { MultipartParser } from '@mjackson/multipart-parser'; + +import { MultipartMessage } from '../messages.js'; + +export async function parse(message: MultipartMessage): Promise<number> { + let start = performance.now(); + + await new MultipartParser(message.boundary).parse(message.generateChunks(), (_part) => { + // Do nothing + }); + + return performance.now() - start; +} diff --git a/packages/tar-parser/bench/parsers/multipasta.ts b/packages/tar-parser/bench/parsers/multipasta.ts new file mode 100644 index 00000000000..37b0b2e5237 --- /dev/null +++ b/packages/tar-parser/bench/parsers/multipasta.ts @@ -0,0 +1,24 @@ +import * as Multipasta from 'multipasta'; + +import { MultipartMessage } from '../messages.js'; + +export function parse(message: MultipartMessage): Promise<number> { + return new Promise((resolve, reject) => { + const start = performance.now(); + const parser = Multipasta.make({ + headers: { 'content-type': `multipart/form-data; boundary=${message.boundary}` }, + onDone() { + resolve(performance.now() - start); + }, + onError: reject, + onFile(_info) { + return (_chunk) => {}; + }, + onField() {}, + }); + for (const chunk of message.generateChunks()) { + parser.write(chunk); + } + parser.end(); + }); +} diff --git a/packages/tar-parser/bench/runner.ts b/packages/tar-parser/bench/runner.ts new file mode 100644 index 00000000000..14f4739784c --- /dev/null +++ b/packages/tar-parser/bench/runner.ts @@ -0,0 +1,90 @@ +import * as os from 'node:os'; +import * as process from 'node:process'; + +import * as messages from './messages.js'; +import * as busboy from './parsers/busboy.js'; +import * as fastifyBusboy from './parsers/fastify-busboy.js'; +import * as multipartParser from './parsers/multipart-parser.js'; +import * as multipasta from './parsers/multipasta.js'; + +const benchmarks = [ + { name: '1 small file', message: messages.oneSmallFile }, + { name: '1 large file', message: messages.oneLargeFile }, + { name: '100 small files', message: messages.oneHundredSmallFiles }, + { name: '5 large files', message: messages.fiveLargeFiles }, +]; + +interface Parser { + parse(message: messages.MultipartMessage): Promise<number>; +} + +async function runParserBenchmarks( + parser: Parser, + times = 1000, +): Promise<BenchmarkResults[string]> { + let results: BenchmarkResults[string] = {}; + + for (let benchmark of benchmarks) { + let measurements: number[] = []; + for (let i = 0; i < times; ++i) { + measurements.push(await parser.parse(benchmark.message)); + } + + results[benchmark.name] = getMeanAndStdDev(measurements); + } + + return results; +} + +function getMeanAndStdDev(measurements: number[]): string { + let mean = measurements.reduce((a, b) => a + b, 0) / measurements.length; + let variance = measurements.reduce((a, b) => a + (b - mean) ** 2, 0) / measurements.length; + let stdDev = Math.sqrt(variance); + return mean.toFixed(2) + ' ms ± ' + stdDev.toFixed(2); +} + +interface BenchmarkResults { + [parserName: string]: { + [benchmarkName: string]: string; + }; +} + +async function runBenchmarks(parserName?: string): Promise<BenchmarkResults> { + let results: BenchmarkResults = {}; + + if (parserName === 'multipart-parser' || parserName === undefined) { + results['multipart-parser'] = await runParserBenchmarks(multipartParser); + } + if (parserName === 'multipasta' || parserName === undefined) { + results['multipasta'] = await runParserBenchmarks(multipasta); + } + if (parserName === 'busboy' || parserName === undefined) { + results.busboy = await runParserBenchmarks(busboy); + } + if (parserName === 'fastify-busboy' || parserName === undefined) { + results['@fastify/busboy'] = await runParserBenchmarks(fastifyBusboy); + } + + return results; +} + +function printResults(results: BenchmarkResults) { + console.log(`Platform: ${os.type()} (${os.release()})`); + console.log(`CPU: ${os.cpus()[0].model}`); + console.log(`Date: ${new Date().toLocaleString()}`); + + if (typeof Bun !== 'undefined') { + console.log(`Bun ${Bun.version}`); + } else if (typeof Deno !== 'undefined') { + console.log(`Deno ${Deno.version.deno}`); + } else { + console.log(`Node.js ${process.version}`); + } + + console.table(results); +} + +runBenchmarks(process.argv[2]).then(printResults, (error) => { + console.error(error); + process.exit(1); +}); diff --git a/packages/tar-parser/bench/tsconfig.json b/packages/tar-parser/bench/tsconfig.json new file mode 100644 index 00000000000..d8aaef54f9d --- /dev/null +++ b/packages/tar-parser/bench/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "lib": ["DOM", "ES2020"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true + } +} diff --git a/packages/tar-parser/bench/utils.ts b/packages/tar-parser/bench/utils.ts new file mode 100644 index 00000000000..7e433503a98 --- /dev/null +++ b/packages/tar-parser/bench/utils.ts @@ -0,0 +1,28 @@ +export function concat(chunks: Uint8Array[]): Uint8Array { + if (chunks.length === 1) return chunks[0]; + + let length = 0; + for (let chunk of chunks) { + length += chunk.length; + } + + let result = new Uint8Array(length); + let offset = 0; + + for (let chunk of chunks) { + result.set(chunk, offset); + offset += chunk.length; + } + + return result; +} + +export function getRandomBytes(size: number): Uint8Array { + let chunks: Uint8Array[] = []; + + for (let i = 0; i < size; i += 65536) { + chunks.push(crypto.getRandomValues(new Uint8Array(Math.min(size - i, 65536)))); + } + + return concat(chunks); +} diff --git a/packages/tar-parser/package.json b/packages/tar-parser/package.json new file mode 100644 index 00000000000..a775066dc25 --- /dev/null +++ b/packages/tar-parser/package.json @@ -0,0 +1,41 @@ +{ + "name": "@mjackson/tar-parser", + "version": "0.0.0", + "description": "A fast, efficient parser for tar streams in any JavaScript environment", + "author": "Michael Jackson <mjijackson@gmail.com>", + "repository": { + "type": "git", + "url": "git+https://github.com/mjackson/remix-the-web.git", + "directory": "packages/tar-parser" + }, + "homepage": "https://github.com/mjackson/remix-the-web/tree/main/packages/tar-parser#readme", + "license": "MIT", + "files": [ + "dist", + "LICENSE", + "README.md" + ], + "type": "module", + "exports": { + ".": "./dist/tar-parser.js", + "./package.json": "./package.json" + }, + "dependencies": { + "@mjackson/lazy-file": "workspace:^" + }, + "devDependencies": { + "@types/node": "^20.14.10" + }, + "scripts": { + "build": "tsc --outDir dist --project tsconfig.lib.json", + "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", + "prepare": "pnpm run build", + "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" + }, + "keywords": [ + "tar", + "archive", + "parser", + "stream" + ] +} diff --git a/packages/tar-parser/src/global.d.ts b/packages/tar-parser/src/global.d.ts new file mode 100644 index 00000000000..b8041179bc5 --- /dev/null +++ b/packages/tar-parser/src/global.d.ts @@ -0,0 +1,6 @@ +// See https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62651 + +interface ReadableStream<R = any> { + values(options?: { preventCancel?: boolean }): AsyncIterableIterator<R>; + [Symbol.asyncIterator](): AsyncIterableIterator<R>; +} diff --git a/packages/tar-parser/src/lib/multipart.spec.ts b/packages/tar-parser/src/lib/multipart.spec.ts new file mode 100644 index 00000000000..b0aa85d5799 --- /dev/null +++ b/packages/tar-parser/src/lib/multipart.spec.ts @@ -0,0 +1,293 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { + isMultipartRequest, + parseMultipartRequest, + MultipartParseError, + getMultipartBoundary, +} from './multipart.js'; +import { createMockRequest, createMultipartMockRequest, getRandomBytes } from '../test/utils.js'; + +const CRLF = '\r\n'; + +describe('getMultipartBoundary', async () => { + it('returns the boundary from the Content-Type header', async () => { + assert.equal(getMultipartBoundary('multipart/form-data; boundary=boundary123'), 'boundary123'); + }); + + it('returns null when boundary is missing', async () => { + assert.equal(getMultipartBoundary('multipart/form-data'), null); + }); + + it('returns null when Content-Type header is not multipart', async () => { + assert.equal(getMultipartBoundary('text/plain'), null); + }); +}); + +describe('isMultipartRequest', async () => { + it('returns true for multipart/form-data requests', async () => { + let request = createMockRequest({ + headers: { 'Content-Type': 'multipart/form-data' }, + }); + + assert.ok(isMultipartRequest(request)); + }); + + it('returns true for multipart/mixed requests', async () => { + let request = createMockRequest({ + headers: { 'Content-Type': 'multipart/mixed' }, + }); + + assert.ok(isMultipartRequest(request)); + }); + + it('returns false for other content types', async () => { + let request = createMockRequest({ + headers: { 'Content-Type': 'text/plain' }, + }); + + assert.ok(!isMultipartRequest(request)); + }); +}); + +describe('parseMultipartRequest', async () => { + let boundary = 'boundary123'; + + it('parses an empty multipart message', async () => { + let request = createMultipartMockRequest(boundary); + + let parts = []; + for await (let part of parseMultipartRequest(request)) { + parts.push(part); + } + + assert.equal(parts.length, 0); + }); + + it('parses a simple multipart form', async () => { + let request = createMultipartMockRequest(boundary, { + field1: 'value1', + }); + + let parts = []; + for await (let part of parseMultipartRequest(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'field1'); + assert.equal(await parts[0].text(), 'value1'); + }); + + it('parses multiple parts correctly', async () => { + let request = createMultipartMockRequest(boundary, { + field1: 'value1', + field2: 'value2', + }); + + let parts = []; + for await (let part of parseMultipartRequest(request)) { + parts.push(part); + } + + assert.equal(parts.length, 2); + assert.equal(parts[0].name, 'field1'); + assert.equal(await parts[0].text(), 'value1'); + assert.equal(parts[1].name, 'field2'); + assert.equal(await parts[1].text(), 'value2'); + }); + + it('parses empty parts correctly', async () => { + let request = createMultipartMockRequest(boundary, { + empty: '', + }); + + let parts = []; + for await (let part of parseMultipartRequest(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'empty'); + assert.equal((await parts[0].bytes()).byteLength, 0); + }); + + it('parses file uploads correctly', async () => { + let request = createMultipartMockRequest(boundary, { + file1: { + filename: 'test.txt', + mediaType: 'text/plain', + content: 'File content', + }, + }); + + let parts = []; + for await (let part of parseMultipartRequest(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'file1'); + assert.equal(parts[0].filename, 'test.txt'); + assert.equal(parts[0].mediaType, 'text/plain'); + assert.equal(await parts[0].text(), 'File content'); + }); + + it('parses multiple fields and a file upload', async () => { + let request = createMultipartMockRequest(boundary, { + field1: 'value1', + field2: 'value2', + file1: { + filename: 'test.txt', + mediaType: 'text/plain', + content: 'File content', + }, + }); + + let parts = []; + for await (let part of parseMultipartRequest(request)) { + parts.push(part); + } + + assert.equal(parts.length, 3); + assert.equal(parts[0].name, 'field1'); + assert.equal(await parts[0].text(), 'value1'); + assert.equal(parts[1].name, 'field2'); + assert.equal(await parts[1].text(), 'value2'); + assert.equal(parts[2].name, 'file1'); + assert.equal(parts[2].filename, 'test.txt'); + assert.equal(parts[2].mediaType, 'text/plain'); + assert.equal(await parts[2].text(), 'File content'); + }); + + it('parses large file uploads correctly', async () => { + let content = getRandomBytes(10 * 1024 * 1024); // 10 MB file + let request = createMultipartMockRequest(boundary, { + file1: { + filename: 'random.dat', + mediaType: 'application/octet-stream', + content, + }, + }); + + let parts = []; + for await (let part of parseMultipartRequest(request)) { + parts.push({ + name: part.name, + filename: part.filename, + mediaType: part.mediaType, + content: await part.bytes(), + }); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'file1'); + assert.equal(parts[0].filename, 'random.dat'); + assert.equal(parts[0].mediaType, 'application/octet-stream'); + assert.deepEqual(parts[0].content, content); + }); + + it('throws when Content-Type is not multipart/form-data', async () => { + let request = createMockRequest({ + headers: { 'Content-Type': 'text/plain' }, + }); + + await assert.rejects(async () => { + await parseMultipartRequest(request).next(); + }, MultipartParseError); + }); + + it('throws when boundary is missing', async () => { + let request = createMockRequest({ + headers: { 'Content-Type': 'multipart/form-data' }, + }); + + await assert.rejects(async () => { + await parseMultipartRequest(request).next(); + }, MultipartParseError); + }); + + it('throws when header exceeds maximum size', async () => { + let request = createMockRequest({ + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + body: [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + 'X-Large-Header: ' + 'X'.repeat(6 * 1024), // 6 KB header + '', + 'value1', + `--${boundary}--`, + ].join(CRLF), + }); + + await assert.rejects(async () => { + for await (let part of parseMultipartRequest(request, { maxHeaderSize: 4 * 1024 })) { + for await (let _ of part.body) { + // Consume all parts + } + } + }, MultipartParseError); + }); + + it('throws when file exceeds maximum size', async () => { + let request = createMultipartMockRequest(boundary, { + file1: { + filename: 'random.dat', + mediaType: 'application/octet-stream', + content: getRandomBytes(11 * 1024 * 1024), // 11 MB file + }, + }); + + await assert.rejects(async () => { + for await (let part of parseMultipartRequest(request, { maxFileSize: 10 * 1024 * 1024 })) { + for await (let _ of part.body) { + // Consume all parts + } + } + }, MultipartParseError); + }); + + it('parses malformed parts', async () => { + let request = createMockRequest({ + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + body: [`--${boundary}`, 'Invalid-Header', '', 'Some content', `--${boundary}--`].join(CRLF), + }); + + let parts = []; + for await (let part of parseMultipartRequest(request)) { + parts.push(part); + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].headers.get('Invalid-Header'), null); + assert.equal(await parts[0].text(), 'Some content'); + }); + + it('throws error when final boundary is missing', async () => { + let request = createMockRequest({ + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + body: [ + `--${boundary}`, + 'Content-Disposition: form-data; name="field1"', + '', + 'value1', + `--${boundary}`, + ].join(CRLF), + }); + + await assert.rejects(async () => { + for await (let part of parseMultipartRequest(request)) { + for await (let _ of part.body) { + // Consume all parts + } + } + }, MultipartParseError); + }); +}); diff --git a/packages/tar-parser/src/lib/multipart.ts b/packages/tar-parser/src/lib/multipart.ts new file mode 100644 index 00000000000..a5ad3c91f18 --- /dev/null +++ b/packages/tar-parser/src/lib/multipart.ts @@ -0,0 +1,478 @@ +import Headers from '@mjackson/headers'; + +import { + SearchFunction, + createSearch, + PartialTailSearchFunction, + createPartialTailSearch, +} from './search.js'; + +/** + * Extracts the boundary string from a `multipart/*` content type. + */ +export function getMultipartBoundary(contentType: string): string | null { + let match = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(contentType); + return match ? (match[1] ?? match[2]) : null; +} + +/** + * Returns true if the given request contains multipart data. + */ +export function isMultipartRequest(request: Request): boolean { + let contentType = request.headers.get('Content-Type'); + return contentType != null && contentType.startsWith('multipart/'); +} + +/** + * Parse a multipart [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and yield each part as + * a `MultipartPart` object. Useful in HTTP server contexts for handling incoming `multipart/*` requests. + */ +export async function* parseMultipartRequest( + request: Request, + options?: MultipartParserOptions, +): AsyncGenerator<MultipartPart> { + if (!isMultipartRequest(request)) { + throw new MultipartParseError('Request is not a multipart request'); + } + if (!request.body) { + throw new MultipartParseError('Request body is empty'); + } + + let boundary = getMultipartBoundary(request.headers.get('Content-Type')!); + if (!boundary) { + throw new MultipartParseError('Invalid Content-Type header: missing boundary'); + } + + yield* parseMultipart(request.body, boundary, options); +} + +/** + * Parse a `multipart/*` buffer or stream and yield each part it finds as a `MultipartPart` object. + * + * Note: This is a low-level API that requires manual handling of the stream and boundary. If you're + * building a web server, consider using `parseMultipartRequest(request)` instead. + */ +export async function* parseMultipart( + message: + | ReadableStream<Uint8Array> + | Uint8Array + | Iterable<Uint8Array> + | AsyncIterable<Uint8Array>, + boundary: string, + options?: MultipartParserOptions, +): AsyncGenerator<MultipartPart> { + let parser = new MultipartParser(boundary, options); + + let parts: MultipartPart[] = []; + let resolveNext: (() => void) | null = null; + let parseError: Error | null = null; + let done = false; + + parser + .parse(message, (part) => { + parts.push(part); + + if (resolveNext) { + resolveNext(); + resolveNext = null; + } + }) + .catch((error) => { + parseError = error; + }) + .finally(() => { + done = true; + if (resolveNext) resolveNext(); + }); + + while (!done) { + if (parts.length === 0) { + await new Promise<void>((resolve) => { + resolveNext = resolve; + }); + } + + while (parts.length > 0) { + yield parts.shift()!; + } + } + + if (parseError) { + throw parseError; + } +} + +const findDoubleNewline = createSearch('\r\n\r\n'); + +export class MultipartParseError extends Error { + constructor(message: string) { + super(message); + this.name = 'MultipartParseError'; + } +} + +export interface MultipartParserOptions { + maxHeaderSize?: number; + maxFileSize?: number; +} + +const enum MultipartParserState { + Start, + AfterBoundary, + Header, + Body, + Done, +} + +/** + * A parser for `multipart/*` HTTP messages. + */ +export class MultipartParser { + boundary: string; + maxHeaderSize: number; + maxFileSize: number; + + #findOpeningBoundary: SearchFunction; + #openingBoundaryLength: number; + + #findBoundary: SearchFunction; + #findPartialTailBoundary: PartialTailSearchFunction; + #boundaryLength: number; + + #state = MultipartParserState.Start; + #buffer: Uint8Array | null = null; + #bodyController: ReadableStreamDefaultController<Uint8Array> | null = null; + #bodyLength = 0; + + constructor(boundary: string, options?: MultipartParserOptions) { + this.boundary = boundary; + this.maxHeaderSize = options?.maxHeaderSize ?? 8 * 1024; + this.maxFileSize = options?.maxFileSize ?? Infinity; + + this.#findOpeningBoundary = createSearch(`--${boundary}`); + this.#openingBoundaryLength = 2 + boundary.length; // length of '--' + boundary + + this.#findBoundary = createSearch(`\r\n--${boundary}`); + this.#findPartialTailBoundary = createPartialTailSearch(`\r\n--${boundary}`); + this.#boundaryLength = 4 + boundary.length; // length of '\r\n--' + boundary + } + + /** + * Parse a stream/buffer multipart message and call the given handler for each part it contains. + * Resolves when the parse is finished and all handlers resolve. + */ + async parse( + message: + | ReadableStream<Uint8Array> + | Uint8Array + | Iterable<Uint8Array> + | AsyncIterable<Uint8Array>, + handler: (part: MultipartPart) => void, + ): Promise<void> { + if (this.#state !== MultipartParserState.Start) { + this.#reset(); + } + + let results: unknown[] = []; + + function handlePart(part: MultipartPart): void { + results.push(handler(part)); + } + + if (message instanceof ReadableStream || isAsyncIterable(message)) { + for await (let chunk of message) { + this.#write(chunk, handlePart); + } + } else if (message instanceof Uint8Array) { + this.#write(message, handlePart); + } else if (isIterable(message)) { + for (let chunk of message) { + this.#write(chunk, handlePart); + } + } else { + throw new TypeError('Cannot parse multipart message; expected a stream or buffer'); + } + + if (this.#state !== MultipartParserState.Done) { + throw new MultipartParseError('Unexpected end of stream'); + } + + await Promise.all(results); + } + + #reset(): void { + this.#state = MultipartParserState.Start; + this.#buffer = null; + this.#bodyController = null; + this.#bodyLength = 0; + } + + #write(chunk: Uint8Array, handler: (part: MultipartPart) => void): void { + if (this.#state === MultipartParserState.Done) { + throw new MultipartParseError('Unexpected data after end of stream'); + } + + let index = 0; + let chunkLength = chunk.length; + + if (this.#buffer !== null) { + let newChunk = new Uint8Array(this.#buffer.length + chunkLength); + newChunk.set(this.#buffer, 0); + newChunk.set(chunk, this.#buffer.length); + chunk = newChunk; + chunkLength = chunk.length; + this.#buffer = null; + } + + while (true) { + if (this.#state === MultipartParserState.Body) { + if (chunkLength - index < this.#boundaryLength) { + this.#buffer = chunk.subarray(index); + break; + } + + let boundaryIndex = this.#findBoundary(chunk, index); + + if (boundaryIndex === -1) { + // No boundary found, but there may be a partial match at the end of the chunk. + let partialTailIndex = this.#findPartialTailBoundary(chunk); + + if (partialTailIndex === -1) { + this.#writeBody(index === 0 ? chunk : chunk.subarray(index)); + } else { + this.#writeBody(chunk.subarray(index, partialTailIndex)); + this.#buffer = chunk.subarray(partialTailIndex); + } + + break; + } + + this.#writeBody(chunk.subarray(index, boundaryIndex)); + this.#closeBody(); + + index = boundaryIndex + this.#boundaryLength; + + this.#state = MultipartParserState.AfterBoundary; + } + + if (this.#state === MultipartParserState.AfterBoundary) { + if (chunkLength - index < 2) { + this.#buffer = chunk.subarray(index); + break; + } + + if (chunk[index] === 45 && chunk[index + 1] === 45) { + this.#state = MultipartParserState.Done; + break; + } + + index += 2; // Skip \r\n after boundary + + this.#state = MultipartParserState.Header; + } + + if (this.#state === MultipartParserState.Header) { + if (chunkLength - index < 4) { + this.#buffer = chunk.subarray(index); + break; + } + + let headerEndIndex = findDoubleNewline(chunk, index); + + if (headerEndIndex === -1) { + if (chunkLength - index > this.maxHeaderSize) { + throw new MultipartParseError( + `Header size exceeds maximum allowed size of ${this.maxHeaderSize} bytes`, + ); + } + + this.#buffer = chunk.subarray(index); + break; + } + + if (headerEndIndex - index > this.maxHeaderSize) { + throw new MultipartParseError( + `Header size exceeds maximum allowed size of ${this.maxHeaderSize} bytes`, + ); + } + + let header = chunk.subarray(index, headerEndIndex); + let part = new MultipartPart( + header, + new ReadableStream({ + start: (controller) => { + this.#bodyController = controller; + }, + }), + ); + + handler(part); + + index = headerEndIndex + 4; // Skip header + \r\n\r\n + + this.#state = MultipartParserState.Body; + + continue; + } + + if (this.#state === MultipartParserState.Start) { + if (chunkLength < this.#openingBoundaryLength) { + this.#buffer = chunk; + break; + } + + if (this.#findOpeningBoundary(chunk) !== 0) { + throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); + } + + index = this.#openingBoundaryLength; + + this.#state = MultipartParserState.AfterBoundary; + } + } + } + + #writeBody(chunk: Uint8Array): void { + if (this.#bodyLength + chunk.length > this.maxFileSize) { + let error = new MultipartParseError( + `File size exceeds maximum allowed size of ${this.maxFileSize} bytes`, + ); + + this.#bodyController!.error(error); + + throw error; + } + + this.#bodyController!.enqueue(chunk); + this.#bodyLength += chunk.length; + } + + #closeBody(): void { + this.#bodyController!.close(); + this.#bodyController = null; + this.#bodyLength = 0; + } +} + +function isIterable<T>(value: unknown): value is Iterable<T> { + return typeof value === 'object' && value != null && Symbol.iterator in value; +} + +function isAsyncIterable<T>(value: unknown): value is AsyncIterable<T> { + return typeof value === 'object' && value != null && Symbol.asyncIterator in value; +} + +/** + * A part of a `multipart/*` HTTP message. + */ +export class MultipartPart { + #header: Uint8Array; + #body: ReadableStream<Uint8Array>; + + #headers?: Headers; + #bodyUsed = false; + + constructor(header: Uint8Array, body: ReadableStream<Uint8Array>) { + this.#header = header; + this.#body = body; + } + + /** + * The content of this part as an `ArrayBuffer`. + */ + async arrayBuffer(): Promise<ArrayBuffer> { + return (await this.bytes()).buffer as ArrayBuffer; + } + + /** + * The body of this part as a `ReadableStream<Uint8Array>`. In `multipart/form-data` messages, this is useful + * for streaming the value of files that were uploaded using `<input type="file">` fields. + */ + get body(): ReadableStream<Uint8Array> { + return this.#body; + } + + /** + * Whether the body of this part has been consumed. + */ + get bodyUsed(): boolean { + return this.#bodyUsed; + } + + /** + * The body of this part buffered into a single `Uint8Array`. In `multipart/form-data` messages, this is useful + * for reading the value of files that were uploaded using `<input type="file">` fields. + */ + async bytes(): Promise<Uint8Array> { + if (this.#bodyUsed) { + throw new Error('Body is already consumed or is being consumed'); + } + + this.#bodyUsed = true; + + let chunks: Uint8Array[] = []; + let totalLength = 0; + for await (let chunk of this.#body) { + chunks.push(chunk); + totalLength += chunk.length; + } + + let result = new Uint8Array(totalLength); + let offset = 0; + for (let chunk of chunks) { + result.set(chunk, offset); + offset += chunk.length; + } + + return result; + } + + /** + * The headers associated with this part. + */ + get headers(): Headers { + if (!this.#headers) { + this.#headers = new Headers(new TextDecoder().decode(this.#header)); + } + + return this.#headers; + } + + /** + * True if this part originated from a file upload. + */ + get isFile(): boolean { + return this.filename !== undefined || this.mediaType === 'application/octet-stream'; + } + + /** + * The filename of the part, if it is a file upload. + */ + get filename(): string | undefined { + return this.headers.contentDisposition.preferredFilename; + } + + /** + * The media type of the part. + */ + get mediaType(): string | undefined { + return this.headers.contentType.mediaType; + } + + /** + * The name of the part, usually the `name` of the field in the `<form>` that submitted the request. + */ + get name(): string | undefined { + return this.headers.contentDisposition.name; + } + + /** + * The body of the part as a string. In `multipart/form-data` messages, this is useful for reading the value + * of parts that originated from `<input type="text">` fields. + * + * Note: Do not use this for binary data, use `await part.bytes()` or stream `part.body` directly instead. + */ + async text(): Promise<string> { + return new TextDecoder().decode(await this.bytes()); + } +} diff --git a/packages/tar-parser/src/lib/tar.ts b/packages/tar-parser/src/lib/tar.ts new file mode 100644 index 00000000000..fffbd02409d --- /dev/null +++ b/packages/tar-parser/src/lib/tar.ts @@ -0,0 +1,320 @@ +const TarBlockSize = 512; + +export class TarParseError extends Error { + constructor(message: string) { + super(message); + this.name = 'TarParseError'; + } +} + +export interface TarHeader { + name: string; + mode: number; + uid: number; + gid: number; + size: number; + mtime: number; + checksum: number; + type: string; + linkname: string; + uname: string; + gname: string; + devmajor: number; + devminor: number; + prefix: string; +} + +const TarFileTypes: Record<string, string> = { + '0': 'file', + '1': 'link', + '2': 'symlink', + '3': 'character', + '4': 'block', + '5': 'directory', + '6': 'fifo', + '7': 'contiguous', +}; + +export function parseTarHeader(buffer: Uint8Array): TarHeader { + if (buffer.length !== TarBlockSize) { + throw new TarParseError('Invalid tar header size'); + } + + let decoder = new TextDecoder('ascii'); + + function getString(offset: number, size: number) { + return decoder.decode(buffer.subarray(offset, offset + size)).replace(/\0.*$/, ''); + } + + function getOctal(offset: number, size: number) { + return parseInt(getString(offset, size), 8); + } + + // UStar header format + // Offset Size Field + // 0 100 Filename + // 100 8 File mode (octal) + // 108 8 Owner's numeric user ID (octal) + // 116 8 Group's numeric user ID (octal) + // 124 12 File size in bytes (octal) + // 136 12 Last modification time (octal) + // 148 8 Checksum for header block (octal) + // 156 1 Link indicator (file type) + // 157 100 Name of linked file + // 257 6 UStar indicator "ustar\0" + // 263 2 UStar version "00" + // 265 32 Owner username + // 297 32 Owner groupname + // 329 8 Device major number (octal) + // 337 8 Device minor number (octal) + // 345 155 Filename prefix + + let checksum = getOctal(148, 8); + if (checksum !== computeHeaderChecksum(buffer)) { + throw new TarParseError('Invalid tar header checksum'); + } + + let ustarIndicator = getString(257, 6); + if (ustarIndicator !== 'ustar') { + throw new TarParseError('Invalid tar header, must be ustar'); + } + + let linkIndicator = String.fromCharCode(buffer[156]); + + return { + name: getString(0, 100), + mode: getOctal(100, 8), + uid: getOctal(108, 8), + gid: getOctal(116, 8), + size: getOctal(124, 12), + mtime: getOctal(136, 12), + checksum, + type: TarFileTypes[linkIndicator] || 'unknown', + linkname: getString(157, 100), + uname: getString(265, 32), + gname: getString(297, 32), + devmajor: getOctal(329, 8), + devminor: getOctal(337, 8), + prefix: getString(345, 155), + }; +} + +function computeHeaderChecksum(buffer: Uint8Array): number { + let sum = 0; + for (let i = 0; i < 512; i++) { + sum += i >= 148 && i < 156 ? 32 : buffer[i]; + } + + return sum; +} + +const enum TarParserState { + Start, + Header, + Body, + Done, +} + +/** + * A parser for tar archives. + */ +export class TarParser { + #state = TarParserState.Start; + #buffer: Uint8Array | null = null; + #bodyController: ReadableStreamDefaultController<Uint8Array> | null = null; + #bodyWritten = 0; + #bodySize = 0; // The declared size of the current body + + /** + * Parse a stream/buffer multipart message and call the given handler for each part it contains. + * Resolves when the parse is finished and all handlers resolve. + */ + async parse( + message: + | ReadableStream<Uint8Array> + | Uint8Array + | Iterable<Uint8Array> + | AsyncIterable<Uint8Array>, + handler: (entry: TarEntry) => void, + ): Promise<void> { + if (this.#state !== TarParserState.Start) { + this.#reset(); + } + + let results: unknown[] = []; + + function handleEntry(entry: TarEntry): void { + results.push(handler(entry)); + } + + if (message instanceof ReadableStream || isAsyncIterable(message)) { + for await (let chunk of message) { + this.#write(chunk, handleEntry); + } + } else if (message instanceof Uint8Array) { + this.#write(message, handleEntry); + } else if (isIterable(message)) { + for (let chunk of message) { + this.#write(chunk, handleEntry); + } + } else { + throw new TypeError('Cannot parse tar archive; expected a stream or buffer'); + } + + if (this.#state !== TarParserState.Done) { + throw new TarParseError('Unexpected end of archive'); + } + + await Promise.all(results); + } + + #reset(): void { + this.#state = TarParserState.Start; + this.#buffer = null; + this.#bodyController = null; + this.#bodySize = 0; + } + + #write(chunk: Uint8Array, handler: (entry: TarEntry) => void): void { + if (this.#state === TarParserState.Done) { + throw new TarParseError('Unexpected data after end of archive'); + } + + let index = 0; + let chunkLength = chunk.length; + + if (this.#buffer !== null) { + let newChunk = new Uint8Array(this.#buffer.length + chunkLength); + newChunk.set(this.#buffer, 0); + newChunk.set(chunk, this.#buffer.length); + chunk = newChunk; + chunkLength = chunk.length; + this.#buffer = null; + } + + while (true) { + if (this.#state === TarParserState.Body) { + } + + if (this.#state === TarParserState.Header) { + } + + if (this.#state === TarParserState.Start) { + } + } + } + + #writeBody(chunk: Uint8Array): void { + if (this.#bodyWritten + chunk.length > this.#bodySize) { + throw new TarParseError('Body size exceeds declared size'); + } + + this.#bodyController!.enqueue(chunk); + this.#bodyWritten += chunk.length + } + + #closeBody(): void { + this.#bodyController!.close(); + this.#bodyController = null; + this.#bodyWritten = 0 + this.#bodySize = 0 + } +} + +function isIterable<T>(value: unknown): value is Iterable<T> { + return typeof value === 'object' && value != null && Symbol.iterator in value; +} + +function isAsyncIterable<T>(value: unknown): value is AsyncIterable<T> { + return typeof value === 'object' && value != null && Symbol.asyncIterator in value; +} + +function isZeroBlock(buffer: Uint8Array): boolean { + return buffer.every((byte) => byte === 0); +} + +/** + * An entry in a tar archive. + */ +export class TarEntry { + #header: TarHeader; + #body: ReadableStream<Uint8Array>; + #bodyUsed = false; + + constructor(header: TarHeader, body: ReadableStream<Uint8Array>) { + this.#header = header; + this.#body = body; + } + + /** + * The content of this entry as an `ArrayBuffer`. + */ + async arrayBuffer(): Promise<ArrayBuffer> { + return (await this.bytes()).buffer as ArrayBuffer; + } + + /** + * The content of this entry as a `ReadableStream<Uint8Array>`. + */ + get body(): ReadableStream<Uint8Array> { + return this.#body; + } + + /** + * Whether the body of this entry has been consumed. + */ + get bodyUsed(): boolean { + return this.#bodyUsed; + } + + /** + * The content of this entry buffered into a single `Uint8Array`. + */ + async bytes(): Promise<Uint8Array> { + if (this.#bodyUsed) { + throw new Error('Body is already consumed or is being consumed'); + } + + this.#bodyUsed = true; + + let result = new Uint8Array(this.size); + let offset = 0; + for (let chunk of this.#body) { + result.set(chunk, offset); + offset += chunk.length; + } + + return result; + } + + /** + * The raw header info associated with this entry. + */ + get header(): TarHeader { + return this.#header; + } + + /** + * The name of this entry. + */ + get name(): string { + // TODO: handle prefix + return this.header.name; + } + + /** + * The size of this entry in bytes. + */ + get size(): number { + return this.header.size; + } + + /** + * The content of this entry as a string. + * + * Note: Do not use this for binary data, use `await entry.bytes()` or stream `entry.body` directly instead. + */ + async text(): Promise<string> { + return new TextDecoder().decode(await this.bytes()); + } +} diff --git a/packages/tar-parser/src/tar-parser.ts b/packages/tar-parser/src/tar-parser.ts new file mode 100644 index 00000000000..ba4f34d7dec --- /dev/null +++ b/packages/tar-parser/src/tar-parser.ts @@ -0,0 +1,6 @@ +export { + TarParseError, + type TarHeader, + parseTarHeader, + TarEntry +} from './lib/tar.js'; diff --git a/packages/tar-parser/src/test/utils.node.ts b/packages/tar-parser/src/test/utils.node.ts new file mode 100644 index 00000000000..ddf8321e4d4 --- /dev/null +++ b/packages/tar-parser/src/test/utils.node.ts @@ -0,0 +1,33 @@ +import * as http from 'node:http'; +import * as stream from 'node:stream'; + +import { PartValue, createMultipartBody } from './utils.js'; + +export function createReadable(content: Uint8Array, chunkSize = 16 * 1024): stream.Readable { + let i = 0; + + return new stream.Readable({ + read() { + if (i < content.length) { + this.push(content.subarray(i, i + chunkSize)); + i += chunkSize; + } else { + this.push(null); + } + }, + }); +} + +export function createMultipartMockRequest( + boundary: string, + parts?: { [name: string]: PartValue }, +): http.IncomingMessage { + let body = createMultipartBody(boundary, parts); + + let request = createReadable(body) as http.IncomingMessage; + request.headers = { + 'content-type': `multipart/form-data; boundary=${boundary}`, + }; + + return request; +} diff --git a/packages/tar-parser/src/test/utils.ts b/packages/tar-parser/src/test/utils.ts new file mode 100644 index 00000000000..ffcfd39ad89 --- /dev/null +++ b/packages/tar-parser/src/test/utils.ts @@ -0,0 +1,149 @@ +import Headers from '@mjackson/headers'; + +export function concat(chunks: Uint8Array[]): Uint8Array { + if (chunks.length === 1) return chunks[0]; + + let length = 0; + for (let chunk of chunks) { + length += chunk.length; + } + + let result = new Uint8Array(length); + let offset = 0; + + for (let chunk of chunks) { + result.set(chunk, offset); + offset += chunk.length; + } + + return result; +} + +export function getRandomBytes(size: number): Uint8Array { + let chunks: Uint8Array[] = []; + + for (let i = 0; i < size; i += 65536) { + chunks.push(crypto.getRandomValues(new Uint8Array(Math.min(size - i, 65536)))); + } + + return concat(chunks); +} + +export function createReadableStream( + content: string | Uint8Array, + chunkSize = 64 * 1024, +): ReadableStream<Uint8Array> { + let encoder = new TextEncoder(); + + return new ReadableStream({ + start(controller) { + for (let i = 0; i < content.length; i += chunkSize) { + controller.enqueue( + typeof content === 'string' + ? encoder.encode(content.slice(i, i + chunkSize)) + : content.subarray(i, i + chunkSize), + ); + } + controller.close(); + }, + }); +} + +export function createMockRequest({ + headers, + body = '', +}: { + headers?: Headers | HeadersInit; + body?: string | Uint8Array | ReadableStream<Uint8Array>; +}): Request { + return { + headers: headers instanceof Headers ? headers : new Headers(headers), + body: + typeof body === 'string' || body instanceof Uint8Array ? createReadableStream(body) : body, + } as unknown as Request; +} + +export type PartValue = + | string + | { + filename?: string; + filenameSplat?: string; + mediaType?: string; + content: string | Uint8Array; + }; + +export function createMultipartBody( + boundary: string, + parts?: { [name: string]: PartValue }, +): Uint8Array { + let chunks: Uint8Array[] = []; + + function pushString(string: string) { + chunks.push(new TextEncoder().encode(string)); + } + + function pushLine(line = '') { + pushString(line + '\r\n'); + } + + if (parts) { + for (let [name, part] of Object.entries(parts)) { + pushLine(`--${boundary}`); + + if (typeof part === 'string') { + let headers = new Headers({ + contentDisposition: { + type: 'form-data', + name, + }, + }); + + pushLine(`${headers}`); + pushLine(); + pushLine(part); + } else { + let headers = new Headers({ + contentDisposition: { + type: 'form-data', + name, + filename: part.filename, + filenameSplat: part.filenameSplat, + }, + }); + + if (part.mediaType) { + headers.contentType = part.mediaType; + } + + pushLine(`${headers}`); + pushLine(); + if (typeof part.content === 'string') { + pushLine(part.content); + } else { + chunks.push(part.content); + pushLine(); + } + } + } + } + + pushString(`--${boundary}--`); + + return concat(chunks); +} + +export function createMultipartMockRequest( + boundary: string, + parts?: { [name: string]: PartValue }, +): Request { + let headers = new Headers({ + contentType: { + mediaType: 'multipart/form-data', + boundary, + }, + }); + + let body = createMultipartBody(boundary, parts); + + return createMockRequest({ headers, body }); +} diff --git a/packages/tar-parser/tsconfig.json b/packages/tar-parser/tsconfig.json new file mode 100644 index 00000000000..d8aaef54f9d --- /dev/null +++ b/packages/tar-parser/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "lib": ["DOM", "ES2020"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true + } +} diff --git a/packages/tar-parser/tsconfig.lib.json b/packages/tar-parser/tsconfig.lib.json new file mode 100644 index 00000000000..c9819aa7ed5 --- /dev/null +++ b/packages/tar-parser/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.spec.ts", "src/test/**/*.ts"], + "compilerOptions": { + "composite": true, + "rootDir": "src" + } +} diff --git a/packages/tar-parser/tsconfig.spec.json b/packages/tar-parser/tsconfig.spec.json new file mode 100644 index 00000000000..0dcc65f3ce6 --- /dev/null +++ b/packages/tar-parser/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.spec.ts", "src/test/**/*.ts"], + "compilerOptions": { + "composite": true, + "types": ["node"] + } +} From d88602998d6bc9157c0bc8a57b5b6d84a269d947 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 17 Oct 2024 11:49:16 -0700 Subject: [PATCH 520/730] More work on tar parser --- packages/tar-parser/src/lib/multipart.spec.ts | 293 ----------- packages/tar-parser/src/lib/multipart.ts | 478 ------------------ packages/tar-parser/src/lib/tar.spec.ts | 12 + packages/tar-parser/src/lib/tar.ts | 220 ++++---- packages/tar-parser/src/tar-parser.ts | 7 +- .../tar-parser/{src => }/test/utils.node.ts | 0 packages/tar-parser/{src => }/test/utils.ts | 0 packages/tar-parser/tsconfig.lib.json | 2 +- packages/tar-parser/tsconfig.spec.json | 2 +- pnpm-lock.yaml | 10 + 10 files changed, 135 insertions(+), 889 deletions(-) delete mode 100644 packages/tar-parser/src/lib/multipart.spec.ts delete mode 100644 packages/tar-parser/src/lib/multipart.ts create mode 100644 packages/tar-parser/src/lib/tar.spec.ts rename packages/tar-parser/{src => }/test/utils.node.ts (100%) rename packages/tar-parser/{src => }/test/utils.ts (100%) diff --git a/packages/tar-parser/src/lib/multipart.spec.ts b/packages/tar-parser/src/lib/multipart.spec.ts deleted file mode 100644 index b0aa85d5799..00000000000 --- a/packages/tar-parser/src/lib/multipart.spec.ts +++ /dev/null @@ -1,293 +0,0 @@ -import * as assert from 'node:assert/strict'; -import { describe, it } from 'node:test'; - -import { - isMultipartRequest, - parseMultipartRequest, - MultipartParseError, - getMultipartBoundary, -} from './multipart.js'; -import { createMockRequest, createMultipartMockRequest, getRandomBytes } from '../test/utils.js'; - -const CRLF = '\r\n'; - -describe('getMultipartBoundary', async () => { - it('returns the boundary from the Content-Type header', async () => { - assert.equal(getMultipartBoundary('multipart/form-data; boundary=boundary123'), 'boundary123'); - }); - - it('returns null when boundary is missing', async () => { - assert.equal(getMultipartBoundary('multipart/form-data'), null); - }); - - it('returns null when Content-Type header is not multipart', async () => { - assert.equal(getMultipartBoundary('text/plain'), null); - }); -}); - -describe('isMultipartRequest', async () => { - it('returns true for multipart/form-data requests', async () => { - let request = createMockRequest({ - headers: { 'Content-Type': 'multipart/form-data' }, - }); - - assert.ok(isMultipartRequest(request)); - }); - - it('returns true for multipart/mixed requests', async () => { - let request = createMockRequest({ - headers: { 'Content-Type': 'multipart/mixed' }, - }); - - assert.ok(isMultipartRequest(request)); - }); - - it('returns false for other content types', async () => { - let request = createMockRequest({ - headers: { 'Content-Type': 'text/plain' }, - }); - - assert.ok(!isMultipartRequest(request)); - }); -}); - -describe('parseMultipartRequest', async () => { - let boundary = 'boundary123'; - - it('parses an empty multipart message', async () => { - let request = createMultipartMockRequest(boundary); - - let parts = []; - for await (let part of parseMultipartRequest(request)) { - parts.push(part); - } - - assert.equal(parts.length, 0); - }); - - it('parses a simple multipart form', async () => { - let request = createMultipartMockRequest(boundary, { - field1: 'value1', - }); - - let parts = []; - for await (let part of parseMultipartRequest(request)) { - parts.push(part); - } - - assert.equal(parts.length, 1); - assert.equal(parts[0].name, 'field1'); - assert.equal(await parts[0].text(), 'value1'); - }); - - it('parses multiple parts correctly', async () => { - let request = createMultipartMockRequest(boundary, { - field1: 'value1', - field2: 'value2', - }); - - let parts = []; - for await (let part of parseMultipartRequest(request)) { - parts.push(part); - } - - assert.equal(parts.length, 2); - assert.equal(parts[0].name, 'field1'); - assert.equal(await parts[0].text(), 'value1'); - assert.equal(parts[1].name, 'field2'); - assert.equal(await parts[1].text(), 'value2'); - }); - - it('parses empty parts correctly', async () => { - let request = createMultipartMockRequest(boundary, { - empty: '', - }); - - let parts = []; - for await (let part of parseMultipartRequest(request)) { - parts.push(part); - } - - assert.equal(parts.length, 1); - assert.equal(parts[0].name, 'empty'); - assert.equal((await parts[0].bytes()).byteLength, 0); - }); - - it('parses file uploads correctly', async () => { - let request = createMultipartMockRequest(boundary, { - file1: { - filename: 'test.txt', - mediaType: 'text/plain', - content: 'File content', - }, - }); - - let parts = []; - for await (let part of parseMultipartRequest(request)) { - parts.push(part); - } - - assert.equal(parts.length, 1); - assert.equal(parts[0].name, 'file1'); - assert.equal(parts[0].filename, 'test.txt'); - assert.equal(parts[0].mediaType, 'text/plain'); - assert.equal(await parts[0].text(), 'File content'); - }); - - it('parses multiple fields and a file upload', async () => { - let request = createMultipartMockRequest(boundary, { - field1: 'value1', - field2: 'value2', - file1: { - filename: 'test.txt', - mediaType: 'text/plain', - content: 'File content', - }, - }); - - let parts = []; - for await (let part of parseMultipartRequest(request)) { - parts.push(part); - } - - assert.equal(parts.length, 3); - assert.equal(parts[0].name, 'field1'); - assert.equal(await parts[0].text(), 'value1'); - assert.equal(parts[1].name, 'field2'); - assert.equal(await parts[1].text(), 'value2'); - assert.equal(parts[2].name, 'file1'); - assert.equal(parts[2].filename, 'test.txt'); - assert.equal(parts[2].mediaType, 'text/plain'); - assert.equal(await parts[2].text(), 'File content'); - }); - - it('parses large file uploads correctly', async () => { - let content = getRandomBytes(10 * 1024 * 1024); // 10 MB file - let request = createMultipartMockRequest(boundary, { - file1: { - filename: 'random.dat', - mediaType: 'application/octet-stream', - content, - }, - }); - - let parts = []; - for await (let part of parseMultipartRequest(request)) { - parts.push({ - name: part.name, - filename: part.filename, - mediaType: part.mediaType, - content: await part.bytes(), - }); - } - - assert.equal(parts.length, 1); - assert.equal(parts[0].name, 'file1'); - assert.equal(parts[0].filename, 'random.dat'); - assert.equal(parts[0].mediaType, 'application/octet-stream'); - assert.deepEqual(parts[0].content, content); - }); - - it('throws when Content-Type is not multipart/form-data', async () => { - let request = createMockRequest({ - headers: { 'Content-Type': 'text/plain' }, - }); - - await assert.rejects(async () => { - await parseMultipartRequest(request).next(); - }, MultipartParseError); - }); - - it('throws when boundary is missing', async () => { - let request = createMockRequest({ - headers: { 'Content-Type': 'multipart/form-data' }, - }); - - await assert.rejects(async () => { - await parseMultipartRequest(request).next(); - }, MultipartParseError); - }); - - it('throws when header exceeds maximum size', async () => { - let request = createMockRequest({ - headers: { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }, - body: [ - `--${boundary}`, - 'Content-Disposition: form-data; name="field1"', - 'X-Large-Header: ' + 'X'.repeat(6 * 1024), // 6 KB header - '', - 'value1', - `--${boundary}--`, - ].join(CRLF), - }); - - await assert.rejects(async () => { - for await (let part of parseMultipartRequest(request, { maxHeaderSize: 4 * 1024 })) { - for await (let _ of part.body) { - // Consume all parts - } - } - }, MultipartParseError); - }); - - it('throws when file exceeds maximum size', async () => { - let request = createMultipartMockRequest(boundary, { - file1: { - filename: 'random.dat', - mediaType: 'application/octet-stream', - content: getRandomBytes(11 * 1024 * 1024), // 11 MB file - }, - }); - - await assert.rejects(async () => { - for await (let part of parseMultipartRequest(request, { maxFileSize: 10 * 1024 * 1024 })) { - for await (let _ of part.body) { - // Consume all parts - } - } - }, MultipartParseError); - }); - - it('parses malformed parts', async () => { - let request = createMockRequest({ - headers: { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }, - body: [`--${boundary}`, 'Invalid-Header', '', 'Some content', `--${boundary}--`].join(CRLF), - }); - - let parts = []; - for await (let part of parseMultipartRequest(request)) { - parts.push(part); - } - - assert.equal(parts.length, 1); - assert.equal(parts[0].headers.get('Invalid-Header'), null); - assert.equal(await parts[0].text(), 'Some content'); - }); - - it('throws error when final boundary is missing', async () => { - let request = createMockRequest({ - headers: { - 'Content-Type': `multipart/form-data; boundary=${boundary}`, - }, - body: [ - `--${boundary}`, - 'Content-Disposition: form-data; name="field1"', - '', - 'value1', - `--${boundary}`, - ].join(CRLF), - }); - - await assert.rejects(async () => { - for await (let part of parseMultipartRequest(request)) { - for await (let _ of part.body) { - // Consume all parts - } - } - }, MultipartParseError); - }); -}); diff --git a/packages/tar-parser/src/lib/multipart.ts b/packages/tar-parser/src/lib/multipart.ts deleted file mode 100644 index a5ad3c91f18..00000000000 --- a/packages/tar-parser/src/lib/multipart.ts +++ /dev/null @@ -1,478 +0,0 @@ -import Headers from '@mjackson/headers'; - -import { - SearchFunction, - createSearch, - PartialTailSearchFunction, - createPartialTailSearch, -} from './search.js'; - -/** - * Extracts the boundary string from a `multipart/*` content type. - */ -export function getMultipartBoundary(contentType: string): string | null { - let match = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(contentType); - return match ? (match[1] ?? match[2]) : null; -} - -/** - * Returns true if the given request contains multipart data. - */ -export function isMultipartRequest(request: Request): boolean { - let contentType = request.headers.get('Content-Type'); - return contentType != null && contentType.startsWith('multipart/'); -} - -/** - * Parse a multipart [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and yield each part as - * a `MultipartPart` object. Useful in HTTP server contexts for handling incoming `multipart/*` requests. - */ -export async function* parseMultipartRequest( - request: Request, - options?: MultipartParserOptions, -): AsyncGenerator<MultipartPart> { - if (!isMultipartRequest(request)) { - throw new MultipartParseError('Request is not a multipart request'); - } - if (!request.body) { - throw new MultipartParseError('Request body is empty'); - } - - let boundary = getMultipartBoundary(request.headers.get('Content-Type')!); - if (!boundary) { - throw new MultipartParseError('Invalid Content-Type header: missing boundary'); - } - - yield* parseMultipart(request.body, boundary, options); -} - -/** - * Parse a `multipart/*` buffer or stream and yield each part it finds as a `MultipartPart` object. - * - * Note: This is a low-level API that requires manual handling of the stream and boundary. If you're - * building a web server, consider using `parseMultipartRequest(request)` instead. - */ -export async function* parseMultipart( - message: - | ReadableStream<Uint8Array> - | Uint8Array - | Iterable<Uint8Array> - | AsyncIterable<Uint8Array>, - boundary: string, - options?: MultipartParserOptions, -): AsyncGenerator<MultipartPart> { - let parser = new MultipartParser(boundary, options); - - let parts: MultipartPart[] = []; - let resolveNext: (() => void) | null = null; - let parseError: Error | null = null; - let done = false; - - parser - .parse(message, (part) => { - parts.push(part); - - if (resolveNext) { - resolveNext(); - resolveNext = null; - } - }) - .catch((error) => { - parseError = error; - }) - .finally(() => { - done = true; - if (resolveNext) resolveNext(); - }); - - while (!done) { - if (parts.length === 0) { - await new Promise<void>((resolve) => { - resolveNext = resolve; - }); - } - - while (parts.length > 0) { - yield parts.shift()!; - } - } - - if (parseError) { - throw parseError; - } -} - -const findDoubleNewline = createSearch('\r\n\r\n'); - -export class MultipartParseError extends Error { - constructor(message: string) { - super(message); - this.name = 'MultipartParseError'; - } -} - -export interface MultipartParserOptions { - maxHeaderSize?: number; - maxFileSize?: number; -} - -const enum MultipartParserState { - Start, - AfterBoundary, - Header, - Body, - Done, -} - -/** - * A parser for `multipart/*` HTTP messages. - */ -export class MultipartParser { - boundary: string; - maxHeaderSize: number; - maxFileSize: number; - - #findOpeningBoundary: SearchFunction; - #openingBoundaryLength: number; - - #findBoundary: SearchFunction; - #findPartialTailBoundary: PartialTailSearchFunction; - #boundaryLength: number; - - #state = MultipartParserState.Start; - #buffer: Uint8Array | null = null; - #bodyController: ReadableStreamDefaultController<Uint8Array> | null = null; - #bodyLength = 0; - - constructor(boundary: string, options?: MultipartParserOptions) { - this.boundary = boundary; - this.maxHeaderSize = options?.maxHeaderSize ?? 8 * 1024; - this.maxFileSize = options?.maxFileSize ?? Infinity; - - this.#findOpeningBoundary = createSearch(`--${boundary}`); - this.#openingBoundaryLength = 2 + boundary.length; // length of '--' + boundary - - this.#findBoundary = createSearch(`\r\n--${boundary}`); - this.#findPartialTailBoundary = createPartialTailSearch(`\r\n--${boundary}`); - this.#boundaryLength = 4 + boundary.length; // length of '\r\n--' + boundary - } - - /** - * Parse a stream/buffer multipart message and call the given handler for each part it contains. - * Resolves when the parse is finished and all handlers resolve. - */ - async parse( - message: - | ReadableStream<Uint8Array> - | Uint8Array - | Iterable<Uint8Array> - | AsyncIterable<Uint8Array>, - handler: (part: MultipartPart) => void, - ): Promise<void> { - if (this.#state !== MultipartParserState.Start) { - this.#reset(); - } - - let results: unknown[] = []; - - function handlePart(part: MultipartPart): void { - results.push(handler(part)); - } - - if (message instanceof ReadableStream || isAsyncIterable(message)) { - for await (let chunk of message) { - this.#write(chunk, handlePart); - } - } else if (message instanceof Uint8Array) { - this.#write(message, handlePart); - } else if (isIterable(message)) { - for (let chunk of message) { - this.#write(chunk, handlePart); - } - } else { - throw new TypeError('Cannot parse multipart message; expected a stream or buffer'); - } - - if (this.#state !== MultipartParserState.Done) { - throw new MultipartParseError('Unexpected end of stream'); - } - - await Promise.all(results); - } - - #reset(): void { - this.#state = MultipartParserState.Start; - this.#buffer = null; - this.#bodyController = null; - this.#bodyLength = 0; - } - - #write(chunk: Uint8Array, handler: (part: MultipartPart) => void): void { - if (this.#state === MultipartParserState.Done) { - throw new MultipartParseError('Unexpected data after end of stream'); - } - - let index = 0; - let chunkLength = chunk.length; - - if (this.#buffer !== null) { - let newChunk = new Uint8Array(this.#buffer.length + chunkLength); - newChunk.set(this.#buffer, 0); - newChunk.set(chunk, this.#buffer.length); - chunk = newChunk; - chunkLength = chunk.length; - this.#buffer = null; - } - - while (true) { - if (this.#state === MultipartParserState.Body) { - if (chunkLength - index < this.#boundaryLength) { - this.#buffer = chunk.subarray(index); - break; - } - - let boundaryIndex = this.#findBoundary(chunk, index); - - if (boundaryIndex === -1) { - // No boundary found, but there may be a partial match at the end of the chunk. - let partialTailIndex = this.#findPartialTailBoundary(chunk); - - if (partialTailIndex === -1) { - this.#writeBody(index === 0 ? chunk : chunk.subarray(index)); - } else { - this.#writeBody(chunk.subarray(index, partialTailIndex)); - this.#buffer = chunk.subarray(partialTailIndex); - } - - break; - } - - this.#writeBody(chunk.subarray(index, boundaryIndex)); - this.#closeBody(); - - index = boundaryIndex + this.#boundaryLength; - - this.#state = MultipartParserState.AfterBoundary; - } - - if (this.#state === MultipartParserState.AfterBoundary) { - if (chunkLength - index < 2) { - this.#buffer = chunk.subarray(index); - break; - } - - if (chunk[index] === 45 && chunk[index + 1] === 45) { - this.#state = MultipartParserState.Done; - break; - } - - index += 2; // Skip \r\n after boundary - - this.#state = MultipartParserState.Header; - } - - if (this.#state === MultipartParserState.Header) { - if (chunkLength - index < 4) { - this.#buffer = chunk.subarray(index); - break; - } - - let headerEndIndex = findDoubleNewline(chunk, index); - - if (headerEndIndex === -1) { - if (chunkLength - index > this.maxHeaderSize) { - throw new MultipartParseError( - `Header size exceeds maximum allowed size of ${this.maxHeaderSize} bytes`, - ); - } - - this.#buffer = chunk.subarray(index); - break; - } - - if (headerEndIndex - index > this.maxHeaderSize) { - throw new MultipartParseError( - `Header size exceeds maximum allowed size of ${this.maxHeaderSize} bytes`, - ); - } - - let header = chunk.subarray(index, headerEndIndex); - let part = new MultipartPart( - header, - new ReadableStream({ - start: (controller) => { - this.#bodyController = controller; - }, - }), - ); - - handler(part); - - index = headerEndIndex + 4; // Skip header + \r\n\r\n - - this.#state = MultipartParserState.Body; - - continue; - } - - if (this.#state === MultipartParserState.Start) { - if (chunkLength < this.#openingBoundaryLength) { - this.#buffer = chunk; - break; - } - - if (this.#findOpeningBoundary(chunk) !== 0) { - throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); - } - - index = this.#openingBoundaryLength; - - this.#state = MultipartParserState.AfterBoundary; - } - } - } - - #writeBody(chunk: Uint8Array): void { - if (this.#bodyLength + chunk.length > this.maxFileSize) { - let error = new MultipartParseError( - `File size exceeds maximum allowed size of ${this.maxFileSize} bytes`, - ); - - this.#bodyController!.error(error); - - throw error; - } - - this.#bodyController!.enqueue(chunk); - this.#bodyLength += chunk.length; - } - - #closeBody(): void { - this.#bodyController!.close(); - this.#bodyController = null; - this.#bodyLength = 0; - } -} - -function isIterable<T>(value: unknown): value is Iterable<T> { - return typeof value === 'object' && value != null && Symbol.iterator in value; -} - -function isAsyncIterable<T>(value: unknown): value is AsyncIterable<T> { - return typeof value === 'object' && value != null && Symbol.asyncIterator in value; -} - -/** - * A part of a `multipart/*` HTTP message. - */ -export class MultipartPart { - #header: Uint8Array; - #body: ReadableStream<Uint8Array>; - - #headers?: Headers; - #bodyUsed = false; - - constructor(header: Uint8Array, body: ReadableStream<Uint8Array>) { - this.#header = header; - this.#body = body; - } - - /** - * The content of this part as an `ArrayBuffer`. - */ - async arrayBuffer(): Promise<ArrayBuffer> { - return (await this.bytes()).buffer as ArrayBuffer; - } - - /** - * The body of this part as a `ReadableStream<Uint8Array>`. In `multipart/form-data` messages, this is useful - * for streaming the value of files that were uploaded using `<input type="file">` fields. - */ - get body(): ReadableStream<Uint8Array> { - return this.#body; - } - - /** - * Whether the body of this part has been consumed. - */ - get bodyUsed(): boolean { - return this.#bodyUsed; - } - - /** - * The body of this part buffered into a single `Uint8Array`. In `multipart/form-data` messages, this is useful - * for reading the value of files that were uploaded using `<input type="file">` fields. - */ - async bytes(): Promise<Uint8Array> { - if (this.#bodyUsed) { - throw new Error('Body is already consumed or is being consumed'); - } - - this.#bodyUsed = true; - - let chunks: Uint8Array[] = []; - let totalLength = 0; - for await (let chunk of this.#body) { - chunks.push(chunk); - totalLength += chunk.length; - } - - let result = new Uint8Array(totalLength); - let offset = 0; - for (let chunk of chunks) { - result.set(chunk, offset); - offset += chunk.length; - } - - return result; - } - - /** - * The headers associated with this part. - */ - get headers(): Headers { - if (!this.#headers) { - this.#headers = new Headers(new TextDecoder().decode(this.#header)); - } - - return this.#headers; - } - - /** - * True if this part originated from a file upload. - */ - get isFile(): boolean { - return this.filename !== undefined || this.mediaType === 'application/octet-stream'; - } - - /** - * The filename of the part, if it is a file upload. - */ - get filename(): string | undefined { - return this.headers.contentDisposition.preferredFilename; - } - - /** - * The media type of the part. - */ - get mediaType(): string | undefined { - return this.headers.contentType.mediaType; - } - - /** - * The name of the part, usually the `name` of the field in the `<form>` that submitted the request. - */ - get name(): string | undefined { - return this.headers.contentDisposition.name; - } - - /** - * The body of the part as a string. In `multipart/form-data` messages, this is useful for reading the value - * of parts that originated from `<input type="text">` fields. - * - * Note: Do not use this for binary data, use `await part.bytes()` or stream `part.body` directly instead. - */ - async text(): Promise<string> { - return new TextDecoder().decode(await this.bytes()); - } -} diff --git a/packages/tar-parser/src/lib/tar.spec.ts b/packages/tar-parser/src/lib/tar.spec.ts new file mode 100644 index 00000000000..61b10fd2766 --- /dev/null +++ b/packages/tar-parser/src/lib/tar.spec.ts @@ -0,0 +1,12 @@ +import { describe, it } from 'node:test'; +import * as assert from 'node:assert/strict'; + +import { parseTarHeader } from './tar.js'; + +describe('parseTarHeader', () => { + it('parses a tarball header', () => { + const header = new TextEncoder().encode( + `0000644 0001750 0001750 00000000000 13175443722 015754 0ustar 000000 00000000 `, + ); + }); +}); diff --git a/packages/tar-parser/src/lib/tar.ts b/packages/tar-parser/src/lib/tar.ts index fffbd02409d..8fcaf411328 100644 --- a/packages/tar-parser/src/lib/tar.ts +++ b/packages/tar-parser/src/lib/tar.ts @@ -1,111 +1,111 @@ const TarBlockSize = 512; export class TarParseError extends Error { - constructor(message: string) { - super(message); - this.name = 'TarParseError'; - } + constructor(message: string) { + super(message); + this.name = 'TarParseError'; + } } export interface TarHeader { - name: string; - mode: number; - uid: number; - gid: number; - size: number; - mtime: number; - checksum: number; - type: string; - linkname: string; - uname: string; - gname: string; - devmajor: number; - devminor: number; - prefix: string; + name: string; + mode: number; + uid: number; + gid: number; + size: number; + mtime: number; + checksum: number; + type: string; + linkname: string; + uname: string; + gname: string; + devmajor: number; + devminor: number; + prefix: string; } const TarFileTypes: Record<string, string> = { - '0': 'file', - '1': 'link', - '2': 'symlink', - '3': 'character', - '4': 'block', - '5': 'directory', - '6': 'fifo', - '7': 'contiguous', + '0': 'file', + '1': 'link', + '2': 'symlink', + '3': 'character', + '4': 'block', + '5': 'directory', + '6': 'fifo', + '7': 'contiguous', }; export function parseTarHeader(buffer: Uint8Array): TarHeader { - if (buffer.length !== TarBlockSize) { - throw new TarParseError('Invalid tar header size'); - } - - let decoder = new TextDecoder('ascii'); - - function getString(offset: number, size: number) { - return decoder.decode(buffer.subarray(offset, offset + size)).replace(/\0.*$/, ''); - } - - function getOctal(offset: number, size: number) { - return parseInt(getString(offset, size), 8); - } - - // UStar header format - // Offset Size Field - // 0 100 Filename - // 100 8 File mode (octal) - // 108 8 Owner's numeric user ID (octal) - // 116 8 Group's numeric user ID (octal) - // 124 12 File size in bytes (octal) - // 136 12 Last modification time (octal) - // 148 8 Checksum for header block (octal) - // 156 1 Link indicator (file type) - // 157 100 Name of linked file - // 257 6 UStar indicator "ustar\0" - // 263 2 UStar version "00" - // 265 32 Owner username - // 297 32 Owner groupname - // 329 8 Device major number (octal) - // 337 8 Device minor number (octal) - // 345 155 Filename prefix - - let checksum = getOctal(148, 8); - if (checksum !== computeHeaderChecksum(buffer)) { - throw new TarParseError('Invalid tar header checksum'); - } - - let ustarIndicator = getString(257, 6); - if (ustarIndicator !== 'ustar') { - throw new TarParseError('Invalid tar header, must be ustar'); - } - - let linkIndicator = String.fromCharCode(buffer[156]); - - return { - name: getString(0, 100), - mode: getOctal(100, 8), - uid: getOctal(108, 8), - gid: getOctal(116, 8), - size: getOctal(124, 12), - mtime: getOctal(136, 12), - checksum, - type: TarFileTypes[linkIndicator] || 'unknown', - linkname: getString(157, 100), - uname: getString(265, 32), - gname: getString(297, 32), - devmajor: getOctal(329, 8), - devminor: getOctal(337, 8), - prefix: getString(345, 155), - }; + if (buffer.length !== TarBlockSize) { + throw new TarParseError('Invalid tar header size'); + } + + let decoder = new TextDecoder('ascii'); + + function getString(offset: number, size: number) { + return decoder.decode(buffer.subarray(offset, offset + size)).replace(/\0.*$/, ''); + } + + function getOctal(offset: number, size: number) { + return parseInt(getString(offset, size), 8); + } + + // UStar header format + // Offset Size Field + // 0 100 Filename + // 100 8 File mode (octal) + // 108 8 Owner's numeric user ID (octal) + // 116 8 Group's numeric user ID (octal) + // 124 12 File size in bytes (octal) + // 136 12 Last modification time (octal) + // 148 8 Checksum for header block (octal) + // 156 1 Link indicator (file type) + // 157 100 Name of linked file + // 257 6 UStar indicator "ustar\0" + // 263 2 UStar version "00" + // 265 32 Owner username + // 297 32 Owner groupname + // 329 8 Device major number (octal) + // 337 8 Device minor number (octal) + // 345 155 Filename prefix + + let checksum = getOctal(148, 8); + if (checksum !== computeHeaderChecksum(buffer)) { + throw new TarParseError('Invalid tar header checksum'); + } + + let ustarIndicator = getString(257, 6); + if (ustarIndicator !== 'ustar') { + throw new TarParseError('Invalid tar header, must be ustar'); + } + + let linkIndicator = String.fromCharCode(buffer[156]); + + return { + name: getString(0, 100), + mode: getOctal(100, 8), + uid: getOctal(108, 8), + gid: getOctal(116, 8), + size: getOctal(124, 12), + mtime: getOctal(136, 12), + checksum, + type: TarFileTypes[linkIndicator] || 'unknown', + linkname: getString(157, 100), + uname: getString(265, 32), + gname: getString(297, 32), + devmajor: getOctal(329, 8), + devminor: getOctal(337, 8), + prefix: getString(345, 155), + }; } function computeHeaderChecksum(buffer: Uint8Array): number { - let sum = 0; - for (let i = 0; i < 512; i++) { - sum += i >= 148 && i < 156 ? 32 : buffer[i]; - } + let sum = 0; + for (let i = 0; i < 512; i++) { + sum += i >= 148 && i < 156 ? 32 : buffer[i]; + } - return sum; + return sum; } const enum TarParserState { @@ -122,7 +122,7 @@ export class TarParser { #state = TarParserState.Start; #buffer: Uint8Array | null = null; #bodyController: ReadableStreamDefaultController<Uint8Array> | null = null; - #bodyWritten = 0; + #bodyWritten = 0; #bodySize = 0; // The declared size of the current body /** @@ -193,7 +193,7 @@ export class TarParser { } while (true) { - if (this.#state === TarParserState.Body) { + if (this.#state === TarParserState.Body) { } if (this.#state === TarParserState.Header) { @@ -205,19 +205,19 @@ export class TarParser { } #writeBody(chunk: Uint8Array): void { - if (this.#bodyWritten + chunk.length > this.#bodySize) { - throw new TarParseError('Body size exceeds declared size'); - } + if (this.#bodyWritten + chunk.length > this.#bodySize) { + throw new TarParseError('Body size exceeds declared size'); + } this.#bodyController!.enqueue(chunk); - this.#bodyWritten += chunk.length + this.#bodyWritten += chunk.length; } #closeBody(): void { this.#bodyController!.close(); this.#bodyController = null; - this.#bodyWritten = 0 - this.#bodySize = 0 + this.#bodyWritten = 0; + this.#bodySize = 0; } } @@ -230,7 +230,7 @@ function isAsyncIterable<T>(value: unknown): value is AsyncIterable<T> { } function isZeroBlock(buffer: Uint8Array): boolean { - return buffer.every((byte) => byte === 0); + return buffer.every((byte) => byte === 0); } /** @@ -279,7 +279,7 @@ export class TarEntry { let result = new Uint8Array(this.size); let offset = 0; - for (let chunk of this.#body) { + for await (let chunk of this.#body) { result.set(chunk, offset); offset += chunk.length; } @@ -291,23 +291,23 @@ export class TarEntry { * The raw header info associated with this entry. */ get header(): TarHeader { - return this.#header; + return this.#header; } /** * The name of this entry. */ get name(): string { - // TODO: handle prefix + // TODO: handle prefix return this.header.name; } - /** - * The size of this entry in bytes. - */ - get size(): number { - return this.header.size; - } + /** + * The size of this entry in bytes. + */ + get size(): number { + return this.header.size; + } /** * The content of this entry as a string. diff --git a/packages/tar-parser/src/tar-parser.ts b/packages/tar-parser/src/tar-parser.ts index ba4f34d7dec..1a021de3662 100644 --- a/packages/tar-parser/src/tar-parser.ts +++ b/packages/tar-parser/src/tar-parser.ts @@ -1,6 +1 @@ -export { - TarParseError, - type TarHeader, - parseTarHeader, - TarEntry -} from './lib/tar.js'; +export { TarParseError, type TarHeader, parseTarHeader, TarParser, TarEntry } from './lib/tar.js'; diff --git a/packages/tar-parser/src/test/utils.node.ts b/packages/tar-parser/test/utils.node.ts similarity index 100% rename from packages/tar-parser/src/test/utils.node.ts rename to packages/tar-parser/test/utils.node.ts diff --git a/packages/tar-parser/src/test/utils.ts b/packages/tar-parser/test/utils.ts similarity index 100% rename from packages/tar-parser/src/test/utils.ts rename to packages/tar-parser/test/utils.ts diff --git a/packages/tar-parser/tsconfig.lib.json b/packages/tar-parser/tsconfig.lib.json index c9819aa7ed5..8e712f7d6c8 100644 --- a/packages/tar-parser/tsconfig.lib.json +++ b/packages/tar-parser/tsconfig.lib.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts", "src/test/**/*.ts"], + "exclude": ["src/**/*.spec.ts"], "compilerOptions": { "composite": true, "rootDir": "src" diff --git a/packages/tar-parser/tsconfig.spec.json b/packages/tar-parser/tsconfig.spec.json index 0dcc65f3ce6..547e6dabbd4 100644 --- a/packages/tar-parser/tsconfig.spec.json +++ b/packages/tar-parser/tsconfig.spec.json @@ -1,6 +1,6 @@ { "extends": "./tsconfig.json", - "include": ["src/**/*.spec.ts", "src/test/**/*.ts"], + "include": ["src/**/*.spec.ts", "test/**/*.ts"], "compilerOptions": { "composite": true, "types": ["node"] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6c2e11d296c..9e2eac6d68b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -203,6 +203,16 @@ importers: specifier: ^4.17.21 version: 4.17.21 + packages/tar-parser: + dependencies: + '@mjackson/lazy-file': + specifier: workspace:^ + version: link:../lazy-file + devDependencies: + '@types/node': + specifier: ^20.14.10 + version: 20.16.1 + scripts: dependencies: '@octokit/request': From 9aabfe09c7c0687d9727e80f7b7557c16e33f786 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Sat, 9 Nov 2024 07:04:06 -0800 Subject: [PATCH 521/730] Add tests for tar-parser --- packages/tar-parser/package.json | 4 +- packages/tar-parser/src/lib/tar.spec.ts | 77 ++++++++- packages/tar-parser/src/lib/tar.ts | 77 +++++++-- .../test/fixtures/express-4.21.1.tgz | Bin 0 -> 57941 bytes .../tar-parser/test/fixtures/react-18.0.0.tgz | Bin 0 -> 81337 bytes packages/tar-parser/test/utils.node.ts | 33 ---- packages/tar-parser/test/utils.ts | 152 +----------------- pnpm-lock.yaml | 3 +- 8 files changed, 145 insertions(+), 201 deletions(-) create mode 100644 packages/tar-parser/test/fixtures/express-4.21.1.tgz create mode 100644 packages/tar-parser/test/fixtures/react-18.0.0.tgz delete mode 100644 packages/tar-parser/test/utils.node.ts diff --git a/packages/tar-parser/package.json b/packages/tar-parser/package.json index a775066dc25..b28faa59229 100644 --- a/packages/tar-parser/package.json +++ b/packages/tar-parser/package.json @@ -20,10 +20,8 @@ ".": "./dist/tar-parser.js", "./package.json": "./package.json" }, - "dependencies": { - "@mjackson/lazy-file": "workspace:^" - }, "devDependencies": { + "@mjackson/lazy-file": "workspace:^", "@types/node": "^20.14.10" }, "scripts": { diff --git a/packages/tar-parser/src/lib/tar.spec.ts b/packages/tar-parser/src/lib/tar.spec.ts index 61b10fd2766..12d5b67d326 100644 --- a/packages/tar-parser/src/lib/tar.spec.ts +++ b/packages/tar-parser/src/lib/tar.spec.ts @@ -1,12 +1,77 @@ import { describe, it } from 'node:test'; import * as assert from 'node:assert/strict'; -import { parseTarHeader } from './tar.js'; +import { openFixture } from '../../test/utils.js'; -describe('parseTarHeader', () => { - it('parses a tarball header', () => { - const header = new TextEncoder().encode( - `0000644 0001750 0001750 00000000000 13175443722 015754 0ustar 000000 00000000 `, - ); +import { TarParser } from './tar.js'; + +function readFixture(name: string): ReadableStream<Uint8Array> { + let stream = openFixture(name).stream(); + return name.endsWith('.tgz') ? stream.pipeThrough(new DecompressionStream('gzip')) : stream; +} + +describe('TarParser', () => { + it('parses express-4.21.1.tgz', async () => { + let stream = readFixture('express-4.21.1.tgz'); + let parser = new TarParser(); + + let entries: [string, number][] = []; + + await parser.parse(stream, (entry) => { + entries.push([entry.name, entry.size]); + }); + + assert.deepEqual(entries, [ + ['package/LICENSE', 1249], + ['package/lib/application.js', 14593], + ['package/lib/express.js', 2409], + ['package/index.js', 224], + ['package/lib/router/index.js', 15123], + ['package/lib/middleware/init.js', 853], + ['package/lib/router/layer.js', 3296], + ['package/lib/middleware/query.js', 885], + ['package/lib/request.js', 12505], + ['package/lib/response.js', 28729], + ['package/lib/router/route.js', 4399], + ['package/lib/utils.js', 5871], + ['package/lib/view.js', 3325], + ['package/package.json', 2708], + ['package/History.md', 114974], + ['package/Readme.md', 9806], + ]); + }); + + it('parses react-18.0.0.tgz', async () => { + let stream = readFixture('react-18.0.0.tgz'); + let parser = new TarParser(); + + let entries: [string, number][] = []; + + await parser.parse(stream, (entry) => { + entries.push([entry.name, entry.size]); + }); + + assert.deepEqual(entries, [ + ['package/LICENSE', 1086], + ['package/index.js', 190], + ['package/jsx-dev-runtime.js', 222], + ['package/jsx-runtime.js', 214], + ['package/cjs/react-jsx-dev-runtime.development.js', 41115], + ['package/cjs/react-jsx-dev-runtime.production.min.js', 343], + ['package/cjs/react-jsx-dev-runtime.profiling.min.js', 342], + ['package/cjs/react-jsx-runtime.development.js', 41714], + ['package/cjs/react-jsx-runtime.production.min.js', 859], + ['package/cjs/react-jsx-runtime.profiling.min.js', 858], + ['package/cjs/react.development.js', 87561], + ['package/umd/react.development.js', 109891], + ['package/cjs/react.production.min.js', 6932], + ['package/umd/react.production.min.js', 10756], + ['package/umd/react.profiling.min.js', 10755], + ['package/cjs/react.shared-subset.development.js', 501], + ['package/react.shared-subset.js', 218], + ['package/cjs/react.shared-subset.production.min.js', 351], + ['package/package.json', 999], + ['package/README.md', 737], + ]); }); }); diff --git a/packages/tar-parser/src/lib/tar.ts b/packages/tar-parser/src/lib/tar.ts index 8fcaf411328..e1554435f36 100644 --- a/packages/tar-parser/src/lib/tar.ts +++ b/packages/tar-parser/src/lib/tar.ts @@ -112,6 +112,7 @@ const enum TarParserState { Start, Header, Body, + AfterBody, Done, } @@ -126,11 +127,11 @@ export class TarParser { #bodySize = 0; // The declared size of the current body /** - * Parse a stream/buffer multipart message and call the given handler for each part it contains. + * Parse a stream/buffer tar archive and call the given handler for each entry it contains. * Resolves when the parse is finished and all handlers resolve. */ async parse( - message: + archive: | ReadableStream<Uint8Array> | Uint8Array | Iterable<Uint8Array> @@ -147,14 +148,14 @@ export class TarParser { results.push(handler(entry)); } - if (message instanceof ReadableStream || isAsyncIterable(message)) { - for await (let chunk of message) { + if (archive instanceof ReadableStream || isAsyncIterable(archive)) { + for await (let chunk of archive) { this.#write(chunk, handleEntry); } - } else if (message instanceof Uint8Array) { - this.#write(message, handleEntry); - } else if (isIterable(message)) { - for (let chunk of message) { + } else if (archive instanceof Uint8Array) { + this.#write(archive, handleEntry); + } else if (isIterable(archive)) { + for (let chunk of archive) { this.#write(chunk, handleEntry); } } else { @@ -194,12 +195,67 @@ export class TarParser { while (true) { if (this.#state === TarParserState.Body) { + let remaining = this.#bodySize - this.#bodyWritten; + + if (chunk.length - index < remaining) { + this.#writeBody(index === 0 ? chunk : chunk.subarray(index)); + break; + } + + this.#writeBody(chunk.subarray(index, index + remaining)); + index += remaining; + + this.#closeBody(); + + this.#state = TarParserState.AfterBody; } - if (this.#state === TarParserState.Header) { + if (this.#state === TarParserState.AfterBody) { + let padding = TarBlockSize - (this.#bodySize % TarBlockSize); + + if (chunk.length - index < padding + 2 * TarBlockSize) { + this.#buffer = chunk.subarray(index); + break; + } + + index += padding; // Skip padding + + // Check for end of archive + if (isZeroBlock(chunk.subarray(index, index + TarBlockSize))) { + if (isZeroBlock(chunk.subarray(index + TarBlockSize, index + 2 * TarBlockSize))) { + this.#state = TarParserState.Done; + break; + } else { + throw new TarParseError('Invalid end of archive'); + } + } + + this.#state = TarParserState.Header; } - if (this.#state === TarParserState.Start) { + if (this.#state === TarParserState.Header || this.#state === TarParserState.Start) { + if (chunk.length - index < TarBlockSize) { + this.#buffer = chunk.subarray(index); + break; + } + + let header = parseTarHeader(chunk.subarray(index, index + TarBlockSize)); + index += TarBlockSize; + + this.#bodySize = header.size; + + let entry = new TarEntry( + header, + new ReadableStream({ + start: (controller) => { + this.#bodyController = controller; + }, + }), + ); + + handler(entry); + + this.#state = TarParserState.Body; } } } @@ -217,7 +273,6 @@ export class TarParser { this.#bodyController!.close(); this.#bodyController = null; this.#bodyWritten = 0; - this.#bodySize = 0; } } diff --git a/packages/tar-parser/test/fixtures/express-4.21.1.tgz b/packages/tar-parser/test/fixtures/express-4.21.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..2bb5ecc20488317e9ac1af7c80842f0ea9f42532 GIT binary patch literal 57941 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%0AC6XW$h6lgxwWccPMXj(q20<5Z9&`9Zc(~X7T=3 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 literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/react-18.0.0.tgz b/packages/tar-parser/test/fixtures/react-18.0.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..bf7fa723e3b0379972d22c7189b21b0cbb468a0f GIT binary patch literal 81337 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 DAF`cz literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/utils.node.ts b/packages/tar-parser/test/utils.node.ts deleted file mode 100644 index ddf8321e4d4..00000000000 --- a/packages/tar-parser/test/utils.node.ts +++ /dev/null @@ -1,33 +0,0 @@ -import * as http from 'node:http'; -import * as stream from 'node:stream'; - -import { PartValue, createMultipartBody } from './utils.js'; - -export function createReadable(content: Uint8Array, chunkSize = 16 * 1024): stream.Readable { - let i = 0; - - return new stream.Readable({ - read() { - if (i < content.length) { - this.push(content.subarray(i, i + chunkSize)); - i += chunkSize; - } else { - this.push(null); - } - }, - }); -} - -export function createMultipartMockRequest( - boundary: string, - parts?: { [name: string]: PartValue }, -): http.IncomingMessage { - let body = createMultipartBody(boundary, parts); - - let request = createReadable(body) as http.IncomingMessage; - request.headers = { - 'content-type': `multipart/form-data; boundary=${boundary}`, - }; - - return request; -} diff --git a/packages/tar-parser/test/utils.ts b/packages/tar-parser/test/utils.ts index ffcfd39ad89..f279750146e 100644 --- a/packages/tar-parser/test/utils.ts +++ b/packages/tar-parser/test/utils.ts @@ -1,149 +1,9 @@ -import Headers from '@mjackson/headers'; +import * as path from 'node:path'; +import { openFile } from '@mjackson/lazy-file/fs'; -export function concat(chunks: Uint8Array[]): Uint8Array { - if (chunks.length === 1) return chunks[0]; +const __dirname = path.dirname(new URL(import.meta.url).pathname); +const fixturesDir = path.resolve(__dirname, 'fixtures'); - let length = 0; - for (let chunk of chunks) { - length += chunk.length; - } - - let result = new Uint8Array(length); - let offset = 0; - - for (let chunk of chunks) { - result.set(chunk, offset); - offset += chunk.length; - } - - return result; -} - -export function getRandomBytes(size: number): Uint8Array { - let chunks: Uint8Array[] = []; - - for (let i = 0; i < size; i += 65536) { - chunks.push(crypto.getRandomValues(new Uint8Array(Math.min(size - i, 65536)))); - } - - return concat(chunks); -} - -export function createReadableStream( - content: string | Uint8Array, - chunkSize = 64 * 1024, -): ReadableStream<Uint8Array> { - let encoder = new TextEncoder(); - - return new ReadableStream({ - start(controller) { - for (let i = 0; i < content.length; i += chunkSize) { - controller.enqueue( - typeof content === 'string' - ? encoder.encode(content.slice(i, i + chunkSize)) - : content.subarray(i, i + chunkSize), - ); - } - controller.close(); - }, - }); -} - -export function createMockRequest({ - headers, - body = '', -}: { - headers?: Headers | HeadersInit; - body?: string | Uint8Array | ReadableStream<Uint8Array>; -}): Request { - return { - headers: headers instanceof Headers ? headers : new Headers(headers), - body: - typeof body === 'string' || body instanceof Uint8Array ? createReadableStream(body) : body, - } as unknown as Request; -} - -export type PartValue = - | string - | { - filename?: string; - filenameSplat?: string; - mediaType?: string; - content: string | Uint8Array; - }; - -export function createMultipartBody( - boundary: string, - parts?: { [name: string]: PartValue }, -): Uint8Array { - let chunks: Uint8Array[] = []; - - function pushString(string: string) { - chunks.push(new TextEncoder().encode(string)); - } - - function pushLine(line = '') { - pushString(line + '\r\n'); - } - - if (parts) { - for (let [name, part] of Object.entries(parts)) { - pushLine(`--${boundary}`); - - if (typeof part === 'string') { - let headers = new Headers({ - contentDisposition: { - type: 'form-data', - name, - }, - }); - - pushLine(`${headers}`); - pushLine(); - pushLine(part); - } else { - let headers = new Headers({ - contentDisposition: { - type: 'form-data', - name, - filename: part.filename, - filenameSplat: part.filenameSplat, - }, - }); - - if (part.mediaType) { - headers.contentType = part.mediaType; - } - - pushLine(`${headers}`); - pushLine(); - if (typeof part.content === 'string') { - pushLine(part.content); - } else { - chunks.push(part.content); - pushLine(); - } - } - } - } - - pushString(`--${boundary}--`); - - return concat(chunks); -} - -export function createMultipartMockRequest( - boundary: string, - parts?: { [name: string]: PartValue }, -): Request { - let headers = new Headers({ - contentType: { - mediaType: 'multipart/form-data', - boundary, - }, - }); - - let body = createMultipartBody(boundary, parts); - - return createMockRequest({ headers, body }); +export function openFixture(name: string): File { + return openFile(path.join(fixturesDir, name)); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e2eac6d68b..10d520a6b98 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -204,11 +204,10 @@ importers: version: 4.17.21 packages/tar-parser: - dependencies: + devDependencies: '@mjackson/lazy-file': specifier: workspace:^ version: link:../lazy-file - devDependencies: '@types/node': specifier: ^20.14.10 version: 20.16.1 From 06fd33fa7156009bee357197091ee4bc214af4e0 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Tue, 12 Nov 2024 23:58:30 -0800 Subject: [PATCH 522/730] Finish tar-parser --- packages/tar-parser/bench/global.d.ts | 2 - packages/tar-parser/bench/messages.ts | 63 --- packages/tar-parser/bench/package.json | 13 +- packages/tar-parser/bench/parsers/busboy.ts | 38 -- .../bench/parsers/fastify-busboy.ts | 38 -- .../bench/parsers/multipart-parser.ts | 13 - .../tar-parser/bench/parsers/multipasta.ts | 24 - .../tar-parser/bench/parsers/tar-parser.ts | 14 + .../tar-parser/bench/parsers/tar-stream.ts | 31 ++ packages/tar-parser/bench/runner.ts | 45 +- packages/tar-parser/bench/utils.ts | 28 - packages/tar-parser/package.json | 5 +- packages/tar-parser/src/lib/tar.spec.ts | 479 ++++++++++++++++-- packages/tar-parser/src/lib/tar.ts | 399 ++++++++++++--- packages/tar-parser/src/tar-parser.ts | 10 +- .../test/fixtures/base-256-size.tar | Bin 0 -> 2048 bytes .../test/fixtures/base-256-uid-gid.tar | Bin 0 -> 10240 bytes .../test/fixtures/fetch-proxy-0.1.0.tar.gz | Bin 0 -> 97606 bytes .../test/fixtures/gnu-incremental.tar | Bin 0 -> 10240 bytes .../test/fixtures/gnu-long-path.tar | Bin 0 -> 7680 bytes packages/tar-parser/test/fixtures/gnu.tar | Bin 0 -> 10240 bytes .../tar-parser/test/fixtures/incomplete.tar | Bin 0 -> 1000 bytes packages/tar-parser/test/fixtures/latin1.tar | Bin 0 -> 10240 bytes .../test/fixtures/lodash-4.17.21.tgz | Bin 0 -> 318961 bytes .../tar-parser/test/fixtures/long-name.tar | Bin 0 -> 2048 bytes .../tar-parser/test/fixtures/multi-file.tar | Bin 0 -> 3072 bytes .../tar-parser/test/fixtures/name-is-100.tar | Bin 0 -> 10240 bytes .../tar-parser/test/fixtures/one-file.tar | Bin 0 -> 2048 bytes packages/tar-parser/test/fixtures/pax.tar | Bin 0 -> 3072 bytes .../tar-parser/test/fixtures/react-18.0.0.tgz | Bin 81337 -> 0 bytes packages/tar-parser/test/fixtures/space.tar | Bin 0 -> 10240 bytes packages/tar-parser/test/fixtures/types.tar | Bin 0 -> 2048 bytes .../tar-parser/test/fixtures/unicode-bsd.tar | Bin 0 -> 10240 bytes packages/tar-parser/test/fixtures/unicode.tar | Bin 0 -> 3072 bytes packages/tar-parser/test/utils.ts | 29 +- pnpm-lock.yaml | 245 +++++++++ pnpm-workspace.yaml | 1 + 37 files changed, 1121 insertions(+), 356 deletions(-) delete mode 100644 packages/tar-parser/bench/messages.ts delete mode 100644 packages/tar-parser/bench/parsers/busboy.ts delete mode 100644 packages/tar-parser/bench/parsers/fastify-busboy.ts delete mode 100644 packages/tar-parser/bench/parsers/multipart-parser.ts delete mode 100644 packages/tar-parser/bench/parsers/multipasta.ts create mode 100644 packages/tar-parser/bench/parsers/tar-parser.ts create mode 100644 packages/tar-parser/bench/parsers/tar-stream.ts delete mode 100644 packages/tar-parser/bench/utils.ts create mode 100644 packages/tar-parser/test/fixtures/base-256-size.tar create mode 100644 packages/tar-parser/test/fixtures/base-256-uid-gid.tar create mode 100644 packages/tar-parser/test/fixtures/fetch-proxy-0.1.0.tar.gz create mode 100644 packages/tar-parser/test/fixtures/gnu-incremental.tar create mode 100644 packages/tar-parser/test/fixtures/gnu-long-path.tar create mode 100644 packages/tar-parser/test/fixtures/gnu.tar create mode 100644 packages/tar-parser/test/fixtures/incomplete.tar create mode 100644 packages/tar-parser/test/fixtures/latin1.tar create mode 100644 packages/tar-parser/test/fixtures/lodash-4.17.21.tgz create mode 100644 packages/tar-parser/test/fixtures/long-name.tar create mode 100644 packages/tar-parser/test/fixtures/multi-file.tar create mode 100644 packages/tar-parser/test/fixtures/name-is-100.tar create mode 100644 packages/tar-parser/test/fixtures/one-file.tar create mode 100644 packages/tar-parser/test/fixtures/pax.tar delete mode 100644 packages/tar-parser/test/fixtures/react-18.0.0.tgz create mode 100644 packages/tar-parser/test/fixtures/space.tar create mode 100644 packages/tar-parser/test/fixtures/types.tar create mode 100644 packages/tar-parser/test/fixtures/unicode-bsd.tar create mode 100644 packages/tar-parser/test/fixtures/unicode.tar diff --git a/packages/tar-parser/bench/global.d.ts b/packages/tar-parser/bench/global.d.ts index dbb97336eb9..b8041179bc5 100644 --- a/packages/tar-parser/bench/global.d.ts +++ b/packages/tar-parser/bench/global.d.ts @@ -1,5 +1,3 @@ -declare var Deno: { version: { deno: string } } | undefined; - // See https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62651 interface ReadableStream<R = any> { diff --git a/packages/tar-parser/bench/messages.ts b/packages/tar-parser/bench/messages.ts deleted file mode 100644 index ea6edbcd60a..00000000000 --- a/packages/tar-parser/bench/messages.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { concat, getRandomBytes } from './utils.js'; - -const NodeDefaultHighWaterMark = 65536; - -export class MultipartMessage { - boundary: string; - content: Uint8Array; - - constructor(boundary: string, partSizes: number[]) { - this.boundary = boundary; - - let chunks: Uint8Array[] = []; - - function pushString(string: string): void { - chunks.push(new TextEncoder().encode(string)); - } - - function pushLine(line = ''): void { - pushString(line + '\r\n'); - } - - for (let i = 0; i < partSizes.length; i++) { - pushLine(`--${boundary}`); - pushLine(`Content-Disposition: form-data; name="file${i}"; filename="file${i}.dat"`); - pushLine('Content-Type: application/octet-stream'); - pushLine(); - chunks.push(getRandomBytes(partSizes[i])); - pushLine(); - } - - pushString(`--${boundary}--`); - - this.content = concat(chunks); - } - - *generateChunks(chunkSize = NodeDefaultHighWaterMark): Generator<Uint8Array> { - for (let i = 0; i < this.content.length; i += chunkSize) { - yield this.content.subarray(i, i + chunkSize); - } - } -} - -const oneKb = 1024; -const oneMb = 1024 * oneKb; - -export const oneSmallFile = new MultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [oneKb]); - -export const oneLargeFile = new MultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [ - 10 * oneMb, -]); - -export const oneHundredSmallFiles = new MultipartMessage( - '----WebKitFormBoundaryzv0Og5zWtGjvzP2A', - Array(100).fill(oneKb), -); - -export const fiveLargeFiles = new MultipartMessage('----WebKitFormBoundaryzv0Og5zWtGjvzP2A', [ - 10 * oneMb, - 10 * oneMb, - 10 * oneMb, - 20 * oneMb, - 50 * oneMb, -]); diff --git a/packages/tar-parser/bench/package.json b/packages/tar-parser/bench/package.json index 4bb5e8ce417..34ec24e78da 100644 --- a/packages/tar-parser/bench/package.json +++ b/packages/tar-parser/bench/package.json @@ -1,15 +1,14 @@ { - "name": "multipart-parser-bench", + "name": "tar-parser-bench", "private": true, "type": "module", "dependencies": { - "@fastify/busboy": "^3.0.0", - "@mjackson/multipart-parser": "workspace:*", - "busboy": "^1.6.0", - "multipasta": "^0.2.4" + "@mjackson/lazy-file": "workspace:*", + "@mjackson/tar-parser": "workspace:*", + "gunzip-maybe": "^1.4.2", + "tar-stream": "^3.1.7" }, "devDependencies": { - "@types/bun": "^1.1.6", - "@types/busboy": "^1.5.4" + "@types/gunzip-maybe": "^1.4.2" } } diff --git a/packages/tar-parser/bench/parsers/busboy.ts b/packages/tar-parser/bench/parsers/busboy.ts deleted file mode 100644 index ed3dfc7fced..00000000000 --- a/packages/tar-parser/bench/parsers/busboy.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Readable } from 'node:stream'; -import busboy from 'busboy'; - -import { MultipartMessage } from '../messages.js'; - -export function parse(message: MultipartMessage): Promise<number> { - let stream = new Readable({ - read() { - for (let chunk of message.generateChunks()) { - this.push(chunk); - } - this.push(null); - }, - }); - - return new Promise((resolve, reject) => { - let start = performance.now(); - - let bb = busboy({ - headers: { 'content-type': `multipart/form-data; boundary=${message.boundary}` }, - limits: { fileSize: Infinity }, - }); - - bb.on('field', () => {}); - - bb.on('file', (_name, stream) => { - stream.resume(); - }); - - bb.on('error', reject); - - bb.on('close', () => { - resolve(performance.now() - start); - }); - - stream.pipe(bb); - }); -} diff --git a/packages/tar-parser/bench/parsers/fastify-busboy.ts b/packages/tar-parser/bench/parsers/fastify-busboy.ts deleted file mode 100644 index 7bb3cbdd962..00000000000 --- a/packages/tar-parser/bench/parsers/fastify-busboy.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Readable } from 'node:stream'; -import busboy from '@fastify/busboy'; - -import { MultipartMessage } from '../messages.js'; - -export function parse(message: MultipartMessage): Promise<number> { - let stream = new Readable({ - read() { - for (let chunk of message.generateChunks()) { - this.push(chunk); - } - this.push(null); - }, - }); - - return new Promise((resolve, reject) => { - let start = performance.now(); - - let bb = new busboy.Busboy({ - headers: { 'content-type': `multipart/form-data; boundary=${message.boundary}` }, - limits: { fileSize: Infinity }, - }); - - bb.on('field', () => {}); - - bb.on('file', (_name, stream) => { - stream.resume(); - }); - - bb.on('error', reject); - - bb.on('finish', () => { - resolve(performance.now() - start); - }); - - stream.pipe(bb); - }); -} diff --git a/packages/tar-parser/bench/parsers/multipart-parser.ts b/packages/tar-parser/bench/parsers/multipart-parser.ts deleted file mode 100644 index b3c7216ff7b..00000000000 --- a/packages/tar-parser/bench/parsers/multipart-parser.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { MultipartParser } from '@mjackson/multipart-parser'; - -import { MultipartMessage } from '../messages.js'; - -export async function parse(message: MultipartMessage): Promise<number> { - let start = performance.now(); - - await new MultipartParser(message.boundary).parse(message.generateChunks(), (_part) => { - // Do nothing - }); - - return performance.now() - start; -} diff --git a/packages/tar-parser/bench/parsers/multipasta.ts b/packages/tar-parser/bench/parsers/multipasta.ts deleted file mode 100644 index 37b0b2e5237..00000000000 --- a/packages/tar-parser/bench/parsers/multipasta.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as Multipasta from 'multipasta'; - -import { MultipartMessage } from '../messages.js'; - -export function parse(message: MultipartMessage): Promise<number> { - return new Promise((resolve, reject) => { - const start = performance.now(); - const parser = Multipasta.make({ - headers: { 'content-type': `multipart/form-data; boundary=${message.boundary}` }, - onDone() { - resolve(performance.now() - start); - }, - onError: reject, - onFile(_info) { - return (_chunk) => {}; - }, - onField() {}, - }); - for (const chunk of message.generateChunks()) { - parser.write(chunk); - } - parser.end(); - }); -} diff --git a/packages/tar-parser/bench/parsers/tar-parser.ts b/packages/tar-parser/bench/parsers/tar-parser.ts new file mode 100644 index 00000000000..f905e766aa4 --- /dev/null +++ b/packages/tar-parser/bench/parsers/tar-parser.ts @@ -0,0 +1,14 @@ +import { TarParser } from '@mjackson/tar-parser'; +import { openFile } from '@mjackson/lazy-file/fs'; + +export async function parse(filename: string): Promise<number> { + let stream = openFile(filename).stream().pipeThrough(new DecompressionStream('gzip')); + + let start = performance.now(); + + await new TarParser().parse(stream, (_file) => { + // Do nothing + }); + + return performance.now() - start; +} diff --git a/packages/tar-parser/bench/parsers/tar-stream.ts b/packages/tar-parser/bench/parsers/tar-stream.ts new file mode 100644 index 00000000000..1ca98ff885f --- /dev/null +++ b/packages/tar-parser/bench/parsers/tar-stream.ts @@ -0,0 +1,31 @@ +import * as fs from 'node:fs'; +import gunzip from 'gunzip-maybe'; +import tar from 'tar-stream'; + +export async function parse(filename: string): Promise<number> { + let stream = fs.createReadStream(filename).pipe(gunzip()); + + let start = performance.now(); + + await new Promise<void>((resolve, reject) => { + let extract = tar.extract(); + + extract.on('error', reject); + + extract.on('entry', function (_header, stream, next) { + stream.on('end', function () { + next(); // ready for next entry + }); + + stream.resume(); // just auto drain the stream + }); + + extract.on('finish', function () { + resolve(); + }); + + stream.pipe(extract); + }); + + return performance.now() - start; +} diff --git a/packages/tar-parser/bench/runner.ts b/packages/tar-parser/bench/runner.ts index 14f4739784c..f238dba19eb 100644 --- a/packages/tar-parser/bench/runner.ts +++ b/packages/tar-parser/bench/runner.ts @@ -1,21 +1,15 @@ import * as os from 'node:os'; import * as process from 'node:process'; -import * as messages from './messages.js'; -import * as busboy from './parsers/busboy.js'; -import * as fastifyBusboy from './parsers/fastify-busboy.js'; -import * as multipartParser from './parsers/multipart-parser.js'; -import * as multipasta from './parsers/multipasta.js'; - -const benchmarks = [ - { name: '1 small file', message: messages.oneSmallFile }, - { name: '1 large file', message: messages.oneLargeFile }, - { name: '100 small files', message: messages.oneHundredSmallFiles }, - { name: '5 large files', message: messages.fiveLargeFiles }, -]; +import { fixtures } from '../test/utils.js'; + +import * as tarParser from './parsers/tar-parser.js'; +import * as tarStream from './parsers/tar-stream.js'; + +const benchmarks = [{ name: 'lodash npm package', filename: fixtures.lodashNpmPackage }]; interface Parser { - parse(message: messages.MultipartMessage): Promise<number>; + parse(filename: string): Promise<number>; } async function runParserBenchmarks( @@ -27,7 +21,7 @@ async function runParserBenchmarks( for (let benchmark of benchmarks) { let measurements: number[] = []; for (let i = 0; i < times; ++i) { - measurements.push(await parser.parse(benchmark.message)); + measurements.push(await parser.parse(benchmark.filename)); } results[benchmark.name] = getMeanAndStdDev(measurements); @@ -52,17 +46,11 @@ interface BenchmarkResults { async function runBenchmarks(parserName?: string): Promise<BenchmarkResults> { let results: BenchmarkResults = {}; - if (parserName === 'multipart-parser' || parserName === undefined) { - results['multipart-parser'] = await runParserBenchmarks(multipartParser); - } - if (parserName === 'multipasta' || parserName === undefined) { - results['multipasta'] = await runParserBenchmarks(multipasta); + if (parserName === 'tar-parser' || parserName === undefined) { + results['tar-parser'] = await runParserBenchmarks(tarParser); } - if (parserName === 'busboy' || parserName === undefined) { - results.busboy = await runParserBenchmarks(busboy); - } - if (parserName === 'fastify-busboy' || parserName === undefined) { - results['@fastify/busboy'] = await runParserBenchmarks(fastifyBusboy); + if (parserName === 'tar-stream' || parserName === undefined) { + results['tar-stream'] = await runParserBenchmarks(tarStream); } return results; @@ -72,14 +60,7 @@ function printResults(results: BenchmarkResults) { console.log(`Platform: ${os.type()} (${os.release()})`); console.log(`CPU: ${os.cpus()[0].model}`); console.log(`Date: ${new Date().toLocaleString()}`); - - if (typeof Bun !== 'undefined') { - console.log(`Bun ${Bun.version}`); - } else if (typeof Deno !== 'undefined') { - console.log(`Deno ${Deno.version.deno}`); - } else { - console.log(`Node.js ${process.version}`); - } + console.log(`Node.js ${process.version}`); console.table(results); } diff --git a/packages/tar-parser/bench/utils.ts b/packages/tar-parser/bench/utils.ts deleted file mode 100644 index 7e433503a98..00000000000 --- a/packages/tar-parser/bench/utils.ts +++ /dev/null @@ -1,28 +0,0 @@ -export function concat(chunks: Uint8Array[]): Uint8Array { - if (chunks.length === 1) return chunks[0]; - - let length = 0; - for (let chunk of chunks) { - length += chunk.length; - } - - let result = new Uint8Array(length); - let offset = 0; - - for (let chunk of chunks) { - result.set(chunk, offset); - offset += chunk.length; - } - - return result; -} - -export function getRandomBytes(size: number): Uint8Array { - let chunks: Uint8Array[] = []; - - for (let i = 0; i < size; i += 65536) { - chunks.push(crypto.getRandomValues(new Uint8Array(Math.min(size - i, 65536)))); - } - - return concat(chunks); -} diff --git a/packages/tar-parser/package.json b/packages/tar-parser/package.json index b28faa59229..48c41089459 100644 --- a/packages/tar-parser/package.json +++ b/packages/tar-parser/package.json @@ -22,9 +22,12 @@ }, "devDependencies": { "@mjackson/lazy-file": "workspace:^", - "@types/node": "^20.14.10" + "@types/node": "^20.14.10", + "@types/tar-stream": "^3.1.3", + "typescript": "^5.6.3" }, "scripts": { + "bench": "node --import @swc-node/register/esm-register ./bench/runner.ts", "build": "tsc --outDir dist --project tsconfig.lib.json", "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", "prepare": "pnpm run build", diff --git a/packages/tar-parser/src/lib/tar.spec.ts b/packages/tar-parser/src/lib/tar.spec.ts index 12d5b67d326..bf9bbeb992a 100644 --- a/packages/tar-parser/src/lib/tar.spec.ts +++ b/packages/tar-parser/src/lib/tar.spec.ts @@ -1,23 +1,29 @@ import { describe, it } from 'node:test'; import * as assert from 'node:assert/strict'; -import { openFixture } from '../../test/utils.js'; +import { fixtures, readFixture } from '../../test/utils.js'; -import { TarParser } from './tar.js'; +import { TarHeader, TarParser } from './tar.js'; -function readFixture(name: string): ReadableStream<Uint8Array> { - let stream = openFixture(name).stream(); - return name.endsWith('.tgz') ? stream.pipeThrough(new DecompressionStream('gzip')) : stream; +async function bufferStream(stream: ReadableStream<Uint8Array>): Promise<string> { + let decoder = new TextDecoder(); + let string = ''; + + for await (let chunk of stream) { + string += decoder.decode(chunk, { stream: true }); + } + + string += decoder.decode(); + + return string; } describe('TarParser', () => { it('parses express-4.21.1.tgz', async () => { - let stream = readFixture('express-4.21.1.tgz'); let parser = new TarParser(); let entries: [string, number][] = []; - - await parser.parse(stream, (entry) => { + await parser.parse(readFixture(fixtures.expressNpmPackage), (entry) => { entries.push([entry.name, entry.size]); }); @@ -41,37 +47,448 @@ describe('TarParser', () => { ]); }); - it('parses react-18.0.0.tgz', async () => { - let stream = readFixture('react-18.0.0.tgz'); + it('parses fetch-proxy-0.1.0.tar.gz', async () => { let parser = new TarParser(); let entries: [string, number][] = []; + await parser.parse(readFixture(fixtures.fetchProxyGithubArchive), (entry) => { + entries.push([entry.name, entry.size]); + }); + + assert.equal(entries.length, 192); + }); - await parser.parse(stream, (entry) => { + it('parses lodash-4.17.21.tgz', async () => { + let parser = new TarParser(); + + let entries: [string, number][] = []; + await parser.parse(readFixture(fixtures.lodashNpmPackage), (entry) => { entries.push([entry.name, entry.size]); }); + assert.equal(entries.length, 1054); + }); +}); + +describe('tar-stream test cases', () => { + it('parses one-file.tar', async () => { + let parser = new TarParser(); + + let entries: [TarHeader, string][] = []; + await parser.parse(readFixture(fixtures.oneFile), async (entry) => { + entries.push([entry.header, await bufferStream(entry.body)]); + }); + + assert.deepEqual(entries, [ + [ + { + name: 'test.txt', + mode: 0o644, + uid: 501, + gid: 20, + size: 12, + mtime: 1387580181, + type: 'file', + linkname: null, + uname: 'maf', + gname: 'staff', + devmajor: 0, + devminor: 0, + pax: null, + }, + 'hello world\n', + ], + ]); + }); + + it('parses multi-file.tar', async () => { + let parser = new TarParser(); + + let entries: [TarHeader, string][] = []; + await parser.parse(readFixture(fixtures.multiFile), async (entry) => { + entries.push([entry.header, await bufferStream(entry.body)]); + }); + + assert.deepEqual(entries, [ + [ + { + name: 'file-1.txt', + mode: 0o644, + uid: 501, + gid: 20, + size: 12, + mtime: 1387580181, + type: 'file', + linkname: null, + uname: 'maf', + gname: 'staff', + devmajor: 0, + devminor: 0, + pax: null, + }, + 'i am file-1\n', + ], + [ + { + name: 'file-2.txt', + mode: 0o644, + uid: 501, + gid: 20, + size: 12, + mtime: 1387580181, + type: 'file', + linkname: null, + uname: 'maf', + gname: 'staff', + devmajor: 0, + devminor: 0, + pax: null, + }, + 'i am file-2\n', + ], + ]); + }); + + it('parses pax.tar', async () => { + let parser = new TarParser(); + + let entries: [TarHeader, string][] = []; + await parser.parse(readFixture(fixtures.pax), async (entry) => { + entries.push([entry.header, await bufferStream(entry.body)]); + }); + + assert.deepEqual(entries, [ + [ + { + name: 'pax.txt', + mode: 0o644, + uid: 501, + gid: 20, + size: 12, + mtime: 1387580181, + type: 'file', + linkname: null, + uname: 'maf', + gname: 'staff', + devmajor: 0, + devminor: 0, + pax: { + path: 'pax.txt', + special: 'sauce', + }, + }, + 'hello world\n', + ], + ]); + }); + + it('parses types.tar', async () => { + let parser = new TarParser(); + + let headers: TarHeader[] = []; + await parser.parse(readFixture(fixtures.types), async (entry) => { + headers.push(entry.header); + }); + + assert.deepEqual(headers, [ + { + name: 'directory', + mode: 0o755, + uid: 501, + gid: 20, + size: 0, + mtime: 1387580181, + type: 'directory', + linkname: null, + uname: 'maf', + gname: 'staff', + devmajor: 0, + devminor: 0, + pax: null, + }, + { + name: 'directory-link', + mode: 0o755, + uid: 501, + gid: 20, + size: 0, + mtime: 1387580181, + type: 'symlink', + linkname: 'directory', + uname: 'maf', + gname: 'staff', + devmajor: 0, + devminor: 0, + pax: null, + }, + ]); + }); + + it('parses long-name.tar', async () => { + let parser = new TarParser(); + + let entries: [TarHeader, string][] = []; + await parser.parse(readFixture(fixtures.longName), async (entry) => { + entries.push([entry.header, await bufferStream(entry.body)]); + }); + + assert.deepEqual(entries, [ + [ + { + name: 'my/file/is/longer/than/100/characters/and/should/use/the/prefix/header/foobarbaz/foobarbaz/foobarbaz/foobarbaz/foobarbaz/foobarbaz/filename.txt', + mode: 0o644, + uid: 501, + gid: 20, + size: 16, + mtime: 1387580181, + type: 'file', + linkname: null, + uname: 'maf', + gname: 'staff', + devmajor: 0, + devminor: 0, + pax: null, + }, + 'hello long name\n', + ], + ]); + }); + + it('parses unicode-bsd.tar', async () => { + let parser = new TarParser(); + + let headers: TarHeader[] = []; + await parser.parse(readFixture(fixtures.unicodeBsd), async (entry) => { + headers.push(entry.header); + }); + + assert.deepEqual(headers, [ + { + name: 'høllø.txt', + mode: 0o644, + uid: 501, + gid: 20, + size: 4, + mtime: 1387588646, + type: 'file', + linkname: null, + uname: 'maf', + gname: 'staff', + devmajor: 0, + devminor: 0, + pax: { + 'SCHILY.dev': '16777217', + 'SCHILY.ino': '3599143', + 'SCHILY.nlink': '1', + atime: '1387589077', + ctime: '1387588646', + path: 'høllø.txt', + }, + }, + ]); + }); + + it('parses unicode.tar', async () => { + let parser = new TarParser(); + + let headers: TarHeader[] = []; + await parser.parse(readFixture(fixtures.unicode), async (entry) => { + headers.push(entry.header); + }); + + assert.deepEqual(headers, [ + { + name: 'høstål.txt', + mode: 0o644, + uid: 501, + gid: 20, + size: 8, + mtime: 1387580181, + type: 'file', + linkname: null, + uname: 'maf', + gname: 'staff', + devmajor: 0, + devminor: 0, + pax: { path: 'høstål.txt' }, + }, + ]); + }); + + it('parses name-is-100.tar', async () => { + let parser = new TarParser(); + + let entries: [number, string][] = []; + await parser.parse(readFixture(fixtures.nameIs100), async (entry) => { + entries.push([entry.header.name.length, await bufferStream(entry.body)]); + }); + + assert.deepEqual(entries, [[100, 'hello\n']]); + }); + + it('parses space.tar', async () => { + let parser = new TarParser(); + + let entries: [TarHeader, string][] = []; + await parser.parse(readFixture(fixtures.space), async (entry) => { + entries.push([entry.header, await bufferStream(entry.body)]); + }); + + assert.equal(entries.length, 4); + }); + + it('parses gnu-long-path.tar', async () => { + let parser = new TarParser(); + + let entries: [TarHeader, string][] = []; + await parser.parse(readFixture(fixtures.gnuLongPath), async (entry) => { + entries.push([entry.header, await bufferStream(entry.body)]); + }); + + assert.equal(entries.length, 1); + }); + + it('parses base-256-uid-gid.tar', async () => { + let parser = new TarParser(); + + let headers: TarHeader[] = []; + await parser.parse(readFixture(fixtures.base256UidGid), async (entry) => { + headers.push(entry.header); + }); + + assert.equal(headers.length, 1); + assert.equal(headers[0].uid, 116435139); + assert.equal(headers[0].gid, 1876110778); + }); + + it('parses base-256-size.tar', async () => { + let parser = new TarParser(); + + let headers: TarHeader[] = []; + await parser.parse(readFixture(fixtures.base256Size), async (entry) => { + headers.push(entry.header); + }); + + assert.deepEqual(headers, [ + { + name: 'test.txt', + mode: 0o644, + uid: 501, + gid: 20, + size: 12, + mtime: 1387580181, + type: 'file', + linkname: null, + uname: 'maf', + gname: 'staff', + devmajor: 0, + devminor: 0, + pax: null, + }, + ]); + }); + + it('parses latin1.tar', async () => { + let parser = new TarParser({ filenameEncoding: 'latin1' }); + + let entries: [TarHeader, string][] = []; + await parser.parse(readFixture(fixtures.latin1), async (entry) => { + entries.push([entry.header, await bufferStream(entry.body)]); + }); + + assert.deepEqual(entries, [ + [ + { + name: "En français, s'il vous plaît?.txt", + mode: 0o644, + uid: 0, + gid: 0, + size: 14, + mtime: 1495941034, + type: 'file', + linkname: null, + uname: 'root', + gname: 'root', + devmajor: 0, + devminor: 0, + pax: null, + }, + 'Hello, world!\n', + ], + ]); + }); + + it('throws when parsing incomplete.tar', async () => { + let parser = new TarParser(); + + await assert.rejects( + async () => { + await parser.parse(readFixture(fixtures.incomplete), () => {}); + }, + { + name: 'TarParseError', + message: 'Unexpected end of archive', + }, + ); + }); + + it('parses gnu.tar', async () => { + let parser = new TarParser(); + + let entries: [TarHeader, string][] = []; + await parser.parse(readFixture(fixtures.gnu), async (entry) => { + entries.push([entry.header, await bufferStream(entry.body)]); + }); + + assert.deepEqual(entries, [ + [ + { + name: 'test.txt', + mode: 0o644, + uid: 12345, + gid: 67890, + size: 14, + mtime: 1559239869, + type: 'file', + linkname: null, + uname: 'myuser', + gname: 'mygroup', + devmajor: 0, + devminor: 0, + pax: null, + }, + 'Hello, world!\n', + ], + ]); + }); + + it('parses gnu-incremental.tar', async () => { + let parser = new TarParser(); + + let entries: [TarHeader, string][] = []; + await parser.parse(readFixture(fixtures.gnuIncremental), async (entry) => { + entries.push([entry.header, await bufferStream(entry.body)]); + }); + assert.deepEqual(entries, [ - ['package/LICENSE', 1086], - ['package/index.js', 190], - ['package/jsx-dev-runtime.js', 222], - ['package/jsx-runtime.js', 214], - ['package/cjs/react-jsx-dev-runtime.development.js', 41115], - ['package/cjs/react-jsx-dev-runtime.production.min.js', 343], - ['package/cjs/react-jsx-dev-runtime.profiling.min.js', 342], - ['package/cjs/react-jsx-runtime.development.js', 41714], - ['package/cjs/react-jsx-runtime.production.min.js', 859], - ['package/cjs/react-jsx-runtime.profiling.min.js', 858], - ['package/cjs/react.development.js', 87561], - ['package/umd/react.development.js', 109891], - ['package/cjs/react.production.min.js', 6932], - ['package/umd/react.production.min.js', 10756], - ['package/umd/react.profiling.min.js', 10755], - ['package/cjs/react.shared-subset.development.js', 501], - ['package/react.shared-subset.js', 218], - ['package/cjs/react.shared-subset.production.min.js', 351], - ['package/package.json', 999], - ['package/README.md', 737], + [ + { + name: 'test.txt', + mode: 0o644, + uid: 12345, + gid: 67890, + size: 14, + mtime: 1559239869, + type: 'file', + linkname: null, + uname: 'myuser', + gname: 'mygroup', + devmajor: 0, + devminor: 0, + pax: null, + }, + 'Hello, world!\n', + ], ]); }); }); diff --git a/packages/tar-parser/src/lib/tar.ts b/packages/tar-parser/src/lib/tar.ts index e1554435f36..6ec91f82b94 100644 --- a/packages/tar-parser/src/lib/tar.ts +++ b/packages/tar-parser/src/lib/tar.ts @@ -9,48 +9,70 @@ export class TarParseError extends Error { export interface TarHeader { name: string; - mode: number; - uid: number; - gid: number; + mode: number | null; + uid: number | null; + gid: number | null; size: number; - mtime: number; - checksum: number; + mtime: number | null; type: string; - linkname: string; + linkname: string | null; uname: string; gname: string; - devmajor: number; - devminor: number; - prefix: string; + devmajor: number | null; + devminor: number | null; + pax: Record<string, string> | null; } const TarFileTypes: Record<string, string> = { '0': 'file', '1': 'link', '2': 'symlink', - '3': 'character', - '4': 'block', + '3': 'character-device', + '4': 'block-device', '5': 'directory', '6': 'fifo', - '7': 'contiguous', + '7': 'contiguous-file', + '27': 'gnu-long-link-path', + '28': 'gnu-long-path', + '30': 'gnu-long-path', + '55': 'pax-global-header', + '72': 'pax-header', }; -export function parseTarHeader(buffer: Uint8Array): TarHeader { - if (buffer.length !== TarBlockSize) { - throw new TarParseError('Invalid tar header size'); - } +const ZeroOffset = '0'.charCodeAt(0); +const UstarMagic = new Uint8Array([0x75, 0x73, 0x74, 0x61, 0x72, 0x00]); // "ustar\0" +const UstarVersion = new Uint8Array([ZeroOffset, ZeroOffset]); // "00" +const GnuMagic = new Uint8Array([0x75, 0x73, 0x74, 0x61, 0x72, 0x20]); // "ustar " +const GnuVersion = new Uint8Array([0x20, 0x00]); // " \0" - let decoder = new TextDecoder('ascii'); +export interface ParseTarHeaderOptions { + /** + * Set false to disallow unknown header formats. Defaults to true. + */ + allowUnknownFormat?: boolean; + /** + * The label (encoding) for filenames. Defaults to 'utf-8'. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Encoding_API/Encodings) + */ + filenameEncoding?: string; +} - function getString(offset: number, size: number) { - return decoder.decode(buffer.subarray(offset, offset + size)).replace(/\0.*$/, ''); +/** + * Parses a tar header block. + * @param block The tar header block + * @param options + * @returns The parsed tar header + */ +export function parseTarHeader(block: Uint8Array, options?: ParseTarHeaderOptions): TarHeader { + if (block.length !== TarBlockSize) { + throw new TarParseError('Invalid tar header size'); } - function getOctal(offset: number, size: number) { - return parseInt(getString(offset, size), 8); - } + let allowUnknownFormat = options?.allowUnknownFormat ?? true; + let filenameEncoding = options?.filenameEncoding ?? 'utf-8'; - // UStar header format + // Tar header format // Offset Size Field // 0 100 Filename // 100 8 File mode (octal) @@ -59,63 +81,151 @@ export function parseTarHeader(buffer: Uint8Array): TarHeader { // 124 12 File size in bytes (octal) // 136 12 Last modification time (octal) // 148 8 Checksum for header block (octal) - // 156 1 Link indicator (file type) + // 156 1 Type flag // 157 100 Name of linked file - // 257 6 UStar indicator "ustar\0" - // 263 2 UStar version "00" + // 257 6 Magic string "ustar\0" or "ustar " + // 263 2 Version "00" or " \0" // 265 32 Owner username // 297 32 Owner groupname // 329 8 Device major number (octal) // 337 8 Device minor number (octal) - // 345 155 Filename prefix + // 345 155 Filename prefix (ustar only) - let checksum = getOctal(148, 8); - if (checksum !== computeHeaderChecksum(buffer)) { - throw new TarParseError('Invalid tar header checksum'); + let checksum = getOctal(block, 148, 8); + if (checksum !== computeChecksum(block)) { + throw new TarParseError( + 'Invalid tar header. Maybe the tar is corrupted or needs to be gunzipped?', + ); } - let ustarIndicator = getString(257, 6); - if (ustarIndicator !== 'ustar') { - throw new TarParseError('Invalid tar header, must be ustar'); + let typeFlag = block[156] === 0 ? 0 : block[156] - ZeroOffset; + let header: TarHeader = { + name: getString(block, 0, 100, filenameEncoding), + mode: getOctal(block, 100, 8), + uid: getOctal(block, 108, 8), + gid: getOctal(block, 116, 8), + size: getOctal(block, 124, 12) ?? 0, + mtime: getOctal(block, 136, 12), + type: TarFileTypes[typeFlag] ?? 'unknown', + linkname: block[157] === 0 ? null : getString(block, 157, 100, filenameEncoding), + uname: getString(block, 265, 32), + gname: getString(block, 297, 32), + devmajor: getOctal(block, 329, 8), + devminor: getOctal(block, 337, 8), + pax: null, + }; + + let magic = block.subarray(257, 263); + let version = block.subarray(263, 265); + if (buffersEqual(magic, UstarMagic) && buffersEqual(version, UstarVersion)) { + // UStar (posix) format + if (block[345] !== 0) { + let prefix = getString(block, 345, 155); + header.name = prefix + '/' + header.name; + } + } else if (buffersEqual(magic, GnuMagic) && buffersEqual(version, GnuVersion)) { + // GNU format + } else if (!allowUnknownFormat) { + throw new TarParseError('Invalid tar header, unknown format'); } - let linkIndicator = String.fromCharCode(buffer[156]); - - return { - name: getString(0, 100), - mode: getOctal(100, 8), - uid: getOctal(108, 8), - gid: getOctal(116, 8), - size: getOctal(124, 12), - mtime: getOctal(136, 12), - checksum, - type: TarFileTypes[linkIndicator] || 'unknown', - linkname: getString(157, 100), - uname: getString(265, 32), - gname: getString(297, 32), - devmajor: getOctal(329, 8), - devminor: getOctal(337, 8), - prefix: getString(345, 155), - }; + return header; +} + +function buffersEqual(a: Uint8Array, b: Uint8Array): boolean { + if (a.length !== b.length) return false; + for (let i = 0; i < a.length; i++) { + if (a[i] !== b[i]) return false; + } + return true; +} + +function indexOf(buffer: Uint8Array, value: number, offset: number, end: number): number { + for (; offset < end; offset++) { + if (buffer[offset] === value) return offset; + } + return end; } -function computeHeaderChecksum(buffer: Uint8Array): number { +const Utf8Decoder = new TextDecoder(); + +function getString(buffer: Uint8Array, offset: number, size: number, label = 'utf-8') { + return new TextDecoder(label).decode( + buffer.subarray(offset, indexOf(buffer, 0, offset, offset + size)), + ); +} + +function getOctal(buffer: Uint8Array, offset: number, size: number) { + let value = buffer.subarray(offset, offset + size); + offset = 0; + + if (value[offset] & 0x80) return parse256(value); + + // Older versions of tar can prefix with spaces + while (offset < value.length && value[offset] === 32) offset++; + let end = clamp(indexOf(value, 32, offset, value.length), value.length, value.length); + while (offset < end && value[offset] === 0) offset++; + if (end === offset) return 0; + + return parseInt(Utf8Decoder.decode(value.subarray(offset, end)), 8); +} + +/* Copied from the tar-stream repo who copied it from the node-tar repo. + */ +function parse256(buf: Uint8Array): number | null { + // first byte MUST be either 80 or FF + // 80 for positive, FF for 2's comp + let positive; + if (buf[0] === 0x80) positive = true; + else if (buf[0] === 0xff) positive = false; + else return null; + + // build up a base-256 tuple from the least sig to the highest + let tuple = []; + let i; + for (i = buf.length - 1; i > 0; i--) { + const byte = buf[i]; + if (positive) tuple.push(byte); + else tuple.push(0xff - byte); + } + let sum = 0; - for (let i = 0; i < 512; i++) { - sum += i >= 148 && i < 156 ? 32 : buffer[i]; + let len = tuple.length; + for (i = 0; i < len; i++) { + sum += tuple[i] * Math.pow(256, i); } + return positive ? sum : -1 * sum; +} + +function clamp(index: number, len: number, defaultValue: number): number { + if (typeof index !== 'number') return defaultValue; + index = ~~index; // Coerce to integer. + if (index >= len) return len; + if (index >= 0) return index; + index += len; + if (index >= 0) return index; + return 0; +} + +function computeChecksum(block: Uint8Array): number { + let sum = 8 * 32; + for (let i = 0; i < 148; i++) sum += block[i]; + for (let i = 156; i < 512; i++) sum += block[i]; return sum; } const enum TarParserState { Start, Header, + AfterHeader, Body, AfterBody, Done, } +export type TarParserOptions = ParseTarHeaderOptions; + /** * A parser for tar archives. */ @@ -125,6 +235,20 @@ export class TarParser { #bodyController: ReadableStreamDefaultController<Uint8Array> | null = null; #bodyWritten = 0; #bodySize = 0; // The declared size of the current body + #header: TarHeader | null = null; + #longHeader = false; + #gnuLongPath: string | null = null; + #gnuLongLinkPath: string | null = null; + #paxGlobal: Record<string, string> | null = null; + #pax: Record<string, string> | null = null; + + #allowUnknownFormat: boolean; + #filenameEncoding: string; + + constructor(options?: TarParserOptions) { + this.#allowUnknownFormat = options?.allowUnknownFormat ?? true; + this.#filenameEncoding = options?.filenameEncoding ?? 'utf-8'; + } /** * Parse a stream/buffer tar archive and call the given handler for each entry it contains. @@ -162,7 +286,10 @@ export class TarParser { throw new TypeError('Cannot parse tar archive; expected a stream or buffer'); } - if (this.#state !== TarParserState.Done) { + if ( + this.#state !== TarParserState.Done && + !(this.#buffer === null || this.#buffer.length === 0) + ) { throw new TarParseError('Unexpected end of archive'); } @@ -174,6 +301,12 @@ export class TarParser { this.#buffer = null; this.#bodyController = null; this.#bodySize = 0; + this.#header = null; + this.#longHeader = false; + this.#gnuLongPath = null; + this.#gnuLongLinkPath = null; + this.#paxGlobal = null; + this.#pax = null; } #write(chunk: Uint8Array, handler: (entry: TarEntry) => void): void { @@ -197,55 +330,138 @@ export class TarParser { if (this.#state === TarParserState.Body) { let remaining = this.#bodySize - this.#bodyWritten; - if (chunk.length - index < remaining) { + if (chunkLength - index < remaining) { this.#writeBody(index === 0 ? chunk : chunk.subarray(index)); break; } this.#writeBody(chunk.subarray(index, index + remaining)); - index += remaining; - this.#closeBody(); + index += remaining; + this.#state = TarParserState.AfterBody; } if (this.#state === TarParserState.AfterBody) { - let padding = TarBlockSize - (this.#bodySize % TarBlockSize); + let padding = overflow(this.#bodySize); - if (chunk.length - index < padding + 2 * TarBlockSize) { + if (chunkLength - index < padding) { this.#buffer = chunk.subarray(index); break; } - index += padding; // Skip padding - - // Check for end of archive - if (isZeroBlock(chunk.subarray(index, index + TarBlockSize))) { - if (isZeroBlock(chunk.subarray(index + TarBlockSize, index + 2 * TarBlockSize))) { - this.#state = TarParserState.Done; - break; - } else { - throw new TarParseError('Invalid end of archive'); - } - } + index += padding; this.#state = TarParserState.Header; } - if (this.#state === TarParserState.Header || this.#state === TarParserState.Start) { - if (chunk.length - index < TarBlockSize) { + if (this.#state === TarParserState.Start || this.#state === TarParserState.Header) { + if (chunkLength - index < TarBlockSize) { this.#buffer = chunk.subarray(index); break; } - let header = parseTarHeader(chunk.subarray(index, index + TarBlockSize)); + let block = chunk.subarray(index, index + TarBlockSize); index += TarBlockSize; - this.#bodySize = header.size; + if (isZeroBlock(block)) { + this.#header = null; + } else { + this.#header = parseTarHeader(block, { + allowUnknownFormat: this.#allowUnknownFormat, + filenameEncoding: this.#filenameEncoding, + }); + + switch (this.#header.type) { + case 'gnu-long-path': + case 'gnu-long-link-path': + case 'pax-global-header': + case 'pax-header': + this.#longHeader = true; + break; + default: + if (this.#gnuLongPath) { + this.#header.name = this.#gnuLongPath; + this.#gnuLongPath = null; + } + + if (this.#gnuLongLinkPath) { + this.#header.linkname = this.#gnuLongLinkPath; + this.#gnuLongLinkPath = null; + } + + if (this.#pax) { + if (this.#pax.path) this.#header.name = this.#pax.path; + if (this.#pax.linkpath) this.#header.linkname = this.#pax.linkpath; + if (this.#pax.size) this.#header.size = parseInt(this.#pax.size, 10); + this.#header.pax = this.#pax; + this.#pax = null; + } + } + } + + this.#state = TarParserState.AfterHeader; + } + + if (this.#state === TarParserState.AfterHeader) { + // Either we are at the end of the archive ... + if (this.#header === null) { + if (chunkLength - index < TarBlockSize) { + this.#buffer = chunk.subarray(index); + break; + } + + let nextBlock = chunk.subarray(index, index + TarBlockSize); + if (isZeroBlock(nextBlock)) { + this.#state = TarParserState.Done; + break; + } else { + throw new TarParseError('Invalid end of archive marker'); + } + } + + // ... or we found a long header that we need to finish parsing ... + if (this.#longHeader) { + let padding = overflow(this.#header.size); + + if (chunkLength - index < this.#header.size + padding) { + this.#buffer = chunk.subarray(index); + break; + } + + let buffer = chunk.subarray(index, index + this.#header.size); + index += this.#header.size + padding; + + switch (this.#header.type) { + case 'gnu-long-path': + this.#gnuLongPath = decodeLongPath(buffer); + break; + case 'gnu-long-link-path': + this.#gnuLongLinkPath = decodeLongPath(buffer); + break; + case 'pax-global-header': + this.#paxGlobal = decodePax(buffer); + break; + case 'pax-header': + this.#pax = + this.#paxGlobal === null + ? decodePax(buffer) + : Object.assign({}, this.#paxGlobal, decodePax(buffer)); + break; + } + + this.#longHeader = false; + + this.#state = TarParserState.Header; + continue; + } + + // ... or it's the beginning of a new entry. + this.#bodySize = this.#header.size; let entry = new TarEntry( - header, + this.#header, new ReadableStream({ start: (controller) => { this.#bodyController = controller; @@ -288,6 +504,37 @@ function isZeroBlock(buffer: Uint8Array): boolean { return buffer.every((byte) => byte === 0); } +function decodeLongPath(buffer: Uint8Array): string { + return Utf8Decoder.decode(buffer); +} + +function decodePax(buffer: Uint8Array): Record<string, string> { + let pax: Record<string, string> = {}; + + while (buffer.length) { + let i = 0; + while (i < buffer.length && buffer[i] !== 32) i++; + + let len = parseInt(Utf8Decoder.decode(buffer.subarray(0, i)), 10); + if (!len) break; + + let val = Utf8Decoder.decode(buffer.subarray(i + 1, len - 1)); + let eq = val.indexOf('='); + if (eq === -1) break; + + pax[val.slice(0, eq)] = val.slice(eq + 1); + + buffer = buffer.subarray(len); + } + + return pax; +} + +function overflow(size: number): number { + size &= 511; + return size && 512 - size; +} + /** * An entry in a tar archive. */ diff --git a/packages/tar-parser/src/tar-parser.ts b/packages/tar-parser/src/tar-parser.ts index 1a021de3662..b363fdd9f95 100644 --- a/packages/tar-parser/src/tar-parser.ts +++ b/packages/tar-parser/src/tar-parser.ts @@ -1 +1,9 @@ -export { TarParseError, type TarHeader, parseTarHeader, TarParser, TarEntry } from './lib/tar.js'; +export { + TarParseError, + type TarHeader, + type ParseTarHeaderOptions, + parseTarHeader, + type TarParserOptions, + TarParser, + TarEntry, +} from './lib/tar.js'; diff --git a/packages/tar-parser/test/fixtures/base-256-size.tar b/packages/tar-parser/test/fixtures/base-256-size.tar new file mode 100644 index 0000000000000000000000000000000000000000..f6427736e533a2902873a4172030820c85f08b73 GIT binary patch literal 2048 zcmXR(EiTb3sVHHfAuup7Ff%bxU;xtQW~N};zzE21K-kG+Xk=t+YG`6=Vq~gdU}$J& zYz$O~kf$B1w74X(2<Wuj#5BB?0F|ZTQvviG5I{T!qK62`NX^N~S18Xf%1PlGB2FH4 S=4c3vhQMeDjD`ReLI42oQ5aAF literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/base-256-uid-gid.tar b/packages/tar-parser/test/fixtures/base-256-uid-gid.tar new file mode 100644 index 0000000000000000000000000000000000000000..6e3d6e3a5f4224e7e01680b54b5c7ec0d2a5dd9b GIT binary patch literal 10240 zcmeH|&5qkP5P*H^VV^?Kxsom0>rDcrKz7#!0wh6@%`IpOni|XWN}|f2q;8R-kJD%9 zwU5vj=_6!@6eVTR1$tRD2kK&r^Z(5Z)iHj{D#(vowzCI%7Wiz|>)G$<|C@jQ_=|q! z-`SsZj?Zej+02UNX0<LZHtUPkY*7@O)nb+`Q18JXs|{00^5Aj4(g44nB}v+{2GS=< zDw@U`wyPoimX1Gw(n7W*S>+e`#-Em;xe}e}CC`IRa?K1&u4G*UC!zN02iZV}6GmPR z#&r70d|nB2u)CbgX1-?}c2eHXhuGP%w`A5Fq(VE&agyZ=faLO|Ffqy!1y<Gfc&`C= zP7@VBxtbJoQVS#1X>@E(ol6hXy5ka0{zJMs84eM4w$h{T`*Zu(%I89B3wrd{FyR_d z3T;M4xUQZqrS97?hAd$(S`qql$FR)J#Je}0q-#JMVwuksXlWG(J#S?RKawEVhrp); zwI@B2B~#@cwERHn4LpwCW#2>}@in$VNp!AVgVQk>X-}o0QfxD&@V%&E`?G<T29xrB z=SBdfJrOq$zQiQ?p&t;;RwKWcva~h4feQbt(<PXX0PRf&oE#ZtVaU0J57*E^TVgc= z+cC@_<5IbPykF!+kuL%dS9ZhHEkSvYf{CcMuoJ3uk|pj@5sbL3r6T9vVinFoZ!)7; zt2?Zg79hoFX!mGTKrwBn8(R$bcywAR+qxE_%{o61Chj=nvNcNVGF}4<Wt@+x-cgbr zEeQp`SLdh?VhC4Es`jq>-jj<7EH6`lN%R#^c>~KM(~W2$;|JiLCs{8;B@L?t&#;4{ zt@`wq{oRCP&<L)i5&k|yGRx7g0>({dq^v!2*TJC~3NJ3(^$v^2W4td`Ed8xOs)LcO zYOz1jjYXW6Bsw1_AKD7*m`o3C3u%7$bdf*8#D;m>W1~sWPjgB;8_Mll7GB?MpIyJ) z=1mz6UOd0rzPj0l*VoV9ZeP8<A=hsD(_1)wl&YL~A8y)U)2|0$Bm0G^*)ON?zr<^O z`X9+#ZmjYj2}HiPt-J799n^5J`;S04!H=xLertbip^=84EH2mJL>N%a-C0BCwcxnt z4%p?*b+*c`YG(2M?9<s-`Z0}ZMFNpPBoGNi0+B!@5D7#Akw7F62}A;sKqL?eL;{gO aBoGNi0+B!@5D7#Akw7F62}A<_6M@eVmGr{^ literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/fetch-proxy-0.1.0.tar.gz b/packages/tar-parser/test/fixtures/fetch-proxy-0.1.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a9d41e5e0162f232e0cb658143521ce22337eb43 GIT binary patch literal 97606 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 Xs6!p<P=`9y;WoqHs(ZSV0Qd(08495t literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/gnu-incremental.tar b/packages/tar-parser/test/fixtures/gnu-incremental.tar new file mode 100644 index 0000000000000000000000000000000000000000..0e62cfea528fabb0abb5a8dd1c4202114feee6bd GIT binary patch literal 10240 zcmeIuK?=e!5QX8aJw@D$Owws`1+O6(+_Y5E6z%OTC<Q59xG3HHvq~OAGV_(xmvea) zvth|pLDh&<BGDP~q8j{k|CS5JRT@=X@Ub@Hw2skO*>I-$>7g&zY^`a>p-*{^7l(Gd z=Wci`^0nZzkk{zq&vI-1JLQ+uG~LNQyWHH4hn<GtTLch5009ILKmY**5I_I{1Q0*~ g0R#|0009ILKmY**5I_I{1Q0*~0R#|00D->+-nl;>YXATM literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/gnu-long-path.tar b/packages/tar-parser/test/fixtures/gnu-long-path.tar new file mode 100644 index 0000000000000000000000000000000000000000..e3ecd9510ecc3e016157370fc839227d33a52886 GIT binary patch literal 7680 zcmeHMZExJh5!Pq@iq+K!d9jYX^J}3%P}17{P`EJ=f5-=&T=2-Hv=WbGc1gW7y8iY) zvu}L4yEqNt0I5sC;Bj|nW@qM^*_m||NAb7ss`B!kC~pov&oejA!JhYg@$$Kwqa_FP z#p30w7YFR!=h@DXYpa?>GIk)Vsu|7<zdkiTT>XdnDyxjoZs*Zr5iMTC8Lw4b*6Wyt z|GBQRw%{rjrD$e#lHMeje0Hs>ayVVfYW=T7W--4{)^)*&!Hj4Op(yLNiLTWj#w1_V zMt=|gQ&7J`K+_w~=)HLU>gBV8#j_WS`K#wIU(Xi@^XJbNuU{Xq`S0P0FFgKlk^FMS zPMPFCwL<bR$W<^sq~SVguKE-79ZbJDJT!SB;`enW8>0RBkg-XbtoekUFiHn?69)7h z9Ak#D=Aq_Q&S-?4o}RLxEi;~rl4pUQKVz#zahi@KuZtw*Vf;}e^YJ{IU0kat@#QfK zg6WCoF(s~(TP~HT%DzZD6dXH=c7Pp0=)?=1XrZ*R-Om|wbSEsBNB9ej$c(F0in_64 z!@Mn1`e5Ny+kn`KoP}23-g3Qzp4#lIuUK!oBWG|#)5@|xYqz_xZ}QD;QndUVJJ84n zFP^qQ3zSUZm|Vf2N%l8U@DC4V8U{bS{qD^_-bU*THVWD%|1&w1Xw0M8f)3P?stW-( zF3VsV<)Ub~?CD#;dHqcra=Z0-sh-AB!&MXNbv*%25Y(rssF7j~<B@;%K_J$i-_7Hw z$0S-OO?n03{3)J}R`*rhOwZ>Rqj|fH@o0y|2%G4fokDZxrZj4*chw!2e+7b}$!09O zL-aCwvZagLne%N*I<RnH+p&A&nEhC_MOFq46AfE&R*IAp@S3ZnVel1aumv2(v$LK~ z1dD7JD56W8)jc$J*znXF*4vretO0xGoCu#DX#h<PJRvHx3><|8h)WSenTD1uvYCb^ z;MR%I0p3HNLmg?8YxaHn<eh$*kQ(!NQ)bx#;@t5fRNAfO4n|9qEKfX=yjv-}^GG0n z-M`PnK>xtXz+iZ`=-f|R>E^8=c%ihX`aDR<Utr;;_j7QO!=AEWKcn%g9zXk&F>O8< zA0waZMI#6Dl8j$hqHF+~oIO7FR3=k+Pp*t3dqK2v*0)ItehRIxNRb#6#M7r(E{|E} zXc$8jloi7wWp_`W;d1I6nXW?T3oO0HG0&Rhh9gEeLPX;8TA5h6qk%G`8Oe`XC2`1P ziREe)2Dh>;3hZDz7yef;f^p5ZG@>^8B!kvGZ7M0aqSLHXIo)NWAlfzy^yw_KZ3vjf zszXsDxjwU9OhUSf@=Cr<kUcxuJySEL?u5=ugF%Lz05k`-><><c-wFfPdXR`}K{p4z zq(D(;IM7ky$?0Q6OG7&evnus;_&p-S$WE$tQV#cqfx$v&nnBdRUtPmX(G7o4ArzWM z1urkDLc-ZKC)klyeT}gPK18Ue`tIj7M?NW2>wjN8bi-Ta!x`#>Zd!BP4IIR@sR1aw zf__`K3q>7>Om5#DPo~14UJ)Aq?2KhbwIPMH#<5ml4AMV^F?X7{V|*FKQy<MGzi)gz z6L1LRnakB5L)4-$t*Rc^ReF^?Hc9=MR(a0(%v5anN~=fJpc-21ngprc#RReQ`F~4L zuY?-fFAk8VGM%byZ;aeqZRf1IZ&Z>riq9>HsF$grV>PV%_Yd#CkLpCCwg8_&Ms~qv z=vn6mC*!D&Y#qDbjPMNHc%EHAR`74q$P;<r5kDKqTYL2pLaE+U_$)%}`^B-_+H3}# zxVX{fZkJ%OpN^B$$}+e4lHb1Rp`UW5kD0;D&afG*_{GS<xuK|KNz@?P*s4X9g<~S) zx7vJG@BiIEJNkd5QA_saMVd*Tx+>|F1}>o?KGG|m-ms=(igR|S+YgD5xvS(26N-tF zwF)&AQeIL%=r}RCZPbh4crg9x;DAEH(<HstLpLzz7j}ZU&>3W--|lvN#lX&RNFhhq z=|j!aoFBf99~>52#k`7ey43Be5Q=U@T>G+WMUk<zTBCkILv7Ol<+$x<z=FzTBau4o z`0L1i%qn!nD_p;5R-|27+1e-I=~cxhZ>6jxZb2%h$5qW!kqe$p=t6<tqa9qBD;1xD zn|s_xpnh^r^SN9zz)p+^EpgM?=1A!Vo+^6#i}JNu+p!v15y$S9?NB@#PMzJfWN$VW zfK00cL!gtw<;}f20DQZYbuE`W>VJzQN2|qsQj)GEev24GI99~t<5LE4`dfF{vsaOG zOh1Jm69BSO0$sxcoqs!`vkSD#v?_azad#V}8-JP<mr!#%*c>6XK6aWsu7^7ixK;XX zuZ`lRJX@B&eI_UiM2=bFqwZYtH2}^g=zT8HAYK6aCUi)Q(8o7g>fYrRF=`#7bAftg zapCPsL`SVJ3YY5ZRu=4(%E%$jvtLa^ntT2ljl`+#E_FUSDQs}JV{B<^y_RCL+ZHZc zzQw<*c7?ECpY-d{G4JtG+=OB1B#t}!*qUsJ6_=r~4yBs|3IN}dfjbbPnL(<~bb_}u zK5>M;rPOxCmj&Xm$DzsZq)Z+nq4XPcQ=OGnbd8IFFkp6zw9;j2Q<<S27bQW@L!7+t zJ{*+Jm+JW9sm9XATni;_b5%*gy#enz?pZ_=nc+xZJR1)q^Ly|43+nweT?(IYT)Pze yB<RWDqPHAC+qW1~fy0}D#YxvD5{pTJ>$_47F3;@{JQn=r!y6cIbNG4wGvq&F`xTi0 literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/gnu.tar b/packages/tar-parser/test/fixtures/gnu.tar new file mode 100644 index 0000000000000000000000000000000000000000..efd641bfb31141cb2665b384c38ff87c6e121da7 GIT binary patch literal 10240 zcmeIuF%H5o425COoFeQ9IjKpmz%`JlSW*?Gsi3!~L)E2ohl>AA@f#xhtL;#)^;>1f z=$vRKs*P&$qCw4KnCB%vif=5L`WVtp)CcoPobI^O`t>-}M{!QNX&l<J)|*E+y-Gj6 zH~qnjdz*8Aai6~A=lOK-V^|*n1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL RKmY**5I_I{1Q7Tmfgku^8S(%C literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/incomplete.tar b/packages/tar-parser/test/fixtures/incomplete.tar new file mode 100644 index 0000000000000000000000000000000000000000..99c5587453423c2fdef57e00483354c02dca2a77 GIT binary patch literal 1000 zcmYex%t_TX)GMhdVW1f>FfcGPF;QRu(&lESVA{Y4!UqZgfuV_lp^=fPsiBFfiIJ&- zfuWI^fe}z0&0K_JaA|Q#ViC}3xru2=qL@sevNU`uAU=V3&cHwc(}2M#lBtlGtB?jx P1YCpDg`=*bMhE}^HP;zU literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/latin1.tar b/packages/tar-parser/test/fixtures/latin1.tar new file mode 100644 index 0000000000000000000000000000000000000000..3583c8933cc75deb9fd0bb934351a778be5c605c GIT binary patch literal 10240 zcmeIuu?oU45XSM$KE*k?6iM0`M<>D82&hm9jU;LHjoo|(>ndW0E*<{ga)gB3-S61R zHTmx8+gwTBv_Xd0XSoIcDu-=(6g5A3jI&mK>X`4UwQ<Tc#?-diyIrluv(ZM0p5J=< zhdvjdL{y6L@2*q#)14Oi;&cfiR&tLioY$*Gj>u35Ab<b@2q1s}0tg_000IagfB*sr eAb<b@2q1s}0tg_000IagfB*srAb<b@KLp;b(jguI literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/lodash-4.17.21.tgz b/packages/tar-parser/test/fixtures/lodash-4.17.21.tgz new file mode 100644 index 0000000000000000000000000000000000000000..f2461356dbb4136645043014138c2f8538081770 GIT binary patch literal 318961 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%0D$9x5oQ>o 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 literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/long-name.tar b/packages/tar-parser/test/fixtures/long-name.tar new file mode 100644 index 0000000000000000000000000000000000000000..cf939817352d4ac1587fc34f2298e0219f528131 GIT binary patch literal 2048 zcmeH^&kn*M490i%DR=_gA?WjTTahJf7+}ft>8<X*gUJ#P^g#LZLBIZ3GDGnUkHl_V z!7~k<z{S{6>ge^$Yz#cp#OJb><{OB3HAXd(Z&&-xsJFFjNoZ89*4DPh8f_Jt%gvzZ zw(G}^OD>ee+C*-*kjUJgV(VmU4#oWR1Sce5%n;&y7pTS43@sw`o)YziQwEv`$UZJ% g*e!nCq2~~y`Z!ddPdgn~slHqZR05SiCGbxK-bofs;s5{u literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/multi-file.tar b/packages/tar-parser/test/fixtures/multi-file.tar new file mode 100644 index 0000000000000000000000000000000000000000..6dabdf6336738440faadd849ed8c977462509239 GIT binary patch literal 3072 zcmeHG!3x7L2<>@a;SX%6)9ib4XrQoOwha3Dm4wnlp|?O_dU;Vqp3l5Ay~jH}@{)&U zfrvo_2E$j-g2*+uk_8D6vnq)SD<E+|w!UVJ4ugN+96v^Fj_FW6KdmiYb<|Dja)@vq w&}U_WI72F*;MONYXVp@Ha(eF2|4;XS%e!y0cmK2de-p*g6>tSyfj>}S1?7S=oB#j- literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/name-is-100.tar b/packages/tar-parser/test/fixtures/name-is-100.tar new file mode 100644 index 0000000000000000000000000000000000000000..299b2e8c352c8b4c8cdc4f544de1dbc9cf77f024 GIT binary patch literal 10240 zcmeIu!H&Wp5XSMI_bGS*7gUOmW4i4ax}lI18r`=SP0a4WG@dpd{#=GIlkm+ira_KV z8kQhgPpS9a<~#c_79Ia~p1t)c<`iV}HK%iyc|85-BDv^Xx-#~9jDuW0eVKwW##yVH zS`V(h*Lr=_dNodMcRSY_Yqxu+%-*)vHOe&qaF!Z(uF<CMwEElGi-eVl+Zw-1sg=pM zYIzAEeY{m9!XSVE0tg_000IagfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s} J0tmbya0Oh2JKF#N literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/one-file.tar b/packages/tar-parser/test/fixtures/one-file.tar new file mode 100644 index 0000000000000000000000000000000000000000..8d4ac2823285493246eb4972786a796d1095bdc0 GIT binary patch literal 2048 zcmeH@K?;CC2t`|W3QrJ@Xq_jhXfY9#QOD03Xcg@STIfdoihQ5;t5$kwkuealW`@FY zQ_G!^Qg4z)U<gDafrUu`0|{R9jGms;+p6ti)~0rNw70_6hOdqENqP<u-cI~c8~Ye% W*ykm7<sbdICnw+poPZO^L*N8Z3mNwS literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/pax.tar b/packages/tar-parser/test/fixtures/pax.tar new file mode 100644 index 0000000000000000000000000000000000000000..f0d9d2f11038c430218f9124532b049e6d73c6c2 GIT binary patch literal 3072 zcmeHGK?;K~5cKRT_621Vvhn1-N58OW#6pUqk>>eb>Om-_pdeJ5y=<~fmYE?_alATi z+?X9#h-i(0OnPDI)ln~Z8A%xhN^2rz$Y=so+FFDx9!F{2JWqi~p?2qX9ey|oto?>q zlq}*<$e*N?g@Hp?4jeBbhFlde4X(biFDIUBm!CvOqPfq3>KF2_%zOTcBtp1P(zaKB cp8w8y-@~IHeUqZT?dK$Pav(X795}TDPs$@ZE&u=k literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/react-18.0.0.tgz b/packages/tar-parser/test/fixtures/react-18.0.0.tgz deleted file mode 100644 index bf7fa723e3b0379972d22c7189b21b0cbb468a0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81337 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 DAF`cz diff --git a/packages/tar-parser/test/fixtures/space.tar b/packages/tar-parser/test/fixtures/space.tar new file mode 100644 index 0000000000000000000000000000000000000000..0bd7cead248ba7c059e2549c4bcc58003d17c77b GIT binary patch literal 10240 zcmeHLTW{Mo6wY&g1tAQ52qsbTZG*w6yI{itG;0B8!+>=NWQlRuNuof?wX-7seTNsx zk{idhVGQj+1&FP~bK`e-jy}1jvi8FO{`}dm-@lpt^7;nP`HG6*o#f@&Nv<diCzBC6 zL+0B4M8k22qQOY1jo}|c(PS_houTj~(f2r6$~qCCGp|{G$3?bFec!s?TWB{4pI^xJ z;T$2aObY5vkypcE@V-`(_f$y6OC{8Y!$^~5eb0pi>7SqkYCq5t-5A^unbR_`AbvOJ z*~5Iv@{E;>Amv5ufx%zeb<R>+N*(X|>c%)`i;@c^vVJcvaB!iQRCYY0w*}9ZIhBn} zAJJQIT=9~Ybt`Xo0CwuT)N#)r&%cmz{O4&Zkhc53;zh77@{{GVr~jkzB(nYg&1f`; zp#R5{aOnE~WCeJ}5qSxfMz-BAy(kDhM9Y+`#=Z1@yZPDw)_WPBlS=S+G_4V6m-5oP zuj^`xagn@-rcbIQy{7>e3;gEwH6E#_iDxvYYsp&e)oK;2hFWhBh7tbb`qc~!i^OLo zOyM%6U?tg9YT+xMCN<2U)_iv`v@4yp%uJ5HPAY(VFV>@rz(Aq-?`F)!dX?aw%&1j~ zfcau<)W{<X!I#xl7Q^fb`cp1vY7()G65J?hAKEMtHM>jFT3NP=zTmv}q1_1XtZ$5L zSz@S4Fd(?OHJRaVYDc6+Iw92*_&5jB1nl#J?L;yvQ^6`#D}*h&diHlvtMcUnioB6% zP>i%M+(t`R-A|;X#XNuTjmgKkDl>Hv{FGDjlu)a8KroRqTG29t7C0tW6Wwl<V2cCD zP5;E7+k@!I`JbeJCkuKq2DoSbqhYk+f8j*)zwuz;=KnKe`(#T8@xM-|D`sf8Tahr$ z6B%^P8qSQ7nvtNWqKaVIm@=a2Jx6c7pM>CIib{^u2}H7@DZ67dd+VVWFA!a`8byk` zJ!;Nqi039|heKY?e)Jr_JNi64)&I?~JrxPu)Bn+UFl_nXQ1ibDya2lXKf0&~7?P&g zx=Z)4JM$EkmQppA_L+>EdmIH(Fi_2ljw6A_@&F=uNM6r!#byh>-a?lyvMko`oCL!+ zogjf<3yP%fa2hL#;Rl6a@ejd9!D`#Ph8f(koX%+9+KBpeh-6Fv@8;qm{_2Az5y3o> z6y%QtZ&r0q3UYN3R;Kw9#&zFWcPWN<><ie9QS9rr;w^hZ*E`+XCFQpJ!j1`UR(cug zRGJmA*?yt_R69-DZd=mEsQgq*sM3PgyR_T1I}kucyCrIGK?Mk@WvHJW!#iLYI8}#$ nL%<>65O4@M1RMem0f&G?z#-rea0oaA90Cpjhk!%ie}%xmfj#!? literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/types.tar b/packages/tar-parser/test/fixtures/types.tar new file mode 100644 index 0000000000000000000000000000000000000000..197af7b674aaa3f741efbaf5e6fe4222b5955a2c GIT binary patch literal 2048 zcmYevEJ{r-$uFv8pdBzUFfcbYRbT+oW)RxI$OOy>3W0%wp^=fPsiBFfiIJ&-fuWJP zp_u}MDeatuFuAn2B(VtSwA{orgdi3cP+1y26;OYGJP8B}SWFm{LMgEL*Uiby%chMJ of#E@7{F|DZ8!Ipv!5v2%cY#eE;qgzykR3I8Gz3ONV33CZ06`%!@Bjb+ literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/unicode-bsd.tar b/packages/tar-parser/test/fixtures/unicode-bsd.tar new file mode 100644 index 0000000000000000000000000000000000000000..2f74b5f4524915b0cd7c888409ba0a0e32fcdded GIT binary patch literal 10240 zcmeIxy-ve06b0bSc?v&4x!1qR;EAP33`k6j7Il@-G@xQo9<6&{4AW96LRF`B2plht zk1Xr@bM8YJ<}obd=BC+gyKc9gr6CoU9Ykcc7Db+&HT#+5VVxr)c1p06#;~=dtspkm zs6q^vE#vfQAMYt_a%t<ZJiXy3&D)mecI<CLhs#l(Co&|7w~!h?di^qIHU&#H2! zs;su(Sr}zCIaf+09&hJ&_fNA${Pb*{bCPo`k8#_-dS&XGwJNzfrhV7;E6?Rbg#LD! zqj$gBMRRMM?SCTutN)dCx&P^E6^#!5=l$Qr7c}DNcfcnEAOHafKmY;|fB*y_009U< g00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5SW_47sEbRtN;K2 literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/fixtures/unicode.tar b/packages/tar-parser/test/fixtures/unicode.tar new file mode 100644 index 0000000000000000000000000000000000000000..ab7dbad9ec7a722c38a80d5130267a0e98efdf1f GIT binary patch literal 3072 zcmWGYtnf%pOi3+bpdBzUFfcPQQD6Yl=4Pf~+Q10H2MPg!k*R{Ak&&sXp^2#pkZoXS zWM*chz)(RuCm~EOEiOqc0y-@>F%2Pzg#}cWhED~=ClJpW7${&dVNePg87dScmSosw z9Ntk}a(HQuUP(m>*PwLisH12R0s(^|{~H>h=YLahc|i*gqnkOx^FJ`(=j0sTF`DJk T)5R!%Gz3ONU^E1Vc?bXi4Y@d* literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/utils.ts b/packages/tar-parser/test/utils.ts index f279750146e..135fe77a7a7 100644 --- a/packages/tar-parser/test/utils.ts +++ b/packages/tar-parser/test/utils.ts @@ -4,6 +4,31 @@ import { openFile } from '@mjackson/lazy-file/fs'; const __dirname = path.dirname(new URL(import.meta.url).pathname); const fixturesDir = path.resolve(__dirname, 'fixtures'); -export function openFixture(name: string): File { - return openFile(path.join(fixturesDir, name)); +export const fixtures = { + base256Size: path.resolve(fixturesDir, 'base-256-size.tar'), + base256UidGid: path.resolve(fixturesDir, 'base-256-uid-gid.tar'), + expressNpmPackage: path.resolve(fixturesDir, 'express-4.21.1.tgz'), + fetchProxyGithubArchive: path.resolve(fixturesDir, 'fetch-proxy-0.1.0.tar.gz'), + gnuIncremental: path.resolve(fixturesDir, 'gnu-incremental.tar'), + gnuLongPath: path.resolve(fixturesDir, 'gnu-long-path.tar'), + gnu: path.resolve(fixturesDir, 'gnu.tar'), + incomplete: path.resolve(fixturesDir, 'incomplete.tar'), + latin1: path.resolve(fixturesDir, 'latin1.tar'), + lodashNpmPackage: path.resolve(fixturesDir, 'lodash-4.17.21.tgz'), + longName: path.resolve(fixturesDir, 'long-name.tar'), + multiFile: path.resolve(fixturesDir, 'multi-file.tar'), + nameIs100: path.resolve(fixturesDir, 'name-is-100.tar'), + oneFile: path.resolve(fixturesDir, 'one-file.tar'), + pax: path.resolve(fixturesDir, 'pax.tar'), + space: path.resolve(fixturesDir, 'space.tar'), + types: path.resolve(fixturesDir, 'types.tar'), + unicodeBsd: path.resolve(fixturesDir, 'unicode-bsd.tar'), + unicode: path.resolve(fixturesDir, 'unicode.tar'), +}; + +export function readFixture(filename: string): ReadableStream<Uint8Array> { + let stream = openFile(filename).stream(); + return filename.endsWith('.tar.gz') || filename.endsWith('.tgz') + ? stream.pipeThrough(new DecompressionStream('gzip')) + : stream; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 10d520a6b98..733481ada63 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -211,6 +211,31 @@ importers: '@types/node': specifier: ^20.14.10 version: 20.16.1 + '@types/tar-stream': + specifier: ^3.1.3 + version: 3.1.3 + typescript: + specifier: ^5.6.3 + version: 5.7.2 + + packages/tar-parser/bench: + dependencies: + '@mjackson/lazy-file': + specifier: workspace:* + version: link:../../lazy-file + '@mjackson/tar-parser': + specifier: workspace:* + version: link:.. + gunzip-maybe: + specifier: ^1.4.2 + version: 1.4.2 + tar-stream: + specifier: ^3.1.7 + version: 3.1.7 + devDependencies: + '@types/gunzip-maybe': + specifier: ^1.4.2 + version: 1.4.2 scripts: dependencies: @@ -803,6 +828,9 @@ packages: '@types/express@4.17.21': resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + '@types/gunzip-maybe@1.4.2': + resolution: {integrity: sha512-2uqXZg1jTCKE1Pjbab8qb74+f2+i9h/jz8rQ+jRR+zaNJF75zWwrpbX8/TjF4m56m3KFOg9umHdCJ074KwiVxg==} + '@types/http-errors@2.0.4': resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} @@ -839,6 +867,9 @@ packages: '@types/serve-static@1.15.7': resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + '@types/tar-stream@3.1.3': + resolution: {integrity: sha512-Zbnx4wpkWBMBSu5CytMbrT5ZpMiF55qgM+EpHzR4yIDu7mv52cej8hTkOc6K+LzpkOAbxwn/m7j3iO+/l42YkQ==} + '@types/tmp@0.2.6': resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} @@ -887,9 +918,15 @@ packages: as-table@1.0.55: resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + b4a@1.6.7: + resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + bare-events@2.5.0: + resolution: {integrity: sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -908,6 +945,12 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + browserify-zlib@0.1.4: + resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + bun-types@1.1.26: resolution: {integrity: sha512-n7jDe62LsB2+WE8Q8/mT3azkPaatKlj/2MyP6hi3mKvPz9oPpB6JW/Ll6JHtNLudasFFuvfgklYSE+rreGvBjw==} @@ -978,6 +1021,9 @@ packages: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cross-spawn@7.0.5: resolution: {integrity: sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==} engines: {node: '>= 8'} @@ -1029,6 +1075,9 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + duplexify@3.7.1: + resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -1045,6 +1094,9 @@ packages: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + es-define-property@1.0.0: resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} engines: {node: '>= 0.4'} @@ -1085,6 +1137,9 @@ packages: resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} engines: {node: '>= 0.10.0'} + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fdir@6.4.2: resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} peerDependencies: @@ -1142,6 +1197,10 @@ packages: gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + gunzip-maybe@1.4.2: + resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} + hasBin: true + has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} @@ -1180,6 +1239,9 @@ packages: resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} engines: {node: '>= 0.4'} + is-deflate@1.0.0: + resolution: {integrity: sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1192,10 +1254,17 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-gzip@1.0.0: + resolution: {integrity: sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==} + engines: {node: '>=0.10.0'} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -1323,9 +1392,15 @@ packages: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -1350,6 +1425,9 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + peek-stream@1.1.3: + resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1391,10 +1469,19 @@ packages: printable-characters@1.0.42: resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + pump@2.0.1: + resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} + + pumpify@1.5.1: + resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -1403,6 +1490,9 @@ packages: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} engines: {node: '>=0.6'} + queue-tick@1.0.1: + resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} + range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -1411,6 +1501,9 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -1446,6 +1539,9 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -1515,10 +1611,16 @@ packages: resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} engines: {node: '>=4', npm: '>=6'} + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + streamx@2.20.1: + resolution: {integrity: sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -1527,6 +1629,9 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -1544,6 +1649,12 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + tar-stream@3.1.7: + resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + + text-decoder@1.2.1: + resolution: {integrity: sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==} + thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -1551,6 +1662,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + tinyexec@0.3.1: resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} @@ -1634,6 +1748,9 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + utils-merge@1.0.1: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} @@ -1676,6 +1793,9 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@8.18.0: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} @@ -1688,6 +1808,10 @@ packages: utf-8-validate: optional: true + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + xxhash-wasm@1.0.2: resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} @@ -2082,6 +2206,10 @@ snapshots: '@types/qs': 6.9.15 '@types/serve-static': 1.15.7 + '@types/gunzip-maybe@1.4.2': + dependencies: + '@types/node': 22.5.4 + '@types/http-errors@2.0.4': {} '@types/mime@1.3.5': {} @@ -2123,6 +2251,10 @@ snapshots: '@types/node': 22.5.4 '@types/send': 0.17.4 + '@types/tar-stream@3.1.3': + dependencies: + '@types/node': 22.5.4 + '@types/tmp@0.2.6': {} '@types/ws@8.5.12': @@ -2163,8 +2295,13 @@ snapshots: dependencies: printable-characters: 1.0.42 + b4a@1.6.7: {} + balanced-match@1.0.2: {} + bare-events@2.5.0: + optional: true + binary-extensions@2.3.0: {} blake3-wasm@2.1.5: {} @@ -2194,6 +2331,12 @@ snapshots: dependencies: fill-range: 7.1.1 + browserify-zlib@0.1.4: + dependencies: + pako: 0.2.9 + + buffer-from@1.1.2: {} + bun-types@1.1.26: dependencies: '@types/node': 20.12.14 @@ -2265,6 +2408,8 @@ snapshots: cookie@0.6.0: {} + core-util-is@1.0.3: {} + cross-spawn@7.0.5: dependencies: path-key: 3.1.1 @@ -2299,6 +2444,13 @@ snapshots: destroy@1.2.0: {} + duplexify@3.7.1: + dependencies: + end-of-stream: 1.4.4 + inherits: 2.0.4 + readable-stream: 2.3.8 + stream-shift: 1.0.3 + eastasianwidth@0.2.0: {} ee-first@1.1.1: {} @@ -2309,6 +2461,10 @@ snapshots: encodeurl@1.0.2: {} + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + es-define-property@1.0.0: dependencies: get-intrinsic: 1.2.4 @@ -2413,6 +2569,8 @@ snapshots: transitivePeerDependencies: - supports-color + fast-fifo@1.3.2: {} + fdir@6.4.2(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 @@ -2479,6 +2637,15 @@ snapshots: dependencies: get-intrinsic: 1.2.4 + gunzip-maybe@1.4.2: + dependencies: + browserify-zlib: 0.1.4 + is-deflate: 1.0.0 + is-gzip: 1.0.0 + peek-stream: 1.1.3 + pumpify: 1.5.1 + through2: 2.0.5 + has-property-descriptors@1.0.2: dependencies: es-define-property: 1.0.0 @@ -2515,6 +2682,8 @@ snapshots: dependencies: hasown: 2.0.2 + is-deflate@1.0.0: {} + is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -2523,8 +2692,12 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-gzip@1.0.0: {} + is-number@7.0.0: {} + isarray@1.0.0: {} + isexe@2.0.0: {} jackspeak@3.4.3: @@ -2626,8 +2799,14 @@ snapshots: dependencies: ee-first: 1.1.1 + once@1.4.0: + dependencies: + wrappy: 1.0.2 + package-json-from-dist@1.0.1: {} + pako@0.2.9: {} + parseurl@1.3.3: {} path-key@3.1.1: {} @@ -2645,6 +2824,12 @@ snapshots: pathe@1.1.2: {} + peek-stream@1.1.3: + dependencies: + buffer-from: 1.1.2 + duplexify: 3.7.1 + through2: 2.0.5 + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -2661,17 +2846,32 @@ snapshots: printable-characters@1.0.42: {} + process-nextick-args@2.0.1: {} + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 ipaddr.js: 1.9.1 + pump@2.0.1: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + pumpify@1.5.1: + dependencies: + duplexify: 3.7.1 + inherits: 2.0.4 + pump: 2.0.1 + punycode@2.3.1: {} qs@6.11.0: dependencies: side-channel: 1.0.6 + queue-tick@1.0.1: {} + range-parser@1.2.1: {} raw-body@2.5.2: @@ -2681,6 +2881,16 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readdirp@3.6.0: dependencies: picomatch: 2.3.1 @@ -2735,6 +2945,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.26.0 fsevents: 2.3.3 + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} safer-buffer@2.1.2: {} @@ -2816,8 +3028,18 @@ snapshots: stoppable@1.1.0: {} + stream-shift@1.0.3: {} + streamsearch@1.1.0: {} + streamx@2.20.1: + dependencies: + fast-fifo: 1.3.2 + queue-tick: 1.0.1 + text-decoder: 1.2.1 + optionalDependencies: + bare-events: 2.5.0 + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -2830,6 +3052,10 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.1.0 + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -2850,6 +3076,14 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + tar-stream@3.1.7: + dependencies: + b4a: 1.6.7 + fast-fifo: 1.3.2 + streamx: 2.20.1 + + text-decoder@1.2.1: {} + thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -2858,6 +3092,11 @@ snapshots: dependencies: any-promise: 1.3.0 + through2@2.0.5: + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + tinyexec@0.3.1: {} tinyglobby@0.2.10: @@ -2940,6 +3179,8 @@ snapshots: unpipe@1.0.0: {} + util-deprecate@1.0.2: {} + utils-merge@1.0.1: {} vary@1.1.2: {} @@ -3004,8 +3245,12 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.0 + wrappy@1.0.2: {} + ws@8.18.0: {} + xtend@4.0.2: {} + xxhash-wasm@1.0.2: {} youch@3.3.3: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 3b843b4e575..b6f382b8a1d 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,4 +3,5 @@ packages: - packages/multipart-parser/bench - packages/multipart-parser/examples/* - packages/node-fetch-server/bench + - packages/tar-parser/bench - scripts From 3bea302d740885b32da5ff104caba3d3193137da Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 14 Nov 2024 11:27:34 -0800 Subject: [PATCH 523/730] Faster parser --- packages/tar-parser/README.md | 203 +----------- packages/tar-parser/bench/package.json | 3 +- packages/tar-parser/package.json | 2 +- packages/tar-parser/src/lib/tar.spec.ts | 7 +- packages/tar-parser/src/lib/tar.ts | 419 +++++++----------------- packages/tar-parser/src/lib/utils.ts | 120 +++++++ pnpm-lock.yaml | 9 +- 7 files changed, 265 insertions(+), 498 deletions(-) create mode 100644 packages/tar-parser/src/lib/utils.ts diff --git a/packages/tar-parser/README.md b/packages/tar-parser/README.md index 1a24d18e885..89c379c4884 100644 --- a/packages/tar-parser/README.md +++ b/packages/tar-parser/README.md @@ -1,220 +1,29 @@ -# multipart-parser +# tar-parser -`multipart-parser` is a fast, efficient parser for multipart streams. It can be used in any JavaScript environment (not just node.js) for a variety of use cases including: - -- Handling file uploads (`multipart/form-data` requests) -- Parsing `multipart/mixed` messages (email attachments, API responses, etc.) -- Parsing email messages with both plain text and HTML versions (`multipart/alternative`) +`tar-parser` is a fast, efficient parser for [tar archives](<https://en.wikipedia.org/wiki/Tar_(computing)>). It can be used in any JavaScript environment (not just Node.js). ## Features -- Runs anywhere JavaScript runs (see [examples for Node.js, Bun, Deno, and Cloudflare Workers](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples)) +- Runs anywhere JavaScript runs - Built on the standard [web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) -- Supports the entire spectrum of `multipart/*` message types - Memory efficient and does not buffer anything in normal usage -- [As fast or faster than](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser#benchmark) other popular multipart libraries +- 0 dependencies ## Installation Install from [npm](https://www.npmjs.com/): ```sh -npm install @mjackson/multipart-parser -``` - -Or install from [JSR](https://jsr.io/): - -```sh -deno add @mjackson/multipart-parser +npm install @mjackson/tar-parser ``` ## Usage -The most common use case for `multipart-parser` is handling file uploads when you're building a web server. For this case, the `parseMultipartRequest` function is your friend. It will automatically validate the request is `multipart/form-data`, extract the multipart boundary from the `Content-Type` header, parse all fields and files in the `request.body` stream, and `yield` each one to you as a `MultipartPart` object so you can save it to disk or upload it somewhere. - -```typescript -import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser'; - -async function handleMultipartRequest(request: Request): void { - try { - // The parser `yield`s each MultipartPart as it becomes available - for await (let part of parseMultipartRequest(request)) { - console.log(part.name); - console.log(part.filename); - - if (/^text\//.test(part.mediaType)) { - console.log(await part.text()); - } else { - // TODO: part.body is a ReadableStream<Uint8Array>, stream it to a file - } - } - } catch (error) { - if (error instanceof MultipartParseError) { - console.error('Failed to parse multipart request:', error.message); - } else { - console.error('An unexpected error occurred:', error); - } - } -} -``` - -The main module (`import from "@mjackson/multipart-parser"`) assumes you're working with [the fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) (`Request`, `ReadableStream`, etc). Support for these interfaces was added to Node.js by the [undici](https://github.com/nodejs/undici) project in [version 16.5.0](https://nodejs.org/en/blog/release/v16.5.0). - -If however you're building a server for Node.js that relies on node-specific APIs like `http.IncomingMessage`, `stream.Readable`, and `buffer.Buffer` (ala Express or `http.createServer`), `multipart-parser` ships with an additional module that works directly with these APIs. - -```typescript -import * as http from 'node:http'; - -import { MultipartParseError } from '@mjackson/multipart-parser'; -// Note: Import from multipart-parser/node for node-specific APIs -import { parseMultipartRequest } from '@mjackson/multipart-parser/node'; - -const server = http.createServer(async (req, res) => { - try { - for await (let part of parseMultipartRequest(req)) { - console.log(part.name); - console.log(part.filename); - console.log(part.mediaType); - - // ... - } - } catch (error) { - if (error instanceof MultipartParseError) { - console.error('Failed to parse multipart request:', error.message); - } else { - console.error('An unexpected error occurred:', error); - } - } -}); - -server.listen(8080); -``` - -## Low-level API - -If you're working directly with multipart boundaries and buffers/streams of multipart data that are not necessarily part of a request, `multipart-parser` provides a lower-level API that you can use directly: - -```typescript -import { parseMultipart } from '@mjackson/multipart-parser'; - -// Get the multipart data from some API, filesystem, etc. -let multipartMessage = new Uint8Array(); -// can also be a stream or any Iterable/AsyncIterable -// let multipartMessage = new ReadableStream(...); -// let multipartMessage = [new Uint8Array(...), new Uint8Array(...)]; - -let boundary = '----WebKitFormBoundary56eac3x'; - -for await (let part of parseMultipart(multipartMessage, boundary)) { - // Do whatever you want with the part... -} -``` - -If you'd prefer a callback-based API, instantiate your own `MultipartParser` and go for it: - -```typescript -import { MultipartParseError, MultipartParser } from '@mjackson/multipart-parser'; - -let multipartMessage = new Uint8Array(); // or ReadableStream<Uint8Array>, etc. -let boundary = '...'; - -let parser = new MultipartParser(boundary); - -try { - // parse() resolves once the parse is finished and all your callbacks are done - await parser.parse(multipartMessage, async (part) => { - // Do whatever you need... - }); -} catch (error) { - if (error instanceof MultipartParseError) { - // The parse failed - } else { - // One of your handlers failed - } -} -``` - -## Examples - -The [`examples` directory](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples) contains a few working examples of how you can use this library: - -- [`examples/bun`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples/bun) - using multipart-parser in Bun -- [`examples/cf-workers`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples/cf-workers) - using multipart-parser in a Cloudflare Worker and storing file uploads in R2 -- [`examples/deno`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples/deno) - using multipart-parser in Deno -- [`examples/node`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser/examples/node) - using multipart-parser in Node.js - -## Benchmark - -`multipart-parser` is designed to be as efficient as possible, operating mainly on streams of data and rarely buffering in common usage. This design yields exceptional performance when handling multipart payloads of any size. In most benchmarks, `multipart-parser` is as fast or faster than `busboy`. - -Important: Benchmarking can be tricky, and results vary greatly depending on platform, parameters, and other factors. So take these results with a grain of salt. The main point of this library is to be portable between JavaScript runtimes. To this end, we run the benchmarks on three major open source JavaScript runtimes: Node.js, Bun, and Deno. - -The results of running the benchmarks on my laptop: - -``` -> @mjackson/multipart-parser@0.6.1 bench:node /Users/michael/Projects/multipart-parser -> node --import tsimp/import ./bench/runner.ts - -Platform: Darwin (23.5.0) -CPU: Apple M1 Pro -Date: 8/18/2024, 4:18:39 PM -Node.js v22.1.0 -┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ -│ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ -├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ multipart-parser │ '0.01 ms ± 0.03' │ '1.06 ms ± 0.04' │ '0.10 ms ± 0.03' │ '10.60 ms ± 0.22' │ -│ multipasta │ '0.01 ms ± 0.03' │ '1.06 ms ± 0.03' │ '0.15 ms ± 0.02' │ '10.70 ms ± 2.70' │ -│ busboy │ '0.03 ms ± 0.09' │ '3.01 ms ± 0.08' │ '0.22 ms ± 0.03' │ '29.91 ms ± 0.91' │ -│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.20 ms ± 0.08' │ '0.39 ms ± 0.07' │ '11.86 ms ± 0.17' │ -└──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ - -> @mjackson/multipart-parser@0.6.1 bench:bun /Users/michael/Projects/multipart-parser -> bun run ./bench/runner.ts - -Platform: Darwin (23.5.0) -CPU: Apple M1 Pro -Date: 8/18/2024, 4:20:58 PM -Bun 1.1.21 -┌──────────────────┬────────────────┬────────────────┬─────────────────┬─────────────────┐ -│ │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ -├──────────────────┼────────────────┼────────────────┼─────────────────┼─────────────────┤ -│ multipart-parser │ 0.01 ms ± 0.04 │ 0.91 ms ± 0.09 │ 0.11 ms ± 0.05 │ 8.23 ms ± 0.18 │ -│ multipasta │ 0.01 ms ± 0.03 │ 0.87 ms ± 0.08 │ 0.22 ms ± 0.15 │ 8.09 ms ± 0.15 │ -│ busboy │ 0.03 ms ± 0.07 │ 3.59 ms ± 0.13 │ 0.36 ms ± 0.17 │ 35.26 ms ± 0.39 │ -│ @fastify/busboy │ 0.04 ms ± 0.11 │ 7.23 ms ± 0.15 │ 0.63 ms ± 0.15 │ 71.86 ms ± 0.53 │ -└──────────────────┴────────────────┴────────────────┴─────────────────┴─────────────────┘ - -> @mjackson/multipart-parser@0.6.1 bench:deno /Users/michael/Projects/multipart-parser -> deno --unstable-byonm --unstable-sloppy-imports run --allow-sys ./bench/runner.ts - -Platform: Darwin (23.5.0) -CPU: Apple M1 Pro -Date: 8/18/2024, 4:24:16 PM -Deno 1.45.5 -┌──────────────────┬──────────────────┬───────────────────┬──────────────────┬────────────────────┐ -│ (idx) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ -├──────────────────┼──────────────────┼───────────────────┼──────────────────┼────────────────────┤ -│ multipart-parser │ "0.01 ms ± 0.15" │ "1.00 ms ± 1.00" │ "0.08 ms ± 0.39" │ "10.08 ms ± 0.41" │ -│ multipasta │ "0.01 ms ± 0.14" │ "1.02 ms ± 1.00" │ "0.17 ms ± 0.56" │ "14.59 ms ± 0.92" │ -│ busboy │ "0.04 ms ± 0.28" │ "3.04 ms ± 1.00" │ "0.30 ms ± 0.71" │ "29.86 ms ± 0.83" │ -│ @fastify/busboy │ "0.05 ms ± 0.31" │ "12.36 ms ± 0.78" │ "0.78 ms ± 0.98" │ "123.54 ms ± 5.04" │ -└──────────────────┴──────────────────┴───────────────────┴──────────────────┴────────────────────┘ -``` - -I encourage you to run the benchmarks yourself. You'll probably get different results! - -```sh -pnpm run bench -``` - ## Related Packages -- [`form-data-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser) - Uses `multipart-parser` internally to parse multipart requests and generate `FileUpload`s for storage -- [`headers`](https://github.com/mjackson/remix-the-web/tree/main/packages/headers) - Used internally to parse HTTP headers and get metadata (filename, content type) for each `MultipartPart` - ## Credits -Thanks to Jacob Ebey who gave me several code reviews on this project prior to publishing. +`tar-parser` is based on Node's excellent [tar-stream package](https://www.npmjs.com/package/tar-stream) (MIT license) and adopts the same core parsing algorithm, utility functions, and many test cases. ## License diff --git a/packages/tar-parser/bench/package.json b/packages/tar-parser/bench/package.json index 34ec24e78da..17548a3fd60 100644 --- a/packages/tar-parser/bench/package.json +++ b/packages/tar-parser/bench/package.json @@ -9,6 +9,7 @@ "tar-stream": "^3.1.7" }, "devDependencies": { - "@types/gunzip-maybe": "^1.4.2" + "@types/gunzip-maybe": "^1.4.2", + "@types/tar-stream": "^3.1.3" } } diff --git a/packages/tar-parser/package.json b/packages/tar-parser/package.json index 48c41089459..981a845a02e 100644 --- a/packages/tar-parser/package.json +++ b/packages/tar-parser/package.json @@ -22,8 +22,8 @@ }, "devDependencies": { "@mjackson/lazy-file": "workspace:^", + "@swc-node/register": "^1.10.9", "@types/node": "^20.14.10", - "@types/tar-stream": "^3.1.3", "typescript": "^5.6.3" }, "scripts": { diff --git a/packages/tar-parser/src/lib/tar.spec.ts b/packages/tar-parser/src/lib/tar.spec.ts index bf9bbeb992a..1b265f08eb6 100644 --- a/packages/tar-parser/src/lib/tar.spec.ts +++ b/packages/tar-parser/src/lib/tar.spec.ts @@ -5,8 +5,11 @@ import { fixtures, readFixture } from '../../test/utils.js'; import { TarHeader, TarParser } from './tar.js'; -async function bufferStream(stream: ReadableStream<Uint8Array>): Promise<string> { - let decoder = new TextDecoder(); +async function bufferStream( + stream: ReadableStream<Uint8Array>, + encoding = 'utf-8', +): Promise<string> { + let decoder = new TextDecoder(encoding); let string = ''; for await (let chunk of stream) { diff --git a/packages/tar-parser/src/lib/tar.ts b/packages/tar-parser/src/lib/tar.ts index 6ec91f82b94..d28f844b024 100644 --- a/packages/tar-parser/src/lib/tar.ts +++ b/packages/tar-parser/src/lib/tar.ts @@ -1,3 +1,14 @@ +import { + buffersEqual, + concatChunks, + computeChecksum, + decodeLongPath, + decodePax, + getOctal, + getString, + overflow, +} from './utils.js'; + const TarBlockSize = 512; export class TarParseError extends Error { @@ -132,122 +143,26 @@ export function parseTarHeader(block: Uint8Array, options?: ParseTarHeaderOption return header; } -function buffersEqual(a: Uint8Array, b: Uint8Array): boolean { - if (a.length !== b.length) return false; - for (let i = 0; i < a.length; i++) { - if (a[i] !== b[i]) return false; - } - return true; -} - -function indexOf(buffer: Uint8Array, value: number, offset: number, end: number): number { - for (; offset < end; offset++) { - if (buffer[offset] === value) return offset; - } - return end; -} - -const Utf8Decoder = new TextDecoder(); - -function getString(buffer: Uint8Array, offset: number, size: number, label = 'utf-8') { - return new TextDecoder(label).decode( - buffer.subarray(offset, indexOf(buffer, 0, offset, offset + size)), - ); -} - -function getOctal(buffer: Uint8Array, offset: number, size: number) { - let value = buffer.subarray(offset, offset + size); - offset = 0; - - if (value[offset] & 0x80) return parse256(value); - - // Older versions of tar can prefix with spaces - while (offset < value.length && value[offset] === 32) offset++; - let end = clamp(indexOf(value, 32, offset, value.length), value.length, value.length); - while (offset < end && value[offset] === 0) offset++; - if (end === offset) return 0; - - return parseInt(Utf8Decoder.decode(value.subarray(offset, end)), 8); -} - -/* Copied from the tar-stream repo who copied it from the node-tar repo. - */ -function parse256(buf: Uint8Array): number | null { - // first byte MUST be either 80 or FF - // 80 for positive, FF for 2's comp - let positive; - if (buf[0] === 0x80) positive = true; - else if (buf[0] === 0xff) positive = false; - else return null; - - // build up a base-256 tuple from the least sig to the highest - let tuple = []; - let i; - for (i = buf.length - 1; i > 0; i--) { - const byte = buf[i]; - if (positive) tuple.push(byte); - else tuple.push(0xff - byte); - } - - let sum = 0; - let len = tuple.length; - for (i = 0; i < len; i++) { - sum += tuple[i] * Math.pow(256, i); - } - - return positive ? sum : -1 * sum; -} - -function clamp(index: number, len: number, defaultValue: number): number { - if (typeof index !== 'number') return defaultValue; - index = ~~index; // Coerce to integer. - if (index >= len) return len; - if (index >= 0) return index; - index += len; - if (index >= 0) return index; - return 0; -} - -function computeChecksum(block: Uint8Array): number { - let sum = 8 * 32; - for (let i = 0; i < 148; i++) sum += block[i]; - for (let i = 156; i < 512; i++) sum += block[i]; - return sum; -} - -const enum TarParserState { - Start, - Header, - AfterHeader, - Body, - AfterBody, - Done, -} - export type TarParserOptions = ParseTarHeaderOptions; /** * A parser for tar archives. */ export class TarParser { - #state = TarParserState.Start; #buffer: Uint8Array | null = null; - #bodyController: ReadableStreamDefaultController<Uint8Array> | null = null; - #bodyWritten = 0; - #bodySize = 0; // The declared size of the current body + #missing = 0; #header: TarHeader | null = null; + #bodyController: ReadableStreamDefaultController<Uint8Array> | null = null; #longHeader = false; #gnuLongPath: string | null = null; #gnuLongLinkPath: string | null = null; #paxGlobal: Record<string, string> | null = null; #pax: Record<string, string> | null = null; - #allowUnknownFormat: boolean; - #filenameEncoding: string; + #options?: TarParserOptions; constructor(options?: TarParserOptions) { - this.#allowUnknownFormat = options?.allowUnknownFormat ?? true; - this.#filenameEncoding = options?.filenameEncoding ?? 'utf-8'; + this.#options = options; } /** @@ -262,9 +177,7 @@ export class TarParser { | AsyncIterable<Uint8Array>, handler: (entry: TarEntry) => void, ): Promise<void> { - if (this.#state !== TarParserState.Start) { - this.#reset(); - } + this.#reset(); let results: unknown[] = []; @@ -286,10 +199,7 @@ export class TarParser { throw new TypeError('Cannot parse tar archive; expected a stream or buffer'); } - if ( - this.#state !== TarParserState.Done && - !(this.#buffer === null || this.#buffer.length === 0) - ) { + if (this.#missing !== 0) { throw new TarParseError('Unexpected end of archive'); } @@ -297,11 +207,10 @@ export class TarParser { } #reset(): void { - this.#state = TarParserState.Start; this.#buffer = null; - this.#bodyController = null; - this.#bodySize = 0; + this.#missing = 0; this.#header = null; + this.#bodyController = null; this.#longHeader = false; this.#gnuLongPath = null; this.#gnuLongLinkPath = null; @@ -310,185 +219,139 @@ export class TarParser { } #write(chunk: Uint8Array, handler: (entry: TarEntry) => void): void { - if (this.#state === TarParserState.Done) { - throw new TarParseError('Unexpected data after end of archive'); - } - - let index = 0; - let chunkLength = chunk.length; - if (this.#buffer !== null) { - let newChunk = new Uint8Array(this.#buffer.length + chunkLength); - newChunk.set(this.#buffer, 0); - newChunk.set(chunk, this.#buffer.length); - chunk = newChunk; - chunkLength = chunk.length; - this.#buffer = null; + this.#buffer = concatChunks(this.#buffer, chunk); + } else { + this.#buffer = chunk; } - while (true) { - if (this.#state === TarParserState.Body) { - let remaining = this.#bodySize - this.#bodyWritten; - - if (chunkLength - index < remaining) { - this.#writeBody(index === 0 ? chunk : chunk.subarray(index)); - break; + while (this.#buffer !== null && this.#buffer.length > 0) { + if (this.#missing > 0) { + if (this.#bodyController !== null) { + this.#parseBody(); + continue; } - this.#writeBody(chunk.subarray(index, index + remaining)); - this.#closeBody(); + if (this.#longHeader) { + if (this.#missing > this.#buffer.length) break; + this.#parseLongHeader(); + continue; + } - index += remaining; + if (this.#missing >= this.#buffer.length) { + this.#missing -= this.#buffer.length; + this.#buffer = null; + break; + } - this.#state = TarParserState.AfterBody; + this.#buffer = this.#buffer.subarray(this.#missing); + this.#missing = 0; } - if (this.#state === TarParserState.AfterBody) { - let padding = overflow(this.#bodySize); + if (this.#buffer.length < TarBlockSize) break; + this.#parseHeader(handler); + } + } - if (chunkLength - index < padding) { - this.#buffer = chunk.subarray(index); - break; - } + #parseHeader(handler: (entry: TarEntry) => void): void { + let block = this.#read(TarBlockSize); - index += padding; + if (isZeroBlock(block)) { + this.#header = null; + return; + } - this.#state = TarParserState.Header; - } + this.#header = parseTarHeader(block, this.#options); - if (this.#state === TarParserState.Start || this.#state === TarParserState.Header) { - if (chunkLength - index < TarBlockSize) { - this.#buffer = chunk.subarray(index); - break; - } + switch (this.#header.type) { + case 'gnu-long-path': + case 'gnu-long-link-path': + case 'pax-global-header': + case 'pax-header': + this.#longHeader = true; + this.#missing = this.#header.size; + return; + } - let block = chunk.subarray(index, index + TarBlockSize); - index += TarBlockSize; - - if (isZeroBlock(block)) { - this.#header = null; - } else { - this.#header = parseTarHeader(block, { - allowUnknownFormat: this.#allowUnknownFormat, - filenameEncoding: this.#filenameEncoding, - }); - - switch (this.#header.type) { - case 'gnu-long-path': - case 'gnu-long-link-path': - case 'pax-global-header': - case 'pax-header': - this.#longHeader = true; - break; - default: - if (this.#gnuLongPath) { - this.#header.name = this.#gnuLongPath; - this.#gnuLongPath = null; - } - - if (this.#gnuLongLinkPath) { - this.#header.linkname = this.#gnuLongLinkPath; - this.#gnuLongLinkPath = null; - } - - if (this.#pax) { - if (this.#pax.path) this.#header.name = this.#pax.path; - if (this.#pax.linkpath) this.#header.linkname = this.#pax.linkpath; - if (this.#pax.size) this.#header.size = parseInt(this.#pax.size, 10); - this.#header.pax = this.#pax; - this.#pax = null; - } - } - } + if (this.#gnuLongPath) { + this.#header.name = this.#gnuLongPath; + this.#gnuLongPath = null; + } - this.#state = TarParserState.AfterHeader; - } + if (this.#gnuLongLinkPath) { + this.#header.linkname = this.#gnuLongLinkPath; + this.#gnuLongLinkPath = null; + } - if (this.#state === TarParserState.AfterHeader) { - // Either we are at the end of the archive ... - if (this.#header === null) { - if (chunkLength - index < TarBlockSize) { - this.#buffer = chunk.subarray(index); - break; - } - - let nextBlock = chunk.subarray(index, index + TarBlockSize); - if (isZeroBlock(nextBlock)) { - this.#state = TarParserState.Done; - break; - } else { - throw new TarParseError('Invalid end of archive marker'); - } - } + if (this.#pax) { + if (this.#pax.path) this.#header.name = this.#pax.path; + if (this.#pax.linkpath) this.#header.linkname = this.#pax.linkpath; + if (this.#pax.size) this.#header.size = parseInt(this.#pax.size, 10); + this.#header.pax = this.#pax; + this.#pax = null; + } - // ... or we found a long header that we need to finish parsing ... - if (this.#longHeader) { - let padding = overflow(this.#header.size); - - if (chunkLength - index < this.#header.size + padding) { - this.#buffer = chunk.subarray(index); - break; - } - - let buffer = chunk.subarray(index, index + this.#header.size); - index += this.#header.size + padding; - - switch (this.#header.type) { - case 'gnu-long-path': - this.#gnuLongPath = decodeLongPath(buffer); - break; - case 'gnu-long-link-path': - this.#gnuLongLinkPath = decodeLongPath(buffer); - break; - case 'pax-global-header': - this.#paxGlobal = decodePax(buffer); - break; - case 'pax-header': - this.#pax = - this.#paxGlobal === null - ? decodePax(buffer) - : Object.assign({}, this.#paxGlobal, decodePax(buffer)); - break; - } - - this.#longHeader = false; - - this.#state = TarParserState.Header; - continue; - } + if (this.#header.size === 0 || this.#header.type === 'directory') { + handler(new TarEntry(this.#header, new ReadableStream<Uint8Array>())); + this.#bodyController = null; + this.#missing = 0; + return; + } + + let body = new ReadableStream<Uint8Array>({ + start: (controller) => { + this.#bodyController = controller; + }, + }); - // ... or it's the beginning of a new entry. - this.#bodySize = this.#header.size; + handler(new TarEntry(this.#header, body)); - let entry = new TarEntry( - this.#header, - new ReadableStream({ - start: (controller) => { - this.#bodyController = controller; - }, - }), - ); + this.#missing = this.#header.size; + } - handler(entry); + #parseLongHeader(): void { + this.#longHeader = false; - this.#state = TarParserState.Body; - } + let buffer = this.#read(this.#header!.size); + + switch (this.#header!.type) { + case 'gnu-long-path': + this.#gnuLongPath = decodeLongPath(buffer); + break; + case 'gnu-long-link-path': + this.#gnuLongLinkPath = decodeLongPath(buffer); + break; + case 'pax-global-header': + this.#paxGlobal = decodePax(buffer); + break; + case 'pax-header': + this.#pax = + this.#paxGlobal !== null + ? Object.assign({}, this.#paxGlobal, decodePax(buffer)) + : decodePax(buffer); + break; } + + this.#missing = overflow(this.#header!.size); } - #writeBody(chunk: Uint8Array): void { - if (this.#bodyWritten + chunk.length > this.#bodySize) { - throw new TarParseError('Body size exceeds declared size'); + #parseBody(): void { + if (this.#missing >= this.#buffer!.length) { + this.#bodyController!.enqueue(this.#buffer!); + this.#missing -= this.#buffer!.length; + this.#buffer = null; + } else { + this.#bodyController!.enqueue(this.#read(this.#missing)); + this.#bodyController!.close(); + this.#bodyController = null; + this.#missing = overflow(this.#header!.size); } - - this.#bodyController!.enqueue(chunk); - this.#bodyWritten += chunk.length; } - #closeBody(): void { - this.#bodyController!.close(); - this.#bodyController = null; - this.#bodyWritten = 0; + #read(size: number): Uint8Array { + let result = this.#buffer!.subarray(0, size); + this.#buffer = this.#buffer!.subarray(size); + return result; } } @@ -504,37 +367,6 @@ function isZeroBlock(buffer: Uint8Array): boolean { return buffer.every((byte) => byte === 0); } -function decodeLongPath(buffer: Uint8Array): string { - return Utf8Decoder.decode(buffer); -} - -function decodePax(buffer: Uint8Array): Record<string, string> { - let pax: Record<string, string> = {}; - - while (buffer.length) { - let i = 0; - while (i < buffer.length && buffer[i] !== 32) i++; - - let len = parseInt(Utf8Decoder.decode(buffer.subarray(0, i)), 10); - if (!len) break; - - let val = Utf8Decoder.decode(buffer.subarray(i + 1, len - 1)); - let eq = val.indexOf('='); - if (eq === -1) break; - - pax[val.slice(0, eq)] = val.slice(eq + 1); - - buffer = buffer.subarray(len); - } - - return pax; -} - -function overflow(size: number): number { - size &= 511; - return size && 512 - size; -} - /** * An entry in a tar archive. */ @@ -600,7 +432,6 @@ export class TarEntry { * The name of this entry. */ get name(): string { - // TODO: handle prefix return this.header.name; } diff --git a/packages/tar-parser/src/lib/utils.ts b/packages/tar-parser/src/lib/utils.ts new file mode 100644 index 00000000000..d1de1b3a3c2 --- /dev/null +++ b/packages/tar-parser/src/lib/utils.ts @@ -0,0 +1,120 @@ +export function buffersEqual(a: Uint8Array, b: Uint8Array): boolean { + if (a.length !== b.length) return false; + for (let i = 0; i < a.length; i++) { + if (a[i] !== b[i]) return false; + } + return true; +} + +export function concatChunks(a: Uint8Array, b: Uint8Array): Uint8Array { + let result = new Uint8Array(a.length + b.length); + result.set(a); + result.set(b, a.length); + return result; +} + +export function computeChecksum(block: Uint8Array): number { + let sum = 8 * 32; + for (let i = 0; i < 148; i++) sum += block[i]; + for (let i = 156; i < 512; i++) sum += block[i]; + return sum; +} + +export function decodeLongPath(buffer: Uint8Array): string { + return Utf8Decoder.decode(buffer); +} + +export function decodePax(buffer: Uint8Array): Record<string, string> { + let pax: Record<string, string> = {}; + + while (buffer.length) { + let i = 0; + while (i < buffer.length && buffer[i] !== 32) i++; + + let len = parseInt(Utf8Decoder.decode(buffer.subarray(0, i)), 10); + if (!len) break; + + let val = Utf8Decoder.decode(buffer.subarray(i + 1, len - 1)); + let eq = val.indexOf('='); + if (eq === -1) break; + + pax[val.slice(0, eq)] = val.slice(eq + 1); + + buffer = buffer.subarray(len); + } + + return pax; +} + +export function indexOf(buffer: Uint8Array, value: number, offset: number, end: number): number { + for (; offset < end; offset++) { + if (buffer[offset] === value) return offset; + } + return end; +} + +export function getString(buffer: Uint8Array, offset: number, size: number, label = 'utf-8') { + return new TextDecoder(label).decode( + buffer.subarray(offset, indexOf(buffer, 0, offset, offset + size)), + ); +} + +const Utf8Decoder = new TextDecoder(); + +export function getOctal(buffer: Uint8Array, offset: number, size: number) { + let value = buffer.subarray(offset, offset + size); + offset = 0; + + if (value[offset] & 0x80) return parse256(value); + + // Older versions of tar can prefix with spaces + while (offset < value.length && value[offset] === 32) offset++; + let end = clamp(indexOf(value, 32, offset, value.length), value.length, value.length); + while (offset < end && value[offset] === 0) offset++; + if (end === offset) return 0; + + return parseInt(Utf8Decoder.decode(value.subarray(offset, end)), 8); +} + +function clamp(index: number, len: number, defaultValue: number): number { + if (typeof index !== 'number') return defaultValue; + index = ~~index; // Coerce to integer. + if (index >= len) return len; + if (index >= 0) return index; + index += len; + if (index >= 0) return index; + return 0; +} + +/* Copied from the tar-stream repo who copied it from the node-tar repo. + */ +function parse256(buf: Uint8Array): number | null { + // first byte MUST be either 80 or FF + // 80 for positive, FF for 2's comp + let positive; + if (buf[0] === 0x80) positive = true; + else if (buf[0] === 0xff) positive = false; + else return null; + + // build up a base-256 tuple from the least sig to the highest + let tuple = []; + let i; + for (i = buf.length - 1; i > 0; i--) { + const byte = buf[i]; + if (positive) tuple.push(byte); + else tuple.push(0xff - byte); + } + + let sum = 0; + let len = tuple.length; + for (i = 0; i < len; i++) { + sum += tuple[i] * Math.pow(256, i); + } + + return positive ? sum : -1 * sum; +} + +export function overflow(size: number): number { + size &= 511; + return size && 512 - size; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 733481ada63..1359f645076 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -208,12 +208,12 @@ importers: '@mjackson/lazy-file': specifier: workspace:^ version: link:../lazy-file + '@swc-node/register': + specifier: ^1.10.9 + version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^20.14.10 version: 20.16.1 - '@types/tar-stream': - specifier: ^3.1.3 - version: 3.1.3 typescript: specifier: ^5.6.3 version: 5.7.2 @@ -236,6 +236,9 @@ importers: '@types/gunzip-maybe': specifier: ^1.4.2 version: 1.4.2 + '@types/tar-stream': + specifier: ^3.1.3 + version: 3.1.3 scripts: dependencies: From f25b73589736b12c00cf8243295c76ded98691b9 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 6 Dec 2024 11:02:28 -0800 Subject: [PATCH 524/730] Prep tar-parser for release --- packages/tar-parser/README.md | 38 ++++++++- packages/tar-parser/bench/package.json | 2 + packages/tar-parser/bench/parsers/node-tar.ts | 21 +++++ .../tar-parser/bench/parsers/tar-parser.ts | 4 +- packages/tar-parser/bench/runner.ts | 10 ++- packages/tar-parser/bench/tsconfig.json | 8 -- packages/tar-parser/{bench => }/global.d.ts | 0 packages/tar-parser/package.json | 36 +++++--- packages/tar-parser/src/global.d.ts | 6 -- .../src/lib/{tar.spec.ts => tar.test.ts} | 82 +++++------------- packages/tar-parser/src/lib/tar.ts | 79 +++++++++++++++--- packages/tar-parser/src/tar-parser.ts | 4 +- packages/tar-parser/tsconfig.json | 12 ++- packages/tar-parser/tsconfig.lib.json | 9 -- packages/tar-parser/tsconfig.spec.json | 8 -- packages/tar-parser/tsup.config.ts | 9 ++ pnpm-lock.yaml | 83 +++++++++++++++++-- 17 files changed, 279 insertions(+), 132 deletions(-) create mode 100644 packages/tar-parser/bench/parsers/node-tar.ts delete mode 100644 packages/tar-parser/bench/tsconfig.json rename packages/tar-parser/{bench => }/global.d.ts (100%) delete mode 100644 packages/tar-parser/src/global.d.ts rename packages/tar-parser/src/lib/{tar.spec.ts => tar.test.ts} (82%) delete mode 100644 packages/tar-parser/tsconfig.lib.json delete mode 100644 packages/tar-parser/tsconfig.spec.json create mode 100644 packages/tar-parser/tsup.config.ts diff --git a/packages/tar-parser/README.md b/packages/tar-parser/README.md index 89c379c4884..9052f53e18b 100644 --- a/packages/tar-parser/README.md +++ b/packages/tar-parser/README.md @@ -5,7 +5,8 @@ ## Features - Runs anywhere JavaScript runs -- Built on the standard [web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) +- Built on the standard [web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API), so it's composable with `fetch()` streams +- Supports POSIX, GNU, and PAX tar formats - Memory efficient and does not buffer anything in normal usage - 0 dependencies @@ -19,11 +20,42 @@ npm install @mjackson/tar-parser ## Usage -## Related Packages +```ts +import { parseTar } from '@mjackson/tar-parser'; + +let response = await fetch( + 'https://github.com/mjackson/remix-the-web/archive/refs/heads/main.tar.gz', +); + +await parseTar(response.body.pipeThrough(new DecompressionStream('gzip')), (entry) => { + console.log(entry.name, entry.size); +}); +``` + +## Benchmark + +`tar-parser` performs on par with other popular TAR parsing libraries on Node.js. + +``` +> @mjackson/tar-parser@0.0.0 bench /Users/michael/Projects/remix-the-web/packages/tar-parser +> node --experimental-strip-types --disable-warning=ExperimentalWarning ./bench/runner.ts + +Platform: Darwin (24.0.0) +CPU: Apple M1 Pro +Date: 12/6/2024, 11:00:55 AM +Node.js v22.8.0 +┌────────────┬────────────────────┐ +│ (index) │ lodash npm package │ +├────────────┼────────────────────┤ +│ tar-parser │ '6.23 ms ± 0.58' │ +│ tar-stream │ '6.72 ms ± 2.24' │ +│ node-tar │ '6.49 ms ± 0.44' │ +└────────────┴────────────────────┘ +``` ## Credits -`tar-parser` is based on Node's excellent [tar-stream package](https://www.npmjs.com/package/tar-stream) (MIT license) and adopts the same core parsing algorithm, utility functions, and many test cases. +`tar-parser` is based on the excellent [tar-stream package](https://www.npmjs.com/package/tar-stream) (MIT license) and adopts the same core parsing algorithm, utility functions, and many test cases. ## License diff --git a/packages/tar-parser/bench/package.json b/packages/tar-parser/bench/package.json index 17548a3fd60..4100dc813c4 100644 --- a/packages/tar-parser/bench/package.json +++ b/packages/tar-parser/bench/package.json @@ -6,10 +6,12 @@ "@mjackson/lazy-file": "workspace:*", "@mjackson/tar-parser": "workspace:*", "gunzip-maybe": "^1.4.2", + "tar": "^7.4.3", "tar-stream": "^3.1.7" }, "devDependencies": { "@types/gunzip-maybe": "^1.4.2", + "@types/tar": "^6.1.13", "@types/tar-stream": "^3.1.3" } } diff --git a/packages/tar-parser/bench/parsers/node-tar.ts b/packages/tar-parser/bench/parsers/node-tar.ts new file mode 100644 index 00000000000..923bd6442f2 --- /dev/null +++ b/packages/tar-parser/bench/parsers/node-tar.ts @@ -0,0 +1,21 @@ +import * as fs from 'node:fs'; +import * as tar from 'tar'; + +export async function parse(filename: string): Promise<number> { + let stream = fs.createReadStream(filename); + + let start = performance.now(); + + await new Promise<void>((resolve, reject) => { + stream + .pipe(tar.t()) + .on('entry', (entry) => { + entry.resume(); + }) + .on('finish', () => { + resolve(); + }); + }); + + return performance.now() - start; +} diff --git a/packages/tar-parser/bench/parsers/tar-parser.ts b/packages/tar-parser/bench/parsers/tar-parser.ts index f905e766aa4..18f40b1a788 100644 --- a/packages/tar-parser/bench/parsers/tar-parser.ts +++ b/packages/tar-parser/bench/parsers/tar-parser.ts @@ -1,4 +1,4 @@ -import { TarParser } from '@mjackson/tar-parser'; +import { parseTar } from '@mjackson/tar-parser'; import { openFile } from '@mjackson/lazy-file/fs'; export async function parse(filename: string): Promise<number> { @@ -6,7 +6,7 @@ export async function parse(filename: string): Promise<number> { let start = performance.now(); - await new TarParser().parse(stream, (_file) => { + await parseTar(stream, (_entry) => { // Do nothing }); diff --git a/packages/tar-parser/bench/runner.ts b/packages/tar-parser/bench/runner.ts index f238dba19eb..6d086b57bef 100644 --- a/packages/tar-parser/bench/runner.ts +++ b/packages/tar-parser/bench/runner.ts @@ -1,10 +1,11 @@ import * as os from 'node:os'; import * as process from 'node:process'; -import { fixtures } from '../test/utils.js'; +import { fixtures } from '../test/utils.ts'; -import * as tarParser from './parsers/tar-parser.js'; -import * as tarStream from './parsers/tar-stream.js'; +import * as nodeTar from './parsers/node-tar.ts'; +import * as tarParser from './parsers/tar-parser.ts'; +import * as tarStream from './parsers/tar-stream.ts'; const benchmarks = [{ name: 'lodash npm package', filename: fixtures.lodashNpmPackage }]; @@ -52,6 +53,9 @@ async function runBenchmarks(parserName?: string): Promise<BenchmarkResults> { if (parserName === 'tar-stream' || parserName === undefined) { results['tar-stream'] = await runParserBenchmarks(tarStream); } + if (parserName === 'node-tar' || parserName === undefined) { + results['node-tar'] = await runParserBenchmarks(nodeTar); + } return results; } diff --git a/packages/tar-parser/bench/tsconfig.json b/packages/tar-parser/bench/tsconfig.json deleted file mode 100644 index d8aaef54f9d..00000000000 --- a/packages/tar-parser/bench/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "lib": ["DOM", "ES2020"], - "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true - } -} diff --git a/packages/tar-parser/bench/global.d.ts b/packages/tar-parser/global.d.ts similarity index 100% rename from packages/tar-parser/bench/global.d.ts rename to packages/tar-parser/global.d.ts diff --git a/packages/tar-parser/package.json b/packages/tar-parser/package.json index 981a845a02e..39e27b790ab 100644 --- a/packages/tar-parser/package.json +++ b/packages/tar-parser/package.json @@ -3,35 +3,51 @@ "version": "0.0.0", "description": "A fast, efficient parser for tar streams in any JavaScript environment", "author": "Michael Jackson <mjijackson@gmail.com>", + "license": "MIT", "repository": { "type": "git", "url": "git+https://github.com/mjackson/remix-the-web.git", "directory": "packages/tar-parser" }, "homepage": "https://github.com/mjackson/remix-the-web/tree/main/packages/tar-parser#readme", - "license": "MIT", "files": [ "dist", "LICENSE", "README.md" ], "type": "module", + "types": "./dist/tar-parser.d.ts", + "main": "./dist/tar-parser.js", "exports": { - ".": "./dist/tar-parser.js", + ".": { + "module-sync": { + "types": "./dist/tar-parser.d.ts", + "default": "./dist/tar-parser.js" + }, + "import": { + "types": "./dist/tar-parser.d.ts", + "default": "./dist/tar-parser.js" + }, + "require": { + "types": "./dist/tar-parser.d.cts", + "default": "./dist/tar-parser.cjs" + }, + "default": { + "types": "./dist/tar-parser.d.ts", + "default": "./dist/tar-parser.js" + } + }, "./package.json": "./package.json" }, "devDependencies": { "@mjackson/lazy-file": "workspace:^", - "@swc-node/register": "^1.10.9", - "@types/node": "^20.14.10", - "typescript": "^5.6.3" + "@types/node": "^20.14.10" }, "scripts": { - "bench": "node --import @swc-node/register/esm-register ./bench/runner.ts", - "build": "tsc --outDir dist --project tsconfig.lib.json", - "test": "node --import @swc-node/register/esm-register --test ./src/**/*.spec.ts", - "prepare": "pnpm run build", - "release": "node --import @swc-node/register/esm-register ../../scripts/release.ts" + "bench": "node --experimental-strip-types --disable-warning=ExperimentalWarning ./bench/runner.ts", + "build": "tsup", + "test": "node --experimental-strip-types --disable-warning=ExperimentalWarning --test ./src/**/*.test.ts", + "prepare": "pnpm run build" }, "keywords": [ "tar", diff --git a/packages/tar-parser/src/global.d.ts b/packages/tar-parser/src/global.d.ts deleted file mode 100644 index b8041179bc5..00000000000 --- a/packages/tar-parser/src/global.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -// See https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62651 - -interface ReadableStream<R = any> { - values(options?: { preventCancel?: boolean }): AsyncIterableIterator<R>; - [Symbol.asyncIterator](): AsyncIterableIterator<R>; -} diff --git a/packages/tar-parser/src/lib/tar.spec.ts b/packages/tar-parser/src/lib/tar.test.ts similarity index 82% rename from packages/tar-parser/src/lib/tar.spec.ts rename to packages/tar-parser/src/lib/tar.test.ts index 1b265f08eb6..46c0df81dac 100644 --- a/packages/tar-parser/src/lib/tar.spec.ts +++ b/packages/tar-parser/src/lib/tar.test.ts @@ -1,9 +1,9 @@ -import { describe, it } from 'node:test'; import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; -import { fixtures, readFixture } from '../../test/utils.js'; +import { fixtures, readFixture } from '../../test/utils.ts'; -import { TarHeader, TarParser } from './tar.js'; +import { type TarHeader, parseTar } from './tar.ts'; async function bufferStream( stream: ReadableStream<Uint8Array>, @@ -23,10 +23,8 @@ async function bufferStream( describe('TarParser', () => { it('parses express-4.21.1.tgz', async () => { - let parser = new TarParser(); - let entries: [string, number][] = []; - await parser.parse(readFixture(fixtures.expressNpmPackage), (entry) => { + await parseTar(readFixture(fixtures.expressNpmPackage), (entry) => { entries.push([entry.name, entry.size]); }); @@ -51,10 +49,8 @@ describe('TarParser', () => { }); it('parses fetch-proxy-0.1.0.tar.gz', async () => { - let parser = new TarParser(); - let entries: [string, number][] = []; - await parser.parse(readFixture(fixtures.fetchProxyGithubArchive), (entry) => { + await parseTar(readFixture(fixtures.fetchProxyGithubArchive), (entry) => { entries.push([entry.name, entry.size]); }); @@ -62,10 +58,8 @@ describe('TarParser', () => { }); it('parses lodash-4.17.21.tgz', async () => { - let parser = new TarParser(); - let entries: [string, number][] = []; - await parser.parse(readFixture(fixtures.lodashNpmPackage), (entry) => { + await parseTar(readFixture(fixtures.lodashNpmPackage), (entry) => { entries.push([entry.name, entry.size]); }); @@ -75,10 +69,8 @@ describe('TarParser', () => { describe('tar-stream test cases', () => { it('parses one-file.tar', async () => { - let parser = new TarParser(); - let entries: [TarHeader, string][] = []; - await parser.parse(readFixture(fixtures.oneFile), async (entry) => { + await parseTar(readFixture(fixtures.oneFile), async (entry) => { entries.push([entry.header, await bufferStream(entry.body)]); }); @@ -105,10 +97,8 @@ describe('tar-stream test cases', () => { }); it('parses multi-file.tar', async () => { - let parser = new TarParser(); - let entries: [TarHeader, string][] = []; - await parser.parse(readFixture(fixtures.multiFile), async (entry) => { + await parseTar(readFixture(fixtures.multiFile), async (entry) => { entries.push([entry.header, await bufferStream(entry.body)]); }); @@ -153,10 +143,8 @@ describe('tar-stream test cases', () => { }); it('parses pax.tar', async () => { - let parser = new TarParser(); - let entries: [TarHeader, string][] = []; - await parser.parse(readFixture(fixtures.pax), async (entry) => { + await parseTar(readFixture(fixtures.pax), async (entry) => { entries.push([entry.header, await bufferStream(entry.body)]); }); @@ -186,10 +174,8 @@ describe('tar-stream test cases', () => { }); it('parses types.tar', async () => { - let parser = new TarParser(); - let headers: TarHeader[] = []; - await parser.parse(readFixture(fixtures.types), async (entry) => { + await parseTar(readFixture(fixtures.types), async (entry) => { headers.push(entry.header); }); @@ -228,10 +214,8 @@ describe('tar-stream test cases', () => { }); it('parses long-name.tar', async () => { - let parser = new TarParser(); - let entries: [TarHeader, string][] = []; - await parser.parse(readFixture(fixtures.longName), async (entry) => { + await parseTar(readFixture(fixtures.longName), async (entry) => { entries.push([entry.header, await bufferStream(entry.body)]); }); @@ -258,10 +242,8 @@ describe('tar-stream test cases', () => { }); it('parses unicode-bsd.tar', async () => { - let parser = new TarParser(); - let headers: TarHeader[] = []; - await parser.parse(readFixture(fixtures.unicodeBsd), async (entry) => { + await parseTar(readFixture(fixtures.unicodeBsd), async (entry) => { headers.push(entry.header); }); @@ -292,10 +274,8 @@ describe('tar-stream test cases', () => { }); it('parses unicode.tar', async () => { - let parser = new TarParser(); - let headers: TarHeader[] = []; - await parser.parse(readFixture(fixtures.unicode), async (entry) => { + await parseTar(readFixture(fixtures.unicode), async (entry) => { headers.push(entry.header); }); @@ -319,10 +299,8 @@ describe('tar-stream test cases', () => { }); it('parses name-is-100.tar', async () => { - let parser = new TarParser(); - let entries: [number, string][] = []; - await parser.parse(readFixture(fixtures.nameIs100), async (entry) => { + await parseTar(readFixture(fixtures.nameIs100), async (entry) => { entries.push([entry.header.name.length, await bufferStream(entry.body)]); }); @@ -330,10 +308,8 @@ describe('tar-stream test cases', () => { }); it('parses space.tar', async () => { - let parser = new TarParser(); - let entries: [TarHeader, string][] = []; - await parser.parse(readFixture(fixtures.space), async (entry) => { + await parseTar(readFixture(fixtures.space), async (entry) => { entries.push([entry.header, await bufferStream(entry.body)]); }); @@ -341,10 +317,8 @@ describe('tar-stream test cases', () => { }); it('parses gnu-long-path.tar', async () => { - let parser = new TarParser(); - let entries: [TarHeader, string][] = []; - await parser.parse(readFixture(fixtures.gnuLongPath), async (entry) => { + await parseTar(readFixture(fixtures.gnuLongPath), async (entry) => { entries.push([entry.header, await bufferStream(entry.body)]); }); @@ -352,10 +326,8 @@ describe('tar-stream test cases', () => { }); it('parses base-256-uid-gid.tar', async () => { - let parser = new TarParser(); - let headers: TarHeader[] = []; - await parser.parse(readFixture(fixtures.base256UidGid), async (entry) => { + await parseTar(readFixture(fixtures.base256UidGid), async (entry) => { headers.push(entry.header); }); @@ -365,10 +337,8 @@ describe('tar-stream test cases', () => { }); it('parses base-256-size.tar', async () => { - let parser = new TarParser(); - let headers: TarHeader[] = []; - await parser.parse(readFixture(fixtures.base256Size), async (entry) => { + await parseTar(readFixture(fixtures.base256Size), async (entry) => { headers.push(entry.header); }); @@ -392,10 +362,8 @@ describe('tar-stream test cases', () => { }); it('parses latin1.tar', async () => { - let parser = new TarParser({ filenameEncoding: 'latin1' }); - let entries: [TarHeader, string][] = []; - await parser.parse(readFixture(fixtures.latin1), async (entry) => { + await parseTar(readFixture(fixtures.latin1), { filenameEncoding: 'latin1' }, async (entry) => { entries.push([entry.header, await bufferStream(entry.body)]); }); @@ -422,11 +390,9 @@ describe('tar-stream test cases', () => { }); it('throws when parsing incomplete.tar', async () => { - let parser = new TarParser(); - await assert.rejects( async () => { - await parser.parse(readFixture(fixtures.incomplete), () => {}); + await parseTar(readFixture(fixtures.incomplete), () => {}); }, { name: 'TarParseError', @@ -436,10 +402,8 @@ describe('tar-stream test cases', () => { }); it('parses gnu.tar', async () => { - let parser = new TarParser(); - let entries: [TarHeader, string][] = []; - await parser.parse(readFixture(fixtures.gnu), async (entry) => { + await parseTar(readFixture(fixtures.gnu), async (entry) => { entries.push([entry.header, await bufferStream(entry.body)]); }); @@ -466,10 +430,8 @@ describe('tar-stream test cases', () => { }); it('parses gnu-incremental.tar', async () => { - let parser = new TarParser(); - let entries: [TarHeader, string][] = []; - await parser.parse(readFixture(fixtures.gnuIncremental), async (entry) => { + await parseTar(readFixture(fixtures.gnuIncremental), async (entry) => { entries.push([entry.header, await bufferStream(entry.body)]); }); diff --git a/packages/tar-parser/src/lib/tar.ts b/packages/tar-parser/src/lib/tar.ts index d28f844b024..7f03c88eedc 100644 --- a/packages/tar-parser/src/lib/tar.ts +++ b/packages/tar-parser/src/lib/tar.ts @@ -7,7 +7,7 @@ import { getOctal, getString, overflow, -} from './utils.js'; +} from './utils.ts'; const TarBlockSize = 512; @@ -71,8 +71,9 @@ export interface ParseTarHeaderOptions { /** * Parses a tar header block. + * * @param block The tar header block - * @param options + * @param options Options that control how the header is parsed * @returns The parsed tar header */ export function parseTarHeader(block: Uint8Array, options?: ParseTarHeaderOptions): TarHeader { @@ -143,6 +144,56 @@ export function parseTarHeader(block: Uint8Array, options?: ParseTarHeaderOption return header; } +type TarArchiveSource = + | ReadableStream<Uint8Array> + | Uint8Array + | Iterable<Uint8Array> + | AsyncIterable<Uint8Array>; + +export type ParseTarOptions = ParseTarHeaderOptions; + +/** + * Parses a tar archive and calls the given handler for each entry it contains. + * + * Example: + * + * ```ts + * import { parseTar } from '@mjackson/tar-parser'; + * + * await parseTar(archive, (entry) => { + * console.log(entry.name); + * }); + * ``` + * + * @param archive The tar archive source data + * @param handler A function to call for each entry in the archive + * @returns A promise that resolves when the parse is finished + */ +export async function parseTar( + archive: TarArchiveSource, + handler: (entry: TarEntry) => void, +): Promise<void>; +export async function parseTar( + archive: TarArchiveSource, + options: ParseTarOptions, + handler: (entry: TarEntry) => void, +): Promise<void>; +export async function parseTar( + archive: TarArchiveSource, + options: ParseTarOptions | ((entry: TarEntry) => void), + handler?: (entry: TarEntry) => void, +): Promise<void> { + let opts: ParseTarOptions | undefined; + if (typeof options === 'function') { + handler = options; + } else { + opts = options; + } + + let parser = new TarParser(opts); + await parser.parse(archive, handler!); +} + export type TarParserOptions = ParseTarHeaderOptions; /** @@ -161,6 +212,9 @@ export class TarParser { #options?: TarParserOptions; + /** + * @param options Options that control how the tar archive is parsed + */ constructor(options?: TarParserOptions) { this.#options = options; } @@ -168,15 +222,12 @@ export class TarParser { /** * Parse a stream/buffer tar archive and call the given handler for each entry it contains. * Resolves when the parse is finished and all handlers resolve. + * + * @param archive The tar archive source data + * @param handler A function to call for each entry in the archive + * @returns A promise that resolves when the parse is finished */ - async parse( - archive: - | ReadableStream<Uint8Array> - | Uint8Array - | Iterable<Uint8Array> - | AsyncIterable<Uint8Array>, - handler: (entry: TarEntry) => void, - ): Promise<void> { + async parse(archive: TarArchiveSource, handler: (entry: TarEntry) => void): Promise<void> { this.#reset(); let results: unknown[] = []; @@ -375,13 +426,17 @@ export class TarEntry { #body: ReadableStream<Uint8Array>; #bodyUsed = false; + /** + * @param header The header info for this entry + * @param body The entry's content as a stream of `Uint8Array` chunks + */ constructor(header: TarHeader, body: ReadableStream<Uint8Array>) { this.#header = header; this.#body = body; } /** - * The content of this entry as an `ArrayBuffer`. + * The content of this entry as an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer). */ async arrayBuffer(): Promise<ArrayBuffer> { return (await this.bytes()).buffer as ArrayBuffer; @@ -402,7 +457,7 @@ export class TarEntry { } /** - * The content of this entry buffered into a single `Uint8Array`. + * The content of this entry buffered into a single typed array. */ async bytes(): Promise<Uint8Array> { if (this.#bodyUsed) { diff --git a/packages/tar-parser/src/tar-parser.ts b/packages/tar-parser/src/tar-parser.ts index b363fdd9f95..7f58f09de17 100644 --- a/packages/tar-parser/src/tar-parser.ts +++ b/packages/tar-parser/src/tar-parser.ts @@ -3,7 +3,9 @@ export { type TarHeader, type ParseTarHeaderOptions, parseTarHeader, + type ParseTarOptions, + parseTar, type TarParserOptions, TarParser, TarEntry, -} from './lib/tar.js'; +} from './lib/tar.ts'; diff --git a/packages/tar-parser/tsconfig.json b/packages/tar-parser/tsconfig.json index d8aaef54f9d..745cb65a640 100644 --- a/packages/tar-parser/tsconfig.json +++ b/packages/tar-parser/tsconfig.json @@ -1,8 +1,12 @@ { "compilerOptions": { - "lib": ["DOM", "ES2020"], - "module": "NodeNext", - "moduleResolution": "NodeNext", - "strict": true + "strict": true, + "lib": ["DOM", "DOM.Iterable", "ES2020"], + "module": "ES2022", + "moduleResolution": "Bundler", + "target": "ESNext", + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + "verbatimModuleSyntax": true } } diff --git a/packages/tar-parser/tsconfig.lib.json b/packages/tar-parser/tsconfig.lib.json deleted file mode 100644 index 8e712f7d6c8..00000000000 --- a/packages/tar-parser/tsconfig.lib.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts"], - "compilerOptions": { - "composite": true, - "rootDir": "src" - } -} diff --git a/packages/tar-parser/tsconfig.spec.json b/packages/tar-parser/tsconfig.spec.json deleted file mode 100644 index 547e6dabbd4..00000000000 --- a/packages/tar-parser/tsconfig.spec.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["src/**/*.spec.ts", "test/**/*.ts"], - "compilerOptions": { - "composite": true, - "types": ["node"] - } -} diff --git a/packages/tar-parser/tsup.config.ts b/packages/tar-parser/tsup.config.ts new file mode 100644 index 00000000000..15e71b354f0 --- /dev/null +++ b/packages/tar-parser/tsup.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig({ + clean: true, + dts: true, + entry: ['src/tar-parser.ts'], + format: ['cjs', 'esm'], + platform: 'neutral', +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1359f645076..8225f0d203f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -208,15 +208,9 @@ importers: '@mjackson/lazy-file': specifier: workspace:^ version: link:../lazy-file - '@swc-node/register': - specifier: ^1.10.9 - version: 1.10.9(@swc/core@1.5.29(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.6.3) '@types/node': specifier: ^20.14.10 version: 20.16.1 - typescript: - specifier: ^5.6.3 - version: 5.7.2 packages/tar-parser/bench: dependencies: @@ -229,6 +223,9 @@ importers: gunzip-maybe: specifier: ^1.4.2 version: 1.4.2 + tar: + specifier: ^7.4.3 + version: 7.4.3 tar-stream: specifier: ^3.1.7 version: 3.1.7 @@ -236,6 +233,9 @@ importers: '@types/gunzip-maybe': specifier: ^1.4.2 version: 1.4.2 + '@types/tar': + specifier: ^6.1.13 + version: 6.1.13 '@types/tar-stream': specifier: ^3.1.3 version: 3.1.3 @@ -599,6 +599,10 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -873,6 +877,9 @@ packages: '@types/tar-stream@3.1.3': resolution: {integrity: sha512-Zbnx4wpkWBMBSu5CytMbrT5ZpMiF55qgM+EpHzR4yIDu7mv52cej8hTkOc6K+LzpkOAbxwn/m7j3iO+/l42YkQ==} + '@types/tar@6.1.13': + resolution: {integrity: sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw==} + '@types/tmp@0.2.6': resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} @@ -990,6 +997,10 @@ packages: resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} engines: {node: '>= 14.16.0'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1336,10 +1347,23 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + minipass@4.2.8: + resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} + engines: {node: '>=8'} + minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + mrmime@2.0.0: resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} engines: {node: '>=10'} @@ -1527,6 +1551,10 @@ packages: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + rollup-plugin-inject@3.0.2: resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. @@ -1655,6 +1683,10 @@ packages: tar-stream@3.1.7: resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + text-decoder@1.2.1: resolution: {integrity: sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==} @@ -1818,6 +1850,10 @@ packages: xxhash-wasm@1.0.2: resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + youch@3.3.3: resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} @@ -2014,6 +2050,10 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -2258,6 +2298,11 @@ snapshots: dependencies: '@types/node': 22.5.4 + '@types/tar@6.1.13': + dependencies: + '@types/node': 22.5.4 + minipass: 4.2.8 + '@types/tmp@0.2.6': {} '@types/ws@8.5.12': @@ -2389,6 +2434,8 @@ snapshots: dependencies: readdirp: 4.0.2 + chownr@3.0.0: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -2764,8 +2811,17 @@ snapshots: dependencies: brace-expansion: 2.0.1 + minipass@4.2.8: {} + minipass@7.1.2: {} + minizlib@3.0.1: + dependencies: + minipass: 7.1.2 + rimraf: 5.0.10 + + mkdirp@3.0.1: {} + mrmime@2.0.0: {} ms@2.0.0: {} @@ -2910,6 +2966,10 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + rollup-plugin-inject@3.0.2: dependencies: estree-walker: 0.6.1 @@ -3085,6 +3145,15 @@ snapshots: fast-fifo: 1.3.2 streamx: 2.20.1 + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.1 + mkdirp: 3.0.1 + yallist: 5.0.0 + text-decoder@1.2.1: {} thenify-all@1.6.0: @@ -3256,6 +3325,8 @@ snapshots: xxhash-wasm@1.0.2: {} + yallist@5.0.0: {} + youch@3.3.3: dependencies: cookie: 0.5.0 From c449177a3c71f749ab486c53e231f938fd305212 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 6 Dec 2024 11:14:14 -0800 Subject: [PATCH 525/730] Update README --- packages/tar-parser/README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/tar-parser/README.md b/packages/tar-parser/README.md index 9052f53e18b..51e5bad949a 100644 --- a/packages/tar-parser/README.md +++ b/packages/tar-parser/README.md @@ -20,6 +20,8 @@ npm install @mjackson/tar-parser ## Usage +The main parser interface is the `parseTar(archive, handler)` function: + ```ts import { parseTar } from '@mjackson/tar-parser'; @@ -32,9 +34,19 @@ await parseTar(response.body.pipeThrough(new DecompressionStream('gzip')), (entr }); ``` +If you're parsing an archive with filename encodings other than UTF-8, use the `filenameEncoding` option: + +```ts +let response = await fetch(/* ... */); + +await parseTar(response.body, { filenameEncoding: 'latin1' }, (entry) => { + console.log(entry.name, entry.size); +}); +``` + ## Benchmark -`tar-parser` performs on par with other popular TAR parsing libraries on Node.js. +`tar-parser` performs on par with other popular tar parsing libraries on Node.js. ``` > @mjackson/tar-parser@0.0.0 bench /Users/michael/Projects/remix-the-web/packages/tar-parser From 86df49559fcd99227aecfcb4cbc51e981ece8609 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 6 Dec 2024 11:16:38 -0800 Subject: [PATCH 526/730] Add missing dep --- packages/tar-parser/package.json | 3 ++- pnpm-lock.yaml | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/tar-parser/package.json b/packages/tar-parser/package.json index 39e27b790ab..6408b667166 100644 --- a/packages/tar-parser/package.json +++ b/packages/tar-parser/package.json @@ -41,7 +41,8 @@ }, "devDependencies": { "@mjackson/lazy-file": "workspace:^", - "@types/node": "^20.14.10" + "@types/node": "^20.14.10", + "tsup": "^8.3.5" }, "scripts": { "bench": "node --experimental-strip-types --disable-warning=ExperimentalWarning ./bench/runner.ts", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8225f0d203f..0da4f1a2e5a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -211,6 +211,9 @@ importers: '@types/node': specifier: ^20.14.10 version: 20.16.1 + tsup: + specifier: ^8.3.5 + version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.7.2) packages/tar-parser/bench: dependencies: From b04f6f09c83e4a56fc50858200da942809fd9593 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 6 Dec 2024 11:17:50 -0800 Subject: [PATCH 527/730] Release tar-parser@0.1.0 --- packages/tar-parser/CHANGELOG.md | 2 +- packages/tar-parser/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/tar-parser/CHANGELOG.md b/packages/tar-parser/CHANGELOG.md index d4a40e60478..836c7c0bb18 100644 --- a/packages/tar-parser/CHANGELOG.md +++ b/packages/tar-parser/CHANGELOG.md @@ -1,3 +1,3 @@ -## HEAD +## v0.1.0 (2024-12-06) - Initial release diff --git a/packages/tar-parser/package.json b/packages/tar-parser/package.json index 6408b667166..16aad2addd2 100644 --- a/packages/tar-parser/package.json +++ b/packages/tar-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/tar-parser", - "version": "0.0.0", + "version": "0.1.0", "description": "A fast, efficient parser for tar streams in any JavaScript environment", "author": "Michael Jackson <mjijackson@gmail.com>", "license": "MIT", From 411a8dcf47ba61f59c61ac36c4953ccbd83d5822 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 6 Dec 2024 22:15:00 -0800 Subject: [PATCH 528/730] Re-export everything from multipart-parser/node --- packages/multipart-parser/CHANGELOG.md | 4 ++++ packages/multipart-parser/examples/node/server.js | 3 +-- packages/multipart-parser/src/lib/multipart.node.ts | 12 ++++++------ .../multipart-parser/src/multipart-parser.node.ts | 10 ++++++++++ 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index ad68d7cf970..7ccc4bb3ca1 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -2,6 +2,10 @@ This is the changelog for [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Re-export everything from `multipart-parser/node` because we have a separate bundle for Node.js now, so everything should be imported from there when using it. + ## v0.7.0 (2024-11-14) - Added CommonJS build diff --git a/packages/multipart-parser/examples/node/server.js b/packages/multipart-parser/examples/node/server.js index 332d0e27232..023d17ad90b 100644 --- a/packages/multipart-parser/examples/node/server.js +++ b/packages/multipart-parser/examples/node/server.js @@ -2,8 +2,7 @@ import * as fs from 'node:fs'; import * as http from 'node:http'; import tmp from 'tmp'; -import { MultipartParseError } from '@mjackson/multipart-parser'; -import { parseMultipartRequest } from '@mjackson/multipart-parser/node'; +import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser/node'; const PORT = 3000; diff --git a/packages/multipart-parser/src/lib/multipart.node.ts b/packages/multipart-parser/src/lib/multipart.node.ts index a550a1da8ab..4c560f175f0 100644 --- a/packages/multipart-parser/src/lib/multipart.node.ts +++ b/packages/multipart-parser/src/lib/multipart.node.ts @@ -12,8 +12,8 @@ import { /** * Returns true if the given request is a multipart request. */ -export function isMultipartRequest(request: http.IncomingMessage): boolean { - let contentType = request.headers['content-type']; +export function isMultipartRequest(req: http.IncomingMessage): boolean { + let contentType = req.headers['content-type']; return contentType != null && /^multipart\//i.test(contentType); } @@ -21,19 +21,19 @@ export function isMultipartRequest(request: http.IncomingMessage): boolean { * Parse a multipart Node.js request and yield each part as a `MultipartPart` object. */ export async function* parseMultipartRequest( - request: http.IncomingMessage, + req: http.IncomingMessage, options?: MultipartParserOptions, ): AsyncGenerator<MultipartPart> { - if (!isMultipartRequest(request)) { + if (!isMultipartRequest(req)) { throw new MultipartParseError('Request is not a multipart request'); } - let boundary = getMultipartBoundary(request.headers['content-type']!); + let boundary = getMultipartBoundary(req.headers['content-type']!); if (!boundary) { throw new MultipartParseError('Invalid Content-Type header: missing boundary'); } - yield* parseMultipart(request, boundary, options); + yield* parseMultipart(req, boundary, options); } /** diff --git a/packages/multipart-parser/src/multipart-parser.node.ts b/packages/multipart-parser/src/multipart-parser.node.ts index 44d317b8e0d..b5a1e33617c 100644 --- a/packages/multipart-parser/src/multipart-parser.node.ts +++ b/packages/multipart-parser/src/multipart-parser.node.ts @@ -1 +1,11 @@ +// Re-export all core functionality +export { + getMultipartBoundary, + MultipartParseError, + type MultipartParserOptions, + MultipartParser, + MultipartPart, +} from './lib/multipart.ts'; + +// Export Node.js-specific functionality export { isMultipartRequest, parseMultipartRequest, parseMultipart } from './lib/multipart.node.ts'; From 3c4b630e8ff15bc9aad85ed7b9a5c7975f61825f Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 6 Dec 2024 22:15:15 -0800 Subject: [PATCH 529/730] Release multipart-parser@0.7.1 --- packages/multipart-parser/CHANGELOG.md | 2 +- packages/multipart-parser/jsr.json | 2 +- packages/multipart-parser/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index 7ccc4bb3ca1..71d418df581 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.7.1 (2024-12-07) - Re-export everything from `multipart-parser/node` because we have a separate bundle for Node.js now, so everything should be imported from there when using it. diff --git a/packages/multipart-parser/jsr.json b/packages/multipart-parser/jsr.json index 45eb3932629..e20dd32e29b 100644 --- a/packages/multipart-parser/jsr.json +++ b/packages/multipart-parser/jsr.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.7.0", + "version": "0.7.1", "exports": "./src/multipart-parser.ts", "publish": { "include": [ diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index b8dd858508a..dfabf3c214f 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.7.0", + "version": "0.7.1", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From 0f4c63d8fa7637f90d62860834715816ffb195e3 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 6 Dec 2024 22:28:39 -0800 Subject: [PATCH 530/730] Update jsr.json --- packages/multipart-parser/jsr.json | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/multipart-parser/jsr.json b/packages/multipart-parser/jsr.json index e20dd32e29b..4325c3cc0d4 100644 --- a/packages/multipart-parser/jsr.json +++ b/packages/multipart-parser/jsr.json @@ -3,13 +3,6 @@ "version": "0.7.1", "exports": "./src/multipart-parser.ts", "publish": { - "include": [ - "LICENSE", - "README.md", - "src/**/*.ts", - "!src/test/", - "!src/**/*.spec.ts", - "!src/**/*.node.ts" - ] + "include": ["LICENSE", "README.md", "src/**/*.ts", "!src/**/*.node.ts", "!src/**/*.test.ts"] } } From 396cd7e9d9dc6a02cbd4240e557282ad5d07ec27 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 6 Dec 2024 23:12:13 -0800 Subject: [PATCH 531/730] Add workspaces key to root package.json --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 5636d9bfcc2..710ac98b49c 100644 --- a/package.json +++ b/package.json @@ -15,5 +15,8 @@ "publish-release-ci": "node ./scripts/publish-release.js", "tag-release": "node ./scripts/tag-release.js", "test": "pnpm -r --workspace-concurrency 1 test" - } + }, + "workspaces": [ + "packages/*" + ] } From 490566b942eed3cc883f1eece48daf87c746852b Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 6 Dec 2024 23:15:39 -0800 Subject: [PATCH 532/730] Update changelog --- packages/multipart-parser/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index 71d418df581..050bd427c4d 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -4,9 +4,9 @@ This is the changelog for [`multipart-parser`](https://github.com/mjackson/remix ## v0.7.1 (2024-12-07) -- Re-export everything from `multipart-parser/node` because we have a separate bundle for Node.js now, so everything should be imported from there when using it. +- Re-export everything from `multipart-parser/node`. If you're using `multipart-parser/node`, you should `import` everything from there. Don't import anything from `multipart-parser`. -## v0.7.0 (2024-11-14) +- ## v0.7.0 (2024-11-14) - Added CommonJS build From 3b7ee16e964898161a1d052832cdffee67344387 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 6 Dec 2024 23:20:22 -0800 Subject: [PATCH 533/730] Update README --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0b9cf8f04d8..6497c724bcc 100644 --- a/README.md +++ b/README.md @@ -21,12 +21,14 @@ The goal is that these packages should be useful for anyone who is building for We currently publish the following packages: +- [fetch-proxy](packages/fetch-proxy): Easily build HTTP proxies using the `fetch()` API - [file-storage](packages/file-storage): Key/value storage for JavaScript `File` objects - [form-data-parser](packages/form-data-parser): A `request.formData()` wrapper with streaming file upload handling - [headers](packages/headers): A toolkit for working with HTTP headers in JavaScript - [lazy-file](packages/lazy-file): Lazy, streaming `Blob`s and `File`s for JavaScript -- [multipart-parser](packages/multipart-parser): Fast, efficient parser for multipart streams -- [node-fetch-server](packages/node-fetch-server): Build HTTP servers for Node.js using the web fetch API +- [multipart-parser](packages/multipart-parser): Fast, streaming parser for multipart messages +- [node-fetch-server](packages/node-fetch-server): Build HTTP servers for Node.js using the web `fetch()` API +- [tar-parser](packages/tar-parser): Fast, streaming parser for tar archives ## License From aa26b073bd08187176671db8ffe869c62a67a1c3 Mon Sep 17 00:00:00 2001 From: Jacob Ebey <jacob.ebey@live.com> Date: Sun, 8 Dec 2024 14:44:52 -0800 Subject: [PATCH 534/730] feat: use object instead of array for sending headers Update `sendResponse` to use an object to add support for libraries such as express while maintaining `node:http` and `node:https` compatibility. --- packages/node-fetch-server/CHANGELOG.md | 1 + .../src/lib/request-listener.test.ts | 12 ++++-------- .../node-fetch-server/src/lib/request-listener.ts | 12 ++++++++++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index d162adb01fc..0defb352800 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -5,6 +5,7 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remi ## HEAD - Expose `createHeaders(req: http.IncomingMessage): Headers` API for creating headers from the headers of incoming request objects. +- Update `sendResponse` to use an object to add support for libraries such as express while maintaining `node:http` and `node:https` compatibility. ## v0.4.1 (2024-12-04) diff --git a/packages/node-fetch-server/src/lib/request-listener.test.ts b/packages/node-fetch-server/src/lib/request-listener.test.ts index 2edc7ec52ef..91bc0c17c0b 100644 --- a/packages/node-fetch-server/src/lib/request-listener.test.ts +++ b/packages/node-fetch-server/src/lib/request-listener.test.ts @@ -169,14 +169,10 @@ describe('createRequestListener', () => { }); mock.method(res, 'end', () => { - assert.deepEqual(headers, [ - 'content-type', - 'text/plain', - 'set-cookie', - 'a=1', - 'set-cookie', - 'b=2', - ]); + assert.deepEqual(headers, { + 'content-type': 'text/plain', + 'set-cookie': ['a=1', 'b=2'], + }); resolve(); }); diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 800a5fa68cb..63739ee51a7 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -188,9 +188,17 @@ export async function sendResponse(res: http.ServerResponse, response: Response) // Use the rawHeaders API and iterate over response.headers so we are sure to send multiple // Set-Cookie headers correctly. These would incorrectly be merged into a single header if we // tried to use `Object.fromEntries(response.headers.entries())`. - let rawHeaders: string[] = []; + let rawHeaders: Record<string, string | string[]> = {}; for (let [key, value] of response.headers) { - rawHeaders.push(key, value); + if (key in rawHeaders) { + if (Array.isArray(rawHeaders[key])) { + rawHeaders[key].push(value); + } else { + rawHeaders[key] = [rawHeaders[key] as string, value]; + } + } else { + rawHeaders[key] = value; + } } res.writeHead(response.status, rawHeaders); From 38b86cd8e8695e57f6b47f64bdbadafe1ba2df31 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Mon, 9 Dec 2024 11:35:37 -0800 Subject: [PATCH 535/730] Style tweaks --- .../src/lib/request-listener.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 63739ee51a7..5b6d8e0f9b2 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -185,23 +185,23 @@ export function createHeaders(req: http.IncomingMessage): Headers { * @param response The response to send. */ export async function sendResponse(res: http.ServerResponse, response: Response): Promise<void> { - // Use the rawHeaders API and iterate over response.headers so we are sure to send multiple - // Set-Cookie headers correctly. These would incorrectly be merged into a single header if we - // tried to use `Object.fromEntries(response.headers.entries())`. - let rawHeaders: Record<string, string | string[]> = {}; + // Iterate over response.headers so we are sure to send multiple Set-Cookie headers correctly. + // These would incorrectly be merged into a single header if we tried to use + // `Object.fromEntries(response.headers.entries())`. + let headers: Record<string, string | string[]> = {}; for (let [key, value] of response.headers) { - if (key in rawHeaders) { - if (Array.isArray(rawHeaders[key])) { - rawHeaders[key].push(value); + if (key in headers) { + if (Array.isArray(headers[key])) { + headers[key].push(value); } else { - rawHeaders[key] = [rawHeaders[key] as string, value]; + headers[key] = [headers[key] as string, value]; } } else { - rawHeaders[key] = value; + headers[key] = value; } } - res.writeHead(response.status, rawHeaders); + res.writeHead(response.status, headers); if (response.body != null && res.req.method !== 'HEAD') { for await (let chunk of response.body) { From dd64e351cb146ebfe07f3ca637d8e3c51d903493 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Mon, 9 Dec 2024 11:36:01 -0800 Subject: [PATCH 536/730] Release node-fetch-server@0.5.0 --- packages/node-fetch-server/CHANGELOG.md | 2 +- packages/node-fetch-server/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 0defb352800..939a79efbd9 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.5.0 (2024-12-09) - Expose `createHeaders(req: http.IncomingMessage): Headers` API for creating headers from the headers of incoming request objects. - Update `sendResponse` to use an object to add support for libraries such as express while maintaining `node:http` and `node:https` compatibility. diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index ad2b161e435..93388880cd4 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/node-fetch-server", - "version": "0.4.1", + "version": "0.5.0", "description": "Build servers for Node.js using the web fetch API", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From 6e56dc703147cd3be9f2fdc295b7c850e17c19ec Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 12 Dec 2024 11:17:08 -0800 Subject: [PATCH 537/730] Fix publish script --- scripts/publish-release.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/publish-release.js b/scripts/publish-release.js index 29da73151fa..70c4434c391 100644 --- a/scripts/publish-release.js +++ b/scripts/publish-release.js @@ -56,7 +56,7 @@ if (packageJson.version !== version) { process.exit(1); } -logAndExec(`npm publish --access public`, { +logAndExec(`pnpm publish --access public`, { cwd: getPackageDir(packageName), env: process.env, }); From 04ab17ce984b0c98bf21f69669ffe533e8cd3fb1 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 12 Dec 2024 11:20:15 -0800 Subject: [PATCH 538/730] Fix dependency on headers package --- packages/form-data-parser/CHANGELOG.md | 4 ++++ packages/multipart-parser/CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index 746f5b55230..f30f527f8fe 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -2,6 +2,10 @@ This is the changelog for [`form-data-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Fix dependency on `headers` in package.json + ## v0.5.0 (2024-11-14) - Added CommonJS build diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index 050bd427c4d..d9889ff4cc6 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -2,6 +2,10 @@ This is the changelog for [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Fix dependency on `headers` in package.json + ## v0.7.1 (2024-12-07) - Re-export everything from `multipart-parser/node`. If you're using `multipart-parser/node`, you should `import` everything from there. Don't import anything from `multipart-parser`. From 9e2b96182b7f93c0fc3fcdf95b6ebb9746c8c8f6 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 12 Dec 2024 11:20:32 -0800 Subject: [PATCH 539/730] Release form-data-parser@0.5.1 --- packages/form-data-parser/CHANGELOG.md | 2 +- packages/form-data-parser/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index f30f527f8fe..6f4063e7b73 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`form-data-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.5.1 (2024-12-12) - Fix dependency on `headers` in package.json diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index 7bac8a977b0..7700c12941f 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/form-data-parser", - "version": "0.5.0", + "version": "0.5.1", "description": "A request.formData() wrapper with streaming file upload handling", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From 782039b92d81416b85955b6cb523c529f33275d4 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 12 Dec 2024 11:20:45 -0800 Subject: [PATCH 540/730] Release multipart-parser@0.7.2 --- packages/multipart-parser/CHANGELOG.md | 2 +- packages/multipart-parser/jsr.json | 10 ++++++++-- packages/multipart-parser/package.json | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index d9889ff4cc6..e57831c6375 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.7.2 (2024-12-12) - Fix dependency on `headers` in package.json diff --git a/packages/multipart-parser/jsr.json b/packages/multipart-parser/jsr.json index 4325c3cc0d4..121c0e159b5 100644 --- a/packages/multipart-parser/jsr.json +++ b/packages/multipart-parser/jsr.json @@ -1,8 +1,14 @@ { "name": "@mjackson/multipart-parser", - "version": "0.7.1", + "version": "0.7.2", "exports": "./src/multipart-parser.ts", "publish": { - "include": ["LICENSE", "README.md", "src/**/*.ts", "!src/**/*.node.ts", "!src/**/*.test.ts"] + "include": [ + "LICENSE", + "README.md", + "src/**/*.ts", + "!src/**/*.node.ts", + "!src/**/*.test.ts" + ] } } diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index dfabf3c214f..93dc5017e95 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.7.1", + "version": "0.7.2", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From 2be502cc18d430e10bc7fd478a9d6e3bbf5e7167 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 12 Dec 2024 11:23:40 -0800 Subject: [PATCH 541/730] Skip git checks on publish --- scripts/publish-release.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/publish-release.js b/scripts/publish-release.js index 70c4434c391..4e6dc587e01 100644 --- a/scripts/publish-release.js +++ b/scripts/publish-release.js @@ -56,7 +56,7 @@ if (packageJson.version !== version) { process.exit(1); } -logAndExec(`pnpm publish --access public`, { +logAndExec(`pnpm publish --access public --no-git-checks`, { cwd: getPackageDir(packageName), env: process.env, }); From 1cc51e17a4f881c6c5694b9b82701dd42921918f Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Wed, 18 Dec 2024 16:18:46 -0800 Subject: [PATCH 542/730] Bunch of improvements to headers --- packages/headers/CHANGELOG.md | 40 ++ packages/headers/README.md | 36 +- .../headers/src/lib/super-headers.test.ts | 465 +++++++++++++++--- packages/headers/src/lib/super-headers.ts | 224 ++++++--- 4 files changed, 631 insertions(+), 134 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index ecf88b7c3a1..84f31dab817 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -2,6 +2,46 @@ This is the changelog for [`headers`](https://github.com/mjackson/remix-the-web/tree/main/packages/headers). It follows [semantic versioning](https://semver.org/). +## HEAD + +- BREAKING CHANGE: `headers.get()` returns `null` for uninitialized custom header values instead of `undefined`. This follows the native `Headers` interface more closely. + +```ts +// before +let headers = new SuperHeaders(); +headers.get('Host'); // null +headers.get('Content-Type'); // undefined + +// after +headers.get('Host'); // null +headers.get('Content-Type'); // null +``` + +- BREAKING CHANGE: `headers.set()` no longer accepts anything other than a string as the 2nd arg. This follows the native `Headers` interface more closely. + +```ts +// before +let headers = new SuperHeaders(); +headers.set('Content-Type', { mediaType: 'text/html' }); + +// after +headers.set('Content-Type', 'text/html'); + +// if you need the previous behavior, use the setter instead of set() +headers.contentType = { mediaType: 'text/html' }; +``` + +- All setter methods now also accept `undefined | null` in addition to `string` and custom object values. Setting a header to `undefined | null` is the same as using `headers.delete()`. + +```ts +// before +let headers = new SuperHeaders({ 'Content-Type': 'text/html' }); +headers.contentType; // 'text/html' + +headers.contentType = null; // same as headers.delete('Content-Type'); +headers.contentType; // null +``` + ## v0.8.0 (2024-11-14) - Added CommonJS build diff --git a/packages/headers/README.md b/packages/headers/README.md index ece3e29891c..e3a7d1b6048 100644 --- a/packages/headers/README.md +++ b/packages/headers/README.md @@ -61,22 +61,23 @@ headers.cookie.set('theme', 'dark'); console.log(headers.get('Cookie')); // 'session_id=abc123; user_id=12345; theme=dark' // Set-Cookie -headers.setCookie = 'session_id=abc123; Path=/; HttpOnly'; +headers.setCookie = ['session_id=abc123; Path=/; HttpOnly']; -console.log(headers.setCookie.name); // 'session_id' -console.log(headers.setCookie.value); // 'abc123' -console.log(headers.setCookie.path); // '/' -console.log(headers.setCookie.httpOnly); // true +console.log(headers.setCookie[0].name); // 'session_id' +console.log(headers.setCookie[0].value); // 'abc123' +console.log(headers.setCookie[0].path); // '/' +console.log(headers.setCookie[0].httpOnly); // true // Modifying Set-Cookie attributes -headers.setCookie.maxAge = 3600; -headers.setCookie.secure = true; +headers.setCookie[0].maxAge = 3600; +headers.setCookie[0].secure = true; console.log(headers.get('Set-Cookie')); // session_id=abc123; Path=/; HttpOnly; Max-Age=3600; Secure -// Setting multiple cookies -headers.append('Set-Cookie', 'user_id=12345; Path=/api; Secure'); +// Setting multiple cookies is easy, it's just an array +headers.setCookie.push('user_id=12345; Path=/api; Secure'); +// or headers.setCookie = [...headers.setCookie, '...'] // Accessing multiple Set-Cookie headers for (let cookie of headers.getSetCookie()) { @@ -163,12 +164,17 @@ All individual header classes may be initialized with either a) the string value The following headers are currently supported: -- [`Accept-Language`](#accept-language) -- [`Cache-Control`](#cache-control) -- [`Content-Disposition`](#content-disposition) -- [`Content-Type`](#content-type) -- [`Cookie`](#cookie) -- [`Set-Cookie`](#set-cookie) +- [headers](#headers) + - [Installation](#installation) + - [Overview](#overview) + - [Low-level API](#low-level-api) + - [Accept-Language](#accept-language) + - [Cache-Control](#cache-control) + - [Content-Disposition](#content-disposition) + - [Content-Type](#content-type) + - [Cookie](#cookie) + - [Set-Cookie](#set-cookie) + - [License](#license) If you need support for a header that isn't listed here, please [send a PR](https://github.com/mjackson/remix-the-web/pulls)! The goal is to have first-class support for all common HTTP headers. diff --git a/packages/headers/src/lib/super-headers.test.ts b/packages/headers/src/lib/super-headers.test.ts index 642418646f3..81e3fccedbd 100644 --- a/packages/headers/src/lib/super-headers.test.ts +++ b/packages/headers/src/lib/super-headers.test.ts @@ -195,158 +195,511 @@ describe('SuperHeaders', () => { ]); }); - describe('header-specific getters and setters', () => { - it('handles Accept-Language header', () => { + describe('setting values in the constructor', () => { + it('handles the Accept-Language header', () => { + let headers = new SuperHeaders({ acceptLanguage: 'en-US,en;q=0.9' }); + assert.equal(headers.get('Accept-Language'), 'en-US,en;q=0.9'); + }); + + it('handles the Age header', () => { + let headers = new SuperHeaders({ age: 42 }); + assert.equal(headers.get('Age'), '42'); + }); + + it('handles the Cache-Control header', () => { + let headers = new SuperHeaders({ cacheControl: 'public, max-age=3600' }); + assert.equal(headers.get('Cache-Control'), 'public, max-age=3600'); + }); + + it('handles the Content-Disposition header', () => { + let headers = new SuperHeaders({ contentDisposition: 'attachment; filename="example.txt"' }); + assert.equal(headers.get('Content-Disposition'), 'attachment; filename="example.txt"'); + }); + + it('handles the Content-Length header', () => { + let headers = new SuperHeaders({ contentLength: 42 }); + assert.equal(headers.get('Content-Length'), '42'); + }); + + it('handles the Content-Type header', () => { + let headers = new SuperHeaders({ contentType: 'text/plain; charset=utf-8' }); + assert.equal(headers.get('Content-Type'), 'text/plain; charset=utf-8'); + }); + + it('handles the Cookie header', () => { + let headers = new SuperHeaders({ cookie: 'name1=value1; name2=value2' }); + assert.equal(headers.get('Cookie'), 'name1=value1; name2=value2'); + }); + + it('handles the Expires header', () => { + let headers = new SuperHeaders({ expires: new Date('2021-01-01T00:00:00Z') }); + assert.equal(headers.get('Expires'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + }); + + it('handles the Last-Modified header', () => { + let headers = new SuperHeaders({ lastModified: new Date('2021-01-01T00:00:00Z') }); + assert.equal(headers.get('Last-Modified'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + }); + + it('handles the Set-Cookie header', () => { + let headers = new SuperHeaders({ setCookie: ['session=abc', 'theme=dark'] }); + assert.deepEqual(headers.getSetCookie(), ['session=abc', 'theme=dark']); + }); + + it('handles the Set-Cookie header with objects', () => { + let headers = new SuperHeaders({ + setCookie: [ + { name: 'session', value: 'abc' }, + { name: 'theme', value: 'dark' }, + ], + }); + assert.deepEqual(headers.getSetCookie(), ['session=abc', 'theme=dark']); + }); + + it('handles the Set-Cookie header with options', () => { + let headers = new SuperHeaders({ + setCookie: [ + { name: 'session', value: 'abc', path: '/' }, + { name: 'theme', value: 'dark', expires: new Date('2021-12-31T23:59:59Z') }, + ], + }); + assert.deepEqual(headers.getSetCookie(), [ + 'session=abc; Path=/', + 'theme=dark; Expires=Fri, 31 Dec 2021 23:59:59 GMT', + ]); + }); + }); + + describe('get() and set()', () => { + it('handles the Accept-Language header', () => { + let headers = new SuperHeaders({ 'Accept-Language': 'en-US,en;q=0.9' }); + assert.equal(headers.get('Accept-Language'), 'en-US,en;q=0.9'); + + headers.set('Accept-Language', 'en;q=0.8, fr'); + assert.equal(headers.get('Accept-Language'), 'en;q=0.8, fr'); + + headers.set('Accept-Language', ''); + assert.equal(headers.get('Accept-Language'), ''); + + headers.delete('Accept-Language'); + assert.equal(headers.get('Accept-Language'), null); + }); + + it('handles the Age header', () => { + let headers = new SuperHeaders({ Age: '42' }); + assert.equal(headers.get('Age'), '42'); + + headers.set('Age', '100'); + assert.equal(headers.get('Age'), '100'); + + headers.set('Age', ''); + assert.equal(headers.get('Age'), ''); + + headers.delete('Age'); + assert.equal(headers.get('Age'), null); + }); + + it('handles the Cache-Control header', () => { + let headers = new SuperHeaders({ 'Cache-Control': 'public, max-age=3600' }); + assert.equal(headers.get('Cache-Control'), 'public, max-age=3600'); + + headers.set('Cache-Control', 'no-cache'); + assert.equal(headers.get('Cache-Control'), 'no-cache'); + + headers.set('Cache-Control', ''); + assert.equal(headers.get('Cache-Control'), ''); + + headers.delete('Cache-Control'); + assert.equal(headers.get('Cache-Control'), null); + }); + + it('handles the Content-Disposition header', () => { let headers = new SuperHeaders({ - acceptLanguage: 'en-US,en;q=0.9', + 'Content-Disposition': 'attachment; filename="example.txt"', }); + assert.equal(headers.get('Content-Disposition'), 'attachment; filename="example.txt"'); + + headers.set('Content-Disposition', 'inline'); + assert.equal(headers.get('Content-Disposition'), 'inline'); + + headers.set('Content-Disposition', ''); + assert.equal(headers.get('Content-Disposition'), ''); + + headers.delete('Content-Disposition'); + assert.equal(headers.get('Content-Disposition'), null); + }); + + it('handles the Content-Length header', () => { + let headers = new SuperHeaders({ 'Content-Length': '42' }); + assert.equal(headers.get('Content-Length'), '42'); + + headers.set('Content-Length', '100'); + assert.equal(headers.get('Content-Length'), '100'); + + headers.set('Content-Length', ''); + assert.equal(headers.get('Content-Length'), ''); + + headers.delete('Content-Length'); + assert.equal(headers.get('Content-Length'), null); + }); + + it('handles the Content-Type header', () => { + let headers = new SuperHeaders({ 'Content-Type': 'text/plain; charset=utf-8' }); + assert.equal(headers.get('Content-Type'), 'text/plain; charset=utf-8'); + + headers.set('Content-Type', 'text/html'); + assert.equal(headers.get('Content-Type'), 'text/html'); + + headers.set('Content-Type', ''); + assert.equal(headers.get('Content-Type'), ''); + + headers.delete('Content-Type'); + assert.equal(headers.get('Content-Type'), null); + }); + + it('handles the Cookie header', () => { + let headers = new SuperHeaders({ Cookie: 'name1=value1; name2=value2' }); + assert.equal(headers.get('Cookie'), 'name1=value1; name2=value2'); + + headers.set('Cookie', 'name3=value3'); + assert.equal(headers.get('Cookie'), 'name3=value3'); + + headers.set('Cookie', ''); + assert.equal(headers.get('Cookie'), ''); + + headers.delete('Cookie'); + assert.equal(headers.get('Cookie'), null); + }); + + it('handles the Date header', () => { + let headers = new SuperHeaders({ Date: 'Fri, 01 Jan 2021 00:00:00 GMT' }); + assert.equal(headers.get('Date'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + + headers.set('Date', 'Fri, 31 Dec 2021 23:59:59 GMT'); + assert.equal(headers.get('Date'), 'Fri, 31 Dec 2021 23:59:59 GMT'); + + headers.set('Date', ''); + assert.equal(headers.get('Date'), ''); + + headers.delete('Date'); + assert.equal(headers.get('Date'), null); + }); + + it('handles the Expires header', () => { + let headers = new SuperHeaders({ Expires: 'Fri, 01 Jan 2021 00:00:00 GMT' }); + assert.equal(headers.get('Expires'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + + headers.set('Expires', 'Fri, 31 Dec 2021 23:59:59 GMT'); + assert.equal(headers.get('Expires'), 'Fri, 31 Dec 2021 23:59:59 GMT'); + + headers.set('Expires', ''); + assert.equal(headers.get('Expires'), ''); + + headers.delete('Expires'); + assert.equal(headers.get('Expires'), null); + }); + + it('handles the Last-Modified header', () => { + let headers = new SuperHeaders({ 'Last-Modified': 'Fri, 01 Jan 2021 00:00:00 GMT' }); + assert.equal(headers.get('Last-Modified'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + + headers.set('Last-Modified', 'Fri, 31 Dec 2021 23:59:59 GMT'); + assert.equal(headers.get('Last-Modified'), 'Fri, 31 Dec 2021 23:59:59 GMT'); + + headers.set('Last-Modified', ''); + assert.equal(headers.get('Last-Modified'), ''); + + headers.delete('Last-Modified'); + assert.equal(headers.get('Last-Modified'), null); + }); + + it('handles the If-Modified-Since header', () => { + let headers = new SuperHeaders({ 'If-Modified-Since': 'Fri, 01 Jan 2021 00:00:00 GMT' }); + assert.equal(headers.get('If-Modified-Since'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + + headers.set('If-Modified-Since', 'Fri, 31 Dec 2021 23:59:59 GMT'); + assert.equal(headers.get('If-Modified-Since'), 'Fri, 31 Dec 2021 23:59:59 GMT'); + + headers.set('If-Modified-Since', ''); + assert.equal(headers.get('If-Modified-Since'), ''); + + headers.delete('If-Modified-Since'); + assert.equal(headers.get('If-Modified-Since'), null); + }); + + it('handles the If-Unmodified-Since header', () => { + let headers = new SuperHeaders({ 'If-Unmodified-Since': 'Fri, 01 Jan 2021 00:00:00 GMT' }); + assert.equal(headers.get('If-Unmodified-Since'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + + headers.set('If-Unmodified-Since', 'Fri, 31 Dec 2021 23:59:59 GMT'); + assert.equal(headers.get('If-Unmodified-Since'), 'Fri, 31 Dec 2021 23:59:59 GMT'); + + headers.set('If-Unmodified-Since', ''); + assert.equal(headers.get('If-Unmodified-Since'), ''); + + headers.delete('If-Unmodified-Since'); + assert.equal(headers.get('If-Unmodified-Since'), null); + }); + + it('handles the Set-Cookie header', () => { + let headers = new SuperHeaders({ 'Set-Cookie': 'session=abc' }); + assert.deepEqual(headers.getSetCookie(), ['session=abc']); + + headers.set('Set-Cookie', 'theme=dark'); + assert.deepEqual(headers.getSetCookie(), ['theme=dark']); + + headers.set('Set-Cookie', ''); + assert.deepEqual(headers.getSetCookie(), ['']); + + headers.delete('Set-Cookie'); + assert.deepEqual(headers.getSetCookie(), []); + }); + }); + + describe('header-specific getters and setters', () => { + it('handles Accept-Language header', () => { + let headers = new SuperHeaders(); assert.ok(headers.acceptLanguage instanceof AcceptLanguage); + + headers.acceptLanguage = 'en-US,en;q=0.9'; + assert.deepEqual(headers.acceptLanguage.size, 2); assert.deepEqual(headers.acceptLanguage.languages, ['en-US', 'en']); + assert.deepEqual(headers.acceptLanguage.qualities, [1, 0.9]); - headers.acceptLanguage.set('en', 0.8); - assert.equal(headers.get('Accept-Language'), 'en-US,en;q=0.8'); + headers.acceptLanguage = { en: 1, 'en-US': 0.8 }; + assert.deepEqual(headers.acceptLanguage.size, 2); + assert.deepEqual(headers.acceptLanguage.languages, ['en', 'en-US']); + assert.deepEqual(headers.acceptLanguage.qualities, [1, 0.8]); - headers.acceptLanguage = { 'fi-FI': 1, fi: 0.9 }; - assert.equal(headers.get('Accept-Language'), 'fi-FI,fi;q=0.9'); + headers.acceptLanguage = null; + assert.ok(headers.acceptLanguage instanceof AcceptLanguage); + assert.equal(headers.acceptLanguage.toString(), ''); }); it('handles Age header', () => { - let headers = new SuperHeaders({ age: 42 }); + let headers = new SuperHeaders(); + + assert.equal(headers.age, null); + + headers.age = '42'; assert.equal(headers.age, 42); - assert.equal(headers.get('Age'), '42'); - headers.age = 100; - assert.equal(headers.age, 100); - assert.equal(headers.get('Age'), '100'); + + headers.age = 42; + assert.equal(headers.age, 42); + + headers.age = null; + assert.equal(headers.age, null); }); it('handles Cache-Control header', () => { let headers = new SuperHeaders(); - headers.cacheControl = 'public, max-age=3600'; assert.ok(headers.cacheControl instanceof CacheControl); - assert.equal(headers.cacheControl.toString(), 'public, max-age=3600'); + + headers.cacheControl = 'public, max-age=3600'; + assert.equal(headers.cacheControl.public, true); + assert.equal(headers.cacheControl.maxAge, 3600); headers.cacheControl.maxAge = 1800; - assert.equal(headers.get('Cache-Control'), 'public, max-age=1800'); + assert.equal(headers.cacheControl.maxAge, 1800); headers.cacheControl = { noCache: true, noStore: true }; - assert.equal(headers.get('Cache-Control'), 'no-cache, no-store'); + assert.equal(headers.cacheControl.noCache, true); + assert.equal(headers.cacheControl.noStore, true); + + headers.cacheControl = null; + assert.ok(headers.cacheControl instanceof CacheControl); + assert.equal(headers.cacheControl.toString(), ''); }); it('handles Content-Disposition header', () => { let headers = new SuperHeaders(); - headers.contentDisposition = 'attachment; filename="example.txt"'; assert.ok(headers.contentDisposition instanceof ContentDisposition); + + headers.contentDisposition = 'attachment; filename="example.txt"'; assert.equal(headers.contentDisposition.type, 'attachment'); assert.equal(headers.contentDisposition.filename, 'example.txt'); headers.contentDisposition.filename = 'new.txt'; - assert.equal(headers.get('Content-Disposition'), 'attachment; filename=new.txt'); + assert.equal(headers.contentDisposition.filename, 'new.txt'); headers.contentDisposition = { type: 'inline', filename: 'index.html' }; - assert.equal(headers.get('Content-Disposition'), 'inline; filename=index.html'); + assert.equal(headers.contentDisposition.type, 'inline'); + assert.equal(headers.contentDisposition.filename, 'index.html'); + + headers.contentDisposition = null; + assert.ok(headers.contentDisposition instanceof ContentDisposition); + assert.equal(headers.contentDisposition.toString(), ''); }); it('handles Content-Length header', () => { let headers = new SuperHeaders(); - headers.contentLength = 42; + assert.equal(headers.contentLength, null); + + headers.contentLength = '42'; assert.equal(headers.contentLength, 42); - assert.equal(headers.get('Content-Length'), '42'); + + headers.contentLength = 42; + assert.equal(headers.contentLength, 42); + + headers.contentLength = null; + assert.equal(headers.contentLength, null); }); it('handles Content-Type header', () => { let headers = new SuperHeaders(); - headers.contentType = 'text/plain; charset=utf-8'; assert.ok(headers.contentType instanceof ContentType); + + headers.contentType = 'text/plain; charset=utf-8'; assert.equal(headers.contentType.mediaType, 'text/plain'); assert.equal(headers.contentType.charset, 'utf-8'); headers.contentType.charset = 'iso-8859-1'; - assert.equal(headers.get('Content-Type'), 'text/plain; charset=iso-8859-1'); + assert.equal(headers.contentType.charset, 'iso-8859-1'); headers.contentType = { mediaType: 'text/html' }; - assert.equal(headers.get('Content-Type'), 'text/html'); + assert.equal(headers.contentType.mediaType, 'text/html'); + + headers.contentType = null; + assert.ok(headers.contentType instanceof ContentType); + assert.equal(headers.contentType.toString(), ''); }); it('handles Cookie header', () => { let headers = new SuperHeaders(); - headers.cookie = 'name1=value1; name2=value2'; assert.ok(headers.cookie instanceof Cookie); + + headers.cookie = 'name1=value1; name2=value2'; assert.equal(headers.cookie.get('name1'), 'value1'); assert.equal(headers.cookie.get('name2'), 'value2'); headers.cookie.set('name3', 'value3'); - assert.equal(headers.get('Cookie'), 'name1=value1; name2=value2; name3=value3'); + assert.equal(headers.cookie.get('name3'), 'value3'); headers.cookie = [['name4', 'value4']]; - assert.equal(headers.get('Cookie'), 'name4=value4'); + assert.equal(headers.cookie.get('name4'), 'value4'); + + headers.cookie = null; + assert.ok(headers.cookie instanceof Cookie); + assert.equal(headers.cookie.toString(), ''); + }); + + it('handles Date header', () => { + let headers = new SuperHeaders(); + + assert.equal(headers.date, null); + + headers.date = new Date('2021-01-01T00:00:00Z'); + assert.ok(headers.date instanceof Date); + assert.equal(headers.date.toUTCString(), 'Fri, 01 Jan 2021 00:00:00 GMT'); + + headers.date = null; + assert.equal(headers.date, null); }); it('handles Expires header', () => { let headers = new SuperHeaders(); - headers.expires = new Date('2021-01-01T00:00:00Z'); + assert.equal(headers.expires, null); + + headers.expires = new Date('2021-01-01T00:00:00Z'); assert.ok(headers.expires instanceof Date); assert.equal(headers.expires.toUTCString(), 'Fri, 01 Jan 2021 00:00:00 GMT'); - assert.equal(headers.get('Expires'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + + headers.expires = null; + assert.equal(headers.expires, null); }); it('handles Last-Modified header', () => { let headers = new SuperHeaders(); - headers.lastModified = new Date('2021-01-01T00:00:00Z'); + assert.equal(headers.lastModified, null); + + headers.lastModified = new Date('2021-01-01T00:00:00Z'); assert.ok(headers.lastModified instanceof Date); assert.equal(headers.lastModified.toUTCString(), 'Fri, 01 Jan 2021 00:00:00 GMT'); - assert.equal(headers.get('Last-Modified'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + + headers.lastModified = null; + assert.equal(headers.lastModified, null); + }); + + it('handles If-Modified-Since header', () => { + let headers = new SuperHeaders(); + + assert.equal(headers.ifModifiedSince, null); + + headers.ifModifiedSince = new Date('2021-01-01T00:00:00Z'); + assert.ok(headers.ifModifiedSince instanceof Date); + assert.equal(headers.ifModifiedSince.toUTCString(), 'Fri, 01 Jan 2021 00:00:00 GMT'); + + headers.ifModifiedSince = null; + assert.equal(headers.ifModifiedSince, null); + }); + + it('handles If-Unmodified-Since header', () => { + let headers = new SuperHeaders(); + + assert.equal(headers.ifUnmodifiedSince, null); + + headers.ifUnmodifiedSince = new Date('2021-01-01T00:00:00Z'); + assert.ok(headers.ifUnmodifiedSince instanceof Date); + assert.equal(headers.ifUnmodifiedSince.toUTCString(), 'Fri, 01 Jan 2021 00:00:00 GMT'); + + headers.ifUnmodifiedSince = null; + assert.equal(headers.ifUnmodifiedSince, null); }); it('handles Set-Cookie header', () => { let headers = new SuperHeaders(); - headers.setCookie = ['session=abc', 'theme=dark']; - assert.ok(Array.isArray(headers.setCookie)); + assert.deepEqual(headers.setCookie, []); + + headers.setCookie = 'session=abc'; + assert.equal(headers.setCookie.length, 1); + assert.equal(headers.setCookie[0].name, 'session'); + assert.equal(headers.setCookie[0].value, 'abc'); + + headers.setCookie = { name: 'session', value: 'def' }; + assert.equal(headers.setCookie.length, 1); + assert.equal(headers.setCookie[0].name, 'session'); + assert.equal(headers.setCookie[0].value, 'def'); + + headers.setCookie = ['session=abc', 'theme=dark']; assert.equal(headers.setCookie.length, 2); assert.equal(headers.setCookie[0].name, 'session'); assert.equal(headers.setCookie[0].value, 'abc'); assert.equal(headers.setCookie[1].name, 'theme'); assert.equal(headers.setCookie[1].value, 'dark'); + // Can use ...spread to add new cookies headers.setCookie = [...headers.setCookie, 'lang=en']; - - assert.equal(headers.get('Set-Cookie'), 'session=abc, theme=dark, lang=en'); + assert.equal(headers.setCookie.length, 3); + assert.equal(headers.setCookie[2].name, 'lang'); + assert.equal(headers.setCookie[2].value, 'en'); headers.setCookie = [ { name: 'session', value: 'def' }, { name: 'theme', value: 'light' }, ]; - assert.equal(headers.get('Set-Cookie'), 'session=def, theme=light'); - }); - - it('creates empty header objects when accessed', () => { - let headers = new SuperHeaders(); - - assert.ok(headers.acceptLanguage instanceof AcceptLanguage); - assert.equal(headers.acceptLanguage.toString(), ''); - - assert.ok(headers.cacheControl instanceof CacheControl); - assert.equal(headers.cacheControl.toString(), ''); - - assert.ok(headers.contentDisposition instanceof ContentDisposition); - assert.equal(headers.contentDisposition.toString(), ''); - - assert.ok(headers.contentType instanceof ContentType); - assert.equal(headers.contentType.toString(), ''); + assert.equal(headers.setCookie.length, 2); + assert.equal(headers.setCookie[0].name, 'session'); + assert.equal(headers.setCookie[0].value, 'def'); + assert.equal(headers.setCookie[1].name, 'theme'); + assert.equal(headers.setCookie[1].value, 'light'); - assert.ok(headers.cookie instanceof Cookie); - assert.equal(headers.cookie.toString(), ''); + // Can use push() to add new cookies + headers.setCookie.push({ name: 'lang', value: 'fr' }); + assert.equal(headers.setCookie.length, 3); + assert.equal(headers.setCookie[2].name, 'lang'); + assert.equal(headers.setCookie[2].value, 'fr'); - assert.ok(Array.isArray(headers.setCookie)); - assert.equal(headers.setCookie.length, 0); + headers.setCookie = null; + assert.deepEqual(headers.setCookie, []); }); }); diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index 226e3a34a96..d579cb101d9 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -12,18 +12,57 @@ const CRLF = '\r\n'; const SetCookieKey = 'set-cookie'; interface SuperHeadersPropertyInit { + /** + * The [`Accept-Language`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) header value. + */ acceptLanguage?: string | AcceptLanguageInit; + /** + * The [`Age`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Age) header value. + */ age?: string | number; + /** + * The [`Cache-Control`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) header value. + */ cacheControl?: string | CacheControlInit; + /** + * The [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) header value. + */ contentDisposition?: string | ContentDispositionInit; + /** + * The [`Content-Length`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Length) header value. + */ contentLength?: string | number; + /** + * The [`Content-Type`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) header value. + */ contentType?: string | ContentTypeInit; + /** + * The [`Cookie`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie) header value. + */ cookie?: string | CookieInit; + /** + * The [`Date`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Date) header value. + */ date?: string | Date; + /** + * The [`Expires`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires) header value. + */ expires?: string | Date; + /** + * The [`If-Modified-Since`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since) header value. + */ ifModifiedSince?: string | Date; + /** + * The [`If-Unmodified-Since`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Unmodified-Since) header value. + */ ifUnmodifiedSince?: string | Date; + /** + * The [`Last-Modified`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified) header value. + */ lastModified?: string | Date; + /** + * The [`Set-Cookie`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) header value(s). + */ setCookie?: string | (string | SetCookieInit)[]; } @@ -120,10 +159,11 @@ export class SuperHeaders extends Headers { return value; } else if (value instanceof Date) { return value.toUTCString(); - } else if (value != null) { - return value.toString(); - } else { + } else if (value == null) { return null; + } else { + let str = value.toString(); + return str === '' ? null : str; } } } @@ -136,7 +176,9 @@ export class SuperHeaders extends Headers { * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/getSetCookie) */ getSetCookie(): string[] { - return this.#setCookieValues.map((value) => value.toString()); + return this.#setCookieValues.map((value) => + typeof value === 'string' ? value : value.toString(), + ); } /** @@ -159,10 +201,10 @@ export class SuperHeaders extends Headers { * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/set) */ - set(name: string, value: string | HeaderValue): void { + set(name: string, value: string): void { let key = name.toLowerCase(); if (key === SetCookieKey) { - this.#setCookieValues = [value as string | SetCookie]; + this.#setCookieValues = [value]; } else { this.#map.set(key, value); } @@ -256,8 +298,12 @@ export class SuperHeaders extends Headers { return this.#getHeaderValue('accept-language', AcceptLanguage); } - set acceptLanguage(value: string | AcceptLanguageInit) { - this.#setHeaderValue('accept-language', AcceptLanguage, value); + set acceptLanguage(value: string | AcceptLanguageInit | undefined | null) { + if (value != null) { + this.#setHeaderValue('accept-language', AcceptLanguage, value); + } else { + this.#map.delete('accept-language'); + } } /** @@ -267,12 +313,16 @@ export class SuperHeaders extends Headers { * * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7234#section-5.1) */ - get age(): number | undefined { + get age(): number | null { return this.#getNumberValue('age'); } - set age(value: string | number) { - this.#map.set('age', value); + set age(value: string | number | undefined | null) { + if (value != null) { + this.#map.set('age', value); + } else { + this.#map.delete('age'); + } } /** @@ -286,8 +336,12 @@ export class SuperHeaders extends Headers { return this.#getHeaderValue('cache-control', CacheControl); } - set cacheControl(value: string | CacheControlInit) { - this.#setHeaderValue('cache-control', CacheControl, value); + set cacheControl(value: string | CacheControlInit | undefined | null) { + if (value != null) { + this.#setHeaderValue('cache-control', CacheControl, value); + } else { + this.#map.delete('cache-control'); + } } /** @@ -301,8 +355,12 @@ export class SuperHeaders extends Headers { return this.#getHeaderValue('content-disposition', ContentDisposition); } - set contentDisposition(value: string | ContentDispositionInit) { - this.#setHeaderValue('content-disposition', ContentDisposition, value); + set contentDisposition(value: string | ContentDispositionInit | undefined | null) { + if (value != null) { + this.#setHeaderValue('content-disposition', ContentDisposition, value); + } else { + this.#map.delete('content-disposition'); + } } /** @@ -312,12 +370,16 @@ export class SuperHeaders extends Headers { * * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2) */ - get contentLength(): number | undefined { + get contentLength(): number | null { return this.#getNumberValue('content-length'); } - set contentLength(value: string | number) { - this.#map.set('content-length', value); + set contentLength(value: string | number | undefined | null) { + if (value != null) { + this.#map.set('content-length', value); + } else { + this.#map.delete('content-length'); + } } /** @@ -331,8 +393,12 @@ export class SuperHeaders extends Headers { return this.#getHeaderValue('content-type', ContentType); } - set contentType(value: string | ContentTypeInit) { - this.#setHeaderValue('content-type', ContentType, value); + set contentType(value: string | ContentTypeInit | undefined | null) { + if (value != null) { + this.#setHeaderValue('content-type', ContentType, value); + } else { + this.#map.delete('content-type'); + } } /** @@ -347,8 +413,12 @@ export class SuperHeaders extends Headers { return this.#getHeaderValue('cookie', Cookie); } - set cookie(value: string | CookieInit) { - this.#setHeaderValue('cookie', Cookie, value); + set cookie(value: string | CookieInit | undefined | null) { + if (value != null) { + this.#setHeaderValue('cookie', Cookie, value); + } else { + this.#map.delete('cookie'); + } } /** @@ -358,12 +428,16 @@ export class SuperHeaders extends Headers { * * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.2) */ - get date(): Date | undefined { + get date(): Date | null { return this.#getDateValue('date'); } - set date(value: string | Date) { - this.#map.set('date', value); + set date(value: string | Date | undefined | null) { + if (value != null) { + this.#map.set('date', value); + } else { + this.#map.delete('date'); + } } /** @@ -373,12 +447,16 @@ export class SuperHeaders extends Headers { * * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7234#section-5.3) */ - get expires(): Date | undefined { + get expires(): Date | null { return this.#getDateValue('expires'); } - set expires(value: string | Date) { - this.#map.set('expires', value); + set expires(value: string | Date | undefined | null) { + if (value != null) { + this.#map.set('expires', value); + } else { + this.#map.delete('expires'); + } } /** @@ -389,12 +467,16 @@ export class SuperHeaders extends Headers { * * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-3.3) */ - get ifModifiedSince(): Date | undefined { + get ifModifiedSince(): Date | null { return this.#getDateValue('if-modified-since'); } - set ifModifiedSince(value: string | Date) { - this.#map.set('if-modified-since', value); + set ifModifiedSince(value: string | Date | undefined | null) { + if (value != null) { + this.#map.set('if-modified-since', value); + } else { + this.#map.delete('if-modified-since'); + } } /** @@ -405,12 +487,16 @@ export class SuperHeaders extends Headers { * * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-3.4) */ - get ifUnmodifiedSince(): Date | undefined { + get ifUnmodifiedSince(): Date | null { return this.#getDateValue('if-unmodified-since'); } - set ifUnmodifiedSince(value: string | Date) { - this.#map.set('if-unmodified-since', value); + set ifUnmodifiedSince(value: string | Date | undefined | null) { + if (value != null) { + this.#map.set('if-unmodified-since', value); + } else { + this.#map.delete('if-unmodified-since'); + } } /** @@ -420,12 +506,16 @@ export class SuperHeaders extends Headers { * * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-2.2) */ - get lastModified(): Date | undefined { + get lastModified(): Date | null { return this.#getDateValue('last-modified'); } - set lastModified(value: string | Date) { - this.#map.set('last-modified', value); + set lastModified(value: string | Date | undefined | null) { + if (value != null) { + this.#map.set('last-modified', value); + } else { + this.#map.delete('last-modified'); + } } /** @@ -446,25 +536,29 @@ export class SuperHeaders extends Headers { return this.#setCookieValues as SetCookie[]; } - set setCookie(values: string | (string | SetCookieInit)[]) { - if (typeof values === 'string') { - this.#setCookieValues = [values]; + set setCookie(values: (string | SetCookieInit)[] | string | SetCookieInit | undefined | null) { + if (values != null) { + if (Array.isArray(values)) { + this.#setCookieValues = values.map((value) => + typeof value === 'string' || value instanceof SetCookie ? value : new SetCookie(value), + ); + } else { + this.#setCookieValues = [new SetCookie(values)]; + } } else { - this.#setCookieValues = values.map((value) => { - if (typeof value === 'string' || value instanceof SetCookie) { - return value; - } else { - return new SetCookie(value); - } - }); + this.#setCookieValues = []; } } // helpers - #getDateValue(key: string): Date | undefined { + #getDateValue(key: string): Date | null { let value = this.#map.get(key); if (value) { + if (value instanceof Date) { + return value; + } + if (typeof value === 'string') { let date = new Date(value); if (isValidDate(date)) { @@ -473,36 +567,40 @@ export class SuperHeaders extends Headers { } else { this.#map.delete(key); // bad value, remove it } - } else if (value instanceof Date) { - return value; - } else { - this.#map.delete(key); // bad value, remove it } + + this.#map.delete(key); // bad value, remove it } + + return null; } - #getNumberValue(key: string): number | undefined { + #getNumberValue(key: string): number | null { let value = this.#map.get(key); - if (value) { + if (value !== undefined) { + if (typeof value === 'number') { + return value; + } + if (typeof value === 'string') { - let v = parseInt(value, 10); - if (!isNaN(v)) { - this.#map.set(key, v); // cache the parsed number - return v; + let num = parseInt(value, 10); + if (!isNaN(num)) { + this.#map.set(key, num); // cache the parsed number + return num; } else { this.#map.delete(key); // bad value, remove it } - } else if (typeof value === 'number') { - return value; - } else { - this.#map.delete(key); // bad value, remove it } + + this.#map.delete(key); // bad value, remove it } + + return null; } #getHeaderValue<T extends HeaderValue>(key: string, ctor: new (init?: string) => T): T { let value = this.#map.get(key); - if (value) { + if (value !== undefined) { if (typeof value === 'string') { let headerValue = new ctor(value); this.#map.set(key, headerValue); From 6c90eaf2b63d56cf0f8ab2ea5b791e963cab09c3 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 19 Dec 2024 15:57:50 -0800 Subject: [PATCH 543/730] Tighten up types --- packages/headers/CHANGELOG.md | 51 ++- .../headers/src/lib/accept-language.test.ts | 6 +- packages/headers/src/lib/accept-language.ts | 14 +- .../headers/src/lib/super-headers.test.ts | 429 +++++------------- packages/headers/src/lib/super-headers.ts | 286 ++++++------ 5 files changed, 317 insertions(+), 469 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 84f31dab817..a074b2ed053 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -4,6 +4,32 @@ This is the changelog for [`headers`](https://github.com/mjackson/remix-the-web/ ## HEAD +This release tightens up the type safety and brings `SuperHeaders` more in line with the built-in `Headers` interface. + +- BREAKING CHANGE: The mutation methods `headers.set()` and `headers.append()` no longer accept anything other than a string as the 2nd arg. This follows the native `Headers` interface more closely. + +```ts +// before +let headers = new SuperHeaders(); +headers.set('Content-Type', { mediaType: 'text/html' }); // don't do this + +// after +headers.set('Content-Type', 'text/html'); + +// if you need the previous behavior, use the setter instead of set() +headers.contentType = { mediaType: 'text/html' }; +``` + +Similarly, the constructor no longer accepts non-string values in an array init value. + +```ts +// before +let headers = new SuperHeaders([['Content-Type', { mediaType: 'text/html' }]]); + +// if you need the previous behavior, use the object init instead +let headers = new SuperHeaders({ contentType: 'text/html' }); +``` + - BREAKING CHANGE: `headers.get()` returns `null` for uninitialized custom header values instead of `undefined`. This follows the native `Headers` interface more closely. ```ts @@ -17,21 +43,18 @@ headers.get('Host'); // null headers.get('Content-Type'); // null ``` -- BREAKING CHANGE: `headers.set()` no longer accepts anything other than a string as the 2nd arg. This follows the native `Headers` interface more closely. +- BREAKING CHANGE: Removed ability to initialize `AcceptLanguage` with `undefined` quality values. ```ts // before -let headers = new SuperHeaders(); -headers.set('Content-Type', { mediaType: 'text/html' }); +let h1 = new AcceptLanguage({ 'en-US': undefined }); +let h2 = new AcceptLanguage([['en-US', undefined]]); // after -headers.set('Content-Type', 'text/html'); - -// if you need the previous behavior, use the setter instead of set() -headers.contentType = { mediaType: 'text/html' }; +let h3 = new AcceptLanguage({ 'en-US': 1 }); ``` -- All setter methods now also accept `undefined | null` in addition to `string` and custom object values. Setting a header to `undefined | null` is the same as using `headers.delete()`. +- All setters now also accept `undefined | null` in addition to `string` and custom object values. Setting a header to `undefined | null` is the same as using `headers.delete()`. ```ts // before @@ -42,6 +65,18 @@ headers.contentType = null; // same as headers.delete('Content-Type'); headers.contentType; // null ``` +- Allow setting date values (`date`, `expires`, `ifModifiedSince`, `ifUnmodifiedSince`, and `lastModified`) using numbers. + +```ts +let ms = new Date().getTime(); +let headers = new SuperHeaders({ lastModified: ms }); +``` + +- Adds support for + - `headers.connection` + - `headers.host` + - `headers.referer` + ## v0.8.0 (2024-11-14) - Added CommonJS build diff --git a/packages/headers/src/lib/accept-language.test.ts b/packages/headers/src/lib/accept-language.test.ts index cbfb6ee7fde..09a1146d14f 100644 --- a/packages/headers/src/lib/accept-language.test.ts +++ b/packages/headers/src/lib/accept-language.test.ts @@ -16,15 +16,13 @@ describe('Accept-Language', () => { }); it('initializes with an array', () => { - let header = new AcceptLanguage(['en-US', ['en', 0.9], ['fi', undefined], ['fi-FI']]); + let header = new AcceptLanguage(['en-US', ['en', 0.9]]); assert.equal(header.get('en-US'), 1); assert.equal(header.get('en'), 0.9); - assert.equal(header.get('fi'), 1); - assert.equal(header.get('fi-FI'), 1); }); it('initializes with an object', () => { - let header = new AcceptLanguage({ 'en-US': undefined, en: 0.9 }); + let header = new AcceptLanguage({ 'en-US': 1, en: 0.9 }); assert.equal(header.get('en-US'), 1); assert.equal(header.get('en'), 0.9); }); diff --git a/packages/headers/src/lib/accept-language.ts b/packages/headers/src/lib/accept-language.ts index 0a0eda42e30..37af9eda65b 100644 --- a/packages/headers/src/lib/accept-language.ts +++ b/packages/headers/src/lib/accept-language.ts @@ -2,9 +2,7 @@ import { type HeaderValue } from './header-value.ts'; import { parseParams } from './param-values.ts'; import { isIterable } from './utils.ts'; -export type AcceptLanguageInit = - | Iterable<string | [string] | [string, number | undefined]> - | Record<string, number | undefined>; +export type AcceptLanguageInit = Iterable<string | [string, number]> | Record<string, number>; /** * The value of a `Accept-Language` HTTP header. @@ -18,6 +16,7 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { constructor(init?: string | AcceptLanguageInit) { this.#map = new Map(); + if (init) { if (typeof init === 'string') { let params = parseParams(init, ','); @@ -31,19 +30,20 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { } } else if (isIterable(init)) { for (let language of init) { - let quality; if (Array.isArray(language)) { - [language, quality] = language; + this.#map.set(language[0], language[1]); + } else { + this.#map.set(language, 1); } - this.#map.set(language, quality ?? 1); } } else { for (let language in init) { if (Object.prototype.hasOwnProperty.call(init, language)) { - this.#map.set(language, init[language] ?? 1); + this.#map.set(language, init[language]); } } } + this.#sort(); } } diff --git a/packages/headers/src/lib/super-headers.test.ts b/packages/headers/src/lib/super-headers.test.ts index 81e3fccedbd..294e3f7cea3 100644 --- a/packages/headers/src/lib/super-headers.test.ts +++ b/packages/headers/src/lib/super-headers.test.ts @@ -6,6 +6,7 @@ import { CacheControl } from './cache-control.ts'; import { ContentDisposition } from './content-disposition.ts'; import { ContentType } from './content-type.ts'; import { Cookie } from './cookie.ts'; +import { SetCookie } from './set-cookie.ts'; import { SuperHeaders } from './super-headers.ts'; describe('SuperHeaders', () => { @@ -20,22 +21,11 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Content-Type'), null); }); - it('initializes from a string', () => { - let headers = new SuperHeaders('Content-Type: text/plain\r\nContent-Length: 42'); - assert.equal(headers.get('Content-Type'), 'text/plain'); - assert.equal(headers.get('Content-Length'), '42'); - }); - it('initializes from an object of header name/value pairs', () => { let headers = new SuperHeaders({ 'Content-Type': 'text/plain' }); assert.equal(headers.get('Content-Type'), 'text/plain'); }); - it('initializes from an object of property name/value pairs', () => { - let headers = new SuperHeaders({ contentType: 'text/plain' }); - assert.equal(headers.get('Content-Type'), 'text/plain'); - }); - it('initializes from an array of key-value pairs', () => { let headers = new SuperHeaders([ ['Content-Type', 'text/plain'], @@ -45,63 +35,22 @@ describe('SuperHeaders', () => { assert.equal(headers.get('X-Custom'), 'value'); }); - it('initializes from another SuperHeaders instance', () => { - let original = new SuperHeaders({ 'Content-Type': 'text/plain' }); - let headers = new SuperHeaders(original); - assert.equal(headers.get('Content-Type'), 'text/plain'); - }); - it('initializes from a Headers instance', () => { - let original = new Headers({ 'Content-Type': 'text/plain' }); - let headers = new SuperHeaders(original); - assert.equal(headers.get('Content-Type'), 'text/plain'); - }); - - it('initializes with a AcceptLanguageInit', () => { - let headers = new SuperHeaders({ - acceptLanguage: { 'en-US': 1, en: 0.9 }, - }); - assert.equal(headers.get('Accept-Language'), 'en-US,en;q=0.9'); + let h1 = new Headers({ 'Content-Type': 'text/plain' }); + let h2 = new SuperHeaders(h1); + assert.equal(h2.get('Content-Type'), 'text/plain'); }); - it('initializes with a CacheControlInit', () => { - let headers = new SuperHeaders({ cacheControl: 'public, max-age=3600' }); - assert.equal(headers.get('Cache-Control'), 'public, max-age=3600'); - }); - - it('initializes with a ContentDispositionInit', () => { - let headers = new SuperHeaders({ - contentDisposition: { type: 'attachment', filename: 'example.txt' }, - }); - assert.equal(headers.get('Content-Disposition'), 'attachment; filename=example.txt'); - }); - - it('initializes with a ContentTypeInit', () => { - let headers = new SuperHeaders({ contentType: { mediaType: 'text/plain', charset: 'utf-8' } }); - assert.equal(headers.get('Content-Type'), 'text/plain; charset=utf-8'); - }); - - it('initializes with a CookieInit', () => { - let headers = new SuperHeaders({ cookie: [['name', 'value']] }); - assert.equal(headers.get('Cookie'), 'name=value'); - }); - - it('initializes with a SetCookieInit', () => { - let headers = new SuperHeaders({ - setCookie: [ - { name: 'session', value: 'abc', path: '/' }, - { name: 'theme', value: 'dark', expires: new Date('2021-12-31T23:59:59Z') }, - ], - }); - assert.deepEqual(headers.getSetCookie(), [ - 'session=abc; Path=/', - 'theme=dark; Expires=Fri, 31 Dec 2021 23:59:59 GMT', - ]); + it('initializes from another SuperHeaders instance', () => { + let h1 = new SuperHeaders({ 'Content-Type': 'text/plain' }); + let h2 = new SuperHeaders(h1); + assert.equal(h2.get('Content-Type'), 'text/plain'); }); - it('initializes with a lastModified Date', () => { - let headers = new SuperHeaders({ lastModified: new Date('2021-01-01T00:00:00Z') }); - assert.equal(headers.get('Last-Modified'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + it('initializes from a string', () => { + let headers = new SuperHeaders('Content-Type: text/plain\r\nContent-Length: 42'); + assert.equal(headers.get('Content-Type'), 'text/plain'); + assert.equal(headers.get('Content-Length'), '42'); }); it('appends values', () => { @@ -195,269 +144,119 @@ describe('SuperHeaders', () => { ]); }); - describe('setting values in the constructor', () => { - it('handles the Accept-Language header', () => { - let headers = new SuperHeaders({ acceptLanguage: 'en-US,en;q=0.9' }); - assert.equal(headers.get('Accept-Language'), 'en-US,en;q=0.9'); - }); - - it('handles the Age header', () => { - let headers = new SuperHeaders({ age: 42 }); - assert.equal(headers.get('Age'), '42'); - }); - - it('handles the Cache-Control header', () => { - let headers = new SuperHeaders({ cacheControl: 'public, max-age=3600' }); - assert.equal(headers.get('Cache-Control'), 'public, max-age=3600'); - }); - - it('handles the Content-Disposition header', () => { - let headers = new SuperHeaders({ contentDisposition: 'attachment; filename="example.txt"' }); - assert.equal(headers.get('Content-Disposition'), 'attachment; filename="example.txt"'); - }); - - it('handles the Content-Length header', () => { - let headers = new SuperHeaders({ contentLength: 42 }); - assert.equal(headers.get('Content-Length'), '42'); - }); - - it('handles the Content-Type header', () => { - let headers = new SuperHeaders({ contentType: 'text/plain; charset=utf-8' }); - assert.equal(headers.get('Content-Type'), 'text/plain; charset=utf-8'); - }); - - it('handles the Cookie header', () => { - let headers = new SuperHeaders({ cookie: 'name1=value1; name2=value2' }); - assert.equal(headers.get('Cookie'), 'name1=value1; name2=value2'); - }); - - it('handles the Expires header', () => { - let headers = new SuperHeaders({ expires: new Date('2021-01-01T00:00:00Z') }); - assert.equal(headers.get('Expires'), 'Fri, 01 Jan 2021 00:00:00 GMT'); - }); - - it('handles the Last-Modified header', () => { - let headers = new SuperHeaders({ lastModified: new Date('2021-01-01T00:00:00Z') }); - assert.equal(headers.get('Last-Modified'), 'Fri, 01 Jan 2021 00:00:00 GMT'); - }); + it('omits empty values when stringified', () => { + let headers = new SuperHeaders(); - it('handles the Set-Cookie header', () => { - let headers = new SuperHeaders({ setCookie: ['session=abc', 'theme=dark'] }); - assert.deepEqual(headers.getSetCookie(), ['session=abc', 'theme=dark']); - }); + // This should appear in the string since it has a media type, it's complete + headers.contentType = 'text/plain'; - it('handles the Set-Cookie header with objects', () => { - let headers = new SuperHeaders({ - setCookie: [ - { name: 'session', value: 'abc' }, - { name: 'theme', value: 'dark' }, - ], - }); - assert.deepEqual(headers.getSetCookie(), ['session=abc', 'theme=dark']); - }); + // This should not appear in the string since it's incomplete, missing the type + headers.contentDisposition.filename = 'example.txt'; - it('handles the Set-Cookie header with options', () => { - let headers = new SuperHeaders({ - setCookie: [ - { name: 'session', value: 'abc', path: '/' }, - { name: 'theme', value: 'dark', expires: new Date('2021-12-31T23:59:59Z') }, - ], - }); - assert.deepEqual(headers.getSetCookie(), [ - 'session=abc; Path=/', - 'theme=dark; Expires=Fri, 31 Dec 2021 23:59:59 GMT', - ]); - }); + assert.equal(headers.toString(), 'Content-Type: text/plain'); }); - describe('get() and set()', () => { - it('handles the Accept-Language header', () => { - let headers = new SuperHeaders({ 'Accept-Language': 'en-US,en;q=0.9' }); + describe('constructor property init', () => { + it('handles the acceptLanguage property', () => { + let headers = new SuperHeaders({ acceptLanguage: { 'en-US': 1, en: 0.9 } }); assert.equal(headers.get('Accept-Language'), 'en-US,en;q=0.9'); - - headers.set('Accept-Language', 'en;q=0.8, fr'); - assert.equal(headers.get('Accept-Language'), 'en;q=0.8, fr'); - - headers.set('Accept-Language', ''); - assert.equal(headers.get('Accept-Language'), ''); - - headers.delete('Accept-Language'); - assert.equal(headers.get('Accept-Language'), null); }); - it('handles the Age header', () => { - let headers = new SuperHeaders({ Age: '42' }); + it('handles the age property', () => { + let headers = new SuperHeaders({ age: 42 }); assert.equal(headers.get('Age'), '42'); - - headers.set('Age', '100'); - assert.equal(headers.get('Age'), '100'); - - headers.set('Age', ''); - assert.equal(headers.get('Age'), ''); - - headers.delete('Age'); - assert.equal(headers.get('Age'), null); }); - it('handles the Cache-Control header', () => { - let headers = new SuperHeaders({ 'Cache-Control': 'public, max-age=3600' }); + it('handles the cacheControl property', () => { + let headers = new SuperHeaders({ cacheControl: { public: true, maxAge: 3600 } }); assert.equal(headers.get('Cache-Control'), 'public, max-age=3600'); + }); - headers.set('Cache-Control', 'no-cache'); - assert.equal(headers.get('Cache-Control'), 'no-cache'); - - headers.set('Cache-Control', ''); - assert.equal(headers.get('Cache-Control'), ''); - - headers.delete('Cache-Control'); - assert.equal(headers.get('Cache-Control'), null); + it('handles the connection property', () => { + let headers = new SuperHeaders({ connection: 'close' }); + assert.equal(headers.get('Connection'), 'close'); }); - it('handles the Content-Disposition header', () => { + it('handles the contentDisposition property', () => { let headers = new SuperHeaders({ - 'Content-Disposition': 'attachment; filename="example.txt"', + contentDisposition: { type: 'attachment', filename: 'example.txt' }, }); - assert.equal(headers.get('Content-Disposition'), 'attachment; filename="example.txt"'); - - headers.set('Content-Disposition', 'inline'); - assert.equal(headers.get('Content-Disposition'), 'inline'); - - headers.set('Content-Disposition', ''); - assert.equal(headers.get('Content-Disposition'), ''); - - headers.delete('Content-Disposition'); - assert.equal(headers.get('Content-Disposition'), null); + assert.equal(headers.get('Content-Disposition'), 'attachment; filename=example.txt'); }); - it('handles the Content-Length header', () => { - let headers = new SuperHeaders({ 'Content-Length': '42' }); + it('handles the contentLength property', () => { + let headers = new SuperHeaders({ contentLength: 42 }); assert.equal(headers.get('Content-Length'), '42'); - - headers.set('Content-Length', '100'); - assert.equal(headers.get('Content-Length'), '100'); - - headers.set('Content-Length', ''); - assert.equal(headers.get('Content-Length'), ''); - - headers.delete('Content-Length'); - assert.equal(headers.get('Content-Length'), null); }); - it('handles the Content-Type header', () => { - let headers = new SuperHeaders({ 'Content-Type': 'text/plain; charset=utf-8' }); + it('handles the contentType property', () => { + let headers = new SuperHeaders({ + contentType: { mediaType: 'text/plain', charset: 'utf-8' }, + }); assert.equal(headers.get('Content-Type'), 'text/plain; charset=utf-8'); - - headers.set('Content-Type', 'text/html'); - assert.equal(headers.get('Content-Type'), 'text/html'); - - headers.set('Content-Type', ''); - assert.equal(headers.get('Content-Type'), ''); - - headers.delete('Content-Type'); - assert.equal(headers.get('Content-Type'), null); }); - it('handles the Cookie header', () => { - let headers = new SuperHeaders({ Cookie: 'name1=value1; name2=value2' }); - assert.equal(headers.get('Cookie'), 'name1=value1; name2=value2'); - - headers.set('Cookie', 'name3=value3'); - assert.equal(headers.get('Cookie'), 'name3=value3'); - - headers.set('Cookie', ''); - assert.equal(headers.get('Cookie'), ''); - - headers.delete('Cookie'); - assert.equal(headers.get('Cookie'), null); + it('handles the cookie property', () => { + let headers = new SuperHeaders({ cookie: [['name', 'value']] }); + assert.equal(headers.get('Cookie'), 'name=value'); }); - it('handles the Date header', () => { - let headers = new SuperHeaders({ Date: 'Fri, 01 Jan 2021 00:00:00 GMT' }); + it('handles the date property', () => { + let headers = new SuperHeaders({ date: new Date('2021-01-01T00:00:00Z') }); assert.equal(headers.get('Date'), 'Fri, 01 Jan 2021 00:00:00 GMT'); - - headers.set('Date', 'Fri, 31 Dec 2021 23:59:59 GMT'); - assert.equal(headers.get('Date'), 'Fri, 31 Dec 2021 23:59:59 GMT'); - - headers.set('Date', ''); - assert.equal(headers.get('Date'), ''); - - headers.delete('Date'); - assert.equal(headers.get('Date'), null); }); - it('handles the Expires header', () => { - let headers = new SuperHeaders({ Expires: 'Fri, 01 Jan 2021 00:00:00 GMT' }); + it('handles the expires property', () => { + let headers = new SuperHeaders({ expires: new Date('2021-01-01T00:00:00Z') }); assert.equal(headers.get('Expires'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + }); - headers.set('Expires', 'Fri, 31 Dec 2021 23:59:59 GMT'); - assert.equal(headers.get('Expires'), 'Fri, 31 Dec 2021 23:59:59 GMT'); - - headers.set('Expires', ''); - assert.equal(headers.get('Expires'), ''); - - headers.delete('Expires'); - assert.equal(headers.get('Expires'), null); + it('handles the host property', () => { + let headers = new SuperHeaders({ host: 'example.com' }); + assert.equal(headers.get('Host'), 'example.com'); }); - it('handles the Last-Modified header', () => { - let headers = new SuperHeaders({ 'Last-Modified': 'Fri, 01 Jan 2021 00:00:00 GMT' }); + it('handles the lastModified property', () => { + let headers = new SuperHeaders({ lastModified: new Date('2021-01-01T00:00:00Z') }); assert.equal(headers.get('Last-Modified'), 'Fri, 01 Jan 2021 00:00:00 GMT'); - - headers.set('Last-Modified', 'Fri, 31 Dec 2021 23:59:59 GMT'); - assert.equal(headers.get('Last-Modified'), 'Fri, 31 Dec 2021 23:59:59 GMT'); - - headers.set('Last-Modified', ''); - assert.equal(headers.get('Last-Modified'), ''); - - headers.delete('Last-Modified'); - assert.equal(headers.get('Last-Modified'), null); }); - it('handles the If-Modified-Since header', () => { - let headers = new SuperHeaders({ 'If-Modified-Since': 'Fri, 01 Jan 2021 00:00:00 GMT' }); + it('handles the ifModifiedSince property', () => { + let headers = new SuperHeaders({ ifModifiedSince: new Date('2021-01-01T00:00:00Z') }); assert.equal(headers.get('If-Modified-Since'), 'Fri, 01 Jan 2021 00:00:00 GMT'); - - headers.set('If-Modified-Since', 'Fri, 31 Dec 2021 23:59:59 GMT'); - assert.equal(headers.get('If-Modified-Since'), 'Fri, 31 Dec 2021 23:59:59 GMT'); - - headers.set('If-Modified-Since', ''); - assert.equal(headers.get('If-Modified-Since'), ''); - - headers.delete('If-Modified-Since'); - assert.equal(headers.get('If-Modified-Since'), null); }); - it('handles the If-Unmodified-Since header', () => { - let headers = new SuperHeaders({ 'If-Unmodified-Since': 'Fri, 01 Jan 2021 00:00:00 GMT' }); + it('handles the ifUnmodifiedSince property', () => { + let headers = new SuperHeaders({ ifUnmodifiedSince: new Date('2021-01-01T00:00:00Z') }); assert.equal(headers.get('If-Unmodified-Since'), 'Fri, 01 Jan 2021 00:00:00 GMT'); - - headers.set('If-Unmodified-Since', 'Fri, 31 Dec 2021 23:59:59 GMT'); - assert.equal(headers.get('If-Unmodified-Since'), 'Fri, 31 Dec 2021 23:59:59 GMT'); - - headers.set('If-Unmodified-Since', ''); - assert.equal(headers.get('If-Unmodified-Since'), ''); - - headers.delete('If-Unmodified-Since'); - assert.equal(headers.get('If-Unmodified-Since'), null); }); - it('handles the Set-Cookie header', () => { - let headers = new SuperHeaders({ 'Set-Cookie': 'session=abc' }); - assert.deepEqual(headers.getSetCookie(), ['session=abc']); - - headers.set('Set-Cookie', 'theme=dark'); - assert.deepEqual(headers.getSetCookie(), ['theme=dark']); + it('handles the referer property', () => { + let headers = new SuperHeaders({ referer: 'https://example.com' }); + assert.equal(headers.get('Referer'), 'https://example.com'); + }); - headers.set('Set-Cookie', ''); - assert.deepEqual(headers.getSetCookie(), ['']); + it('handles the setCookie property', () => { + let headers = new SuperHeaders({ + setCookie: [ + { name: 'session', value: 'abc', path: '/' }, + { name: 'theme', value: 'dark', expires: new Date('2021-12-31T23:59:59Z') }, + ], + }); + assert.deepEqual(headers.getSetCookie(), [ + 'session=abc; Path=/', + 'theme=dark; Expires=Fri, 31 Dec 2021 23:59:59 GMT', + ]); + }); - headers.delete('Set-Cookie'); - assert.deepEqual(headers.getSetCookie(), []); + it('stringifies unknown properties with non-string values', () => { + let headers = new SuperHeaders({ unknown: 42 }); + assert.equal(headers.get('Unknown'), '42'); }); }); - describe('header-specific getters and setters', () => { - it('handles Accept-Language header', () => { + describe('property getters and setters', () => { + it('supports the acceptLanguage property', () => { let headers = new SuperHeaders(); assert.ok(headers.acceptLanguage instanceof AcceptLanguage); @@ -477,7 +276,7 @@ describe('SuperHeaders', () => { assert.equal(headers.acceptLanguage.toString(), ''); }); - it('handles Age header', () => { + it('supports the age property', () => { let headers = new SuperHeaders(); assert.equal(headers.age, null); @@ -492,7 +291,7 @@ describe('SuperHeaders', () => { assert.equal(headers.age, null); }); - it('handles Cache-Control header', () => { + it('supports the cacheControl property', () => { let headers = new SuperHeaders(); assert.ok(headers.cacheControl instanceof CacheControl); @@ -513,7 +312,19 @@ describe('SuperHeaders', () => { assert.equal(headers.cacheControl.toString(), ''); }); - it('handles Content-Disposition header', () => { + it('supports the connection property', () => { + let headers = new SuperHeaders(); + + assert.equal(headers.connection, null); + + headers.connection = 'close'; + assert.equal(headers.connection, 'close'); + + headers.connection = null; + assert.equal(headers.connection, null); + }); + + it('supports the contentDisposition property', () => { let headers = new SuperHeaders(); assert.ok(headers.contentDisposition instanceof ContentDisposition); @@ -534,7 +345,7 @@ describe('SuperHeaders', () => { assert.equal(headers.contentDisposition.toString(), ''); }); - it('handles Content-Length header', () => { + it('supports the contentLength property', () => { let headers = new SuperHeaders(); assert.equal(headers.contentLength, null); @@ -549,7 +360,7 @@ describe('SuperHeaders', () => { assert.equal(headers.contentLength, null); }); - it('handles Content-Type header', () => { + it('supports the contentType property', () => { let headers = new SuperHeaders(); assert.ok(headers.contentType instanceof ContentType); @@ -569,7 +380,7 @@ describe('SuperHeaders', () => { assert.equal(headers.contentType.toString(), ''); }); - it('handles Cookie header', () => { + it('supports the cookie property', () => { let headers = new SuperHeaders(); assert.ok(headers.cookie instanceof Cookie); @@ -589,7 +400,7 @@ describe('SuperHeaders', () => { assert.equal(headers.cookie.toString(), ''); }); - it('handles Date header', () => { + it('supports the date property', () => { let headers = new SuperHeaders(); assert.equal(headers.date, null); @@ -602,7 +413,7 @@ describe('SuperHeaders', () => { assert.equal(headers.date, null); }); - it('handles Expires header', () => { + it('supports the expires property', () => { let headers = new SuperHeaders(); assert.equal(headers.expires, null); @@ -615,7 +426,19 @@ describe('SuperHeaders', () => { assert.equal(headers.expires, null); }); - it('handles Last-Modified header', () => { + it('supports the host property', () => { + let headers = new SuperHeaders(); + + assert.equal(headers.host, null); + + headers.host = 'example.com'; + assert.equal(headers.host, 'example.com'); + + headers.host = null; + assert.equal(headers.host, null); + }); + + it('supports the lastModified property', () => { let headers = new SuperHeaders(); assert.equal(headers.lastModified, null); @@ -628,7 +451,7 @@ describe('SuperHeaders', () => { assert.equal(headers.lastModified, null); }); - it('handles If-Modified-Since header', () => { + it('supports the ifModifiedSince property', () => { let headers = new SuperHeaders(); assert.equal(headers.ifModifiedSince, null); @@ -641,7 +464,7 @@ describe('SuperHeaders', () => { assert.equal(headers.ifModifiedSince, null); }); - it('handles If-Unmodified-Since header', () => { + it('supports the ifUnmodifiedSince property', () => { let headers = new SuperHeaders(); assert.equal(headers.ifUnmodifiedSince, null); @@ -654,7 +477,19 @@ describe('SuperHeaders', () => { assert.equal(headers.ifUnmodifiedSince, null); }); - it('handles Set-Cookie header', () => { + it('supports the referer property', () => { + let headers = new SuperHeaders(); + + assert.equal(headers.referer, null); + + headers.referer = 'https://example.com'; + assert.equal(headers.referer, 'https://example.com'); + + headers.referer = null; + assert.equal(headers.referer, null); + }); + + it('supports the setCookie property', () => { let headers = new SuperHeaders(); assert.deepEqual(headers.setCookie, []); @@ -702,18 +537,4 @@ describe('SuperHeaders', () => { assert.deepEqual(headers.setCookie, []); }); }); - - describe('toString', () => { - it('omits empty values when stringified', () => { - let headers = new SuperHeaders(); - - // This should appear in the string since it has a media type, it's complete - headers.contentType = 'text/plain'; - - // This should not appear in the string since it's incomplete, missing the type - headers.contentDisposition.filename = 'example.txt'; - - assert.equal(headers.toString(), 'Content-Type: text/plain'); - }); - }); }); diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index d579cb101d9..ab5ee936ee3 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -11,6 +11,8 @@ import { isIterable, isValidDate } from './utils.ts'; const CRLF = '\r\n'; const SetCookieKey = 'set-cookie'; +type DateInit = number | Date; + interface SuperHeadersPropertyInit { /** * The [`Accept-Language`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) header value. @@ -43,23 +45,23 @@ interface SuperHeadersPropertyInit { /** * The [`Date`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Date) header value. */ - date?: string | Date; + date?: string | DateInit; /** * The [`Expires`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires) header value. */ - expires?: string | Date; + expires?: string | DateInit; /** * The [`If-Modified-Since`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since) header value. */ - ifModifiedSince?: string | Date; + ifModifiedSince?: string | DateInit; /** * The [`If-Unmodified-Since`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Unmodified-Since) header value. */ - ifUnmodifiedSince?: string | Date; + ifUnmodifiedSince?: string | DateInit; /** * The [`Last-Modified`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified) header value. */ - lastModified?: string | Date; + lastModified?: string | DateInit; /** * The [`Set-Cookie`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) header value(s). */ @@ -67,7 +69,7 @@ interface SuperHeadersPropertyInit { } export type SuperHeadersInit = - | Iterable<[string, string | HeaderValue]> + | Iterable<[string, string]> | (SuperHeadersPropertyInit & Record<string, string | HeaderValue>); /** @@ -100,13 +102,17 @@ export class SuperHeaders extends Headers { this.append(name, value); } } else if (typeof init === 'object') { - for (let name in init) { - if (Object.prototype.hasOwnProperty.call(init, name)) { - let setter = Object.getOwnPropertyDescriptor(SuperHeaders.prototype, name)?.set; - if (setter) { - setter.call(this, init[name]); + for (let name of Object.getOwnPropertyNames(init)) { + let value = init[name]; + + if (typeof value === 'string') { + this.set(name, value); + } else { + let descriptor = Object.getOwnPropertyDescriptor(SuperHeaders.prototype, name); + if (descriptor?.set) { + descriptor.set.call(this, value); } else { - this.append(name, init[name]); + this.set(name, value.toString()); } } } @@ -120,12 +126,13 @@ export class SuperHeaders extends Headers { * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/append) */ - append(name: string, value: string | HeaderValue): void { + append(name: string, value: string): void { let key = name.toLowerCase(); if (key === SetCookieKey) { - this.#setCookieValues.push(value as string | SetCookie); + this.#setCookieValues.push(value); } else { let existingValue = this.#map.get(key); + // TODO: check if it's an empty string this.#map.set(key, existingValue ? `${existingValue}, ${value}` : value); } } @@ -152,18 +159,16 @@ export class SuperHeaders extends Headers { get(name: string): string | null { let key = name.toLowerCase(); if (key === SetCookieKey) { - return this.#setCookieValues.map((value) => value.toString()).join(', '); + return this.getSetCookie().join(', '); } else { let value = this.#map.get(key); if (typeof value === 'string') { return value; - } else if (value instanceof Date) { - return value.toUTCString(); - } else if (value == null) { - return null; - } else { + } else if (value != null) { let str = value.toString(); return str === '' ? null : str; + } else { + return null; } } } @@ -217,16 +222,16 @@ export class SuperHeaders extends Headers { */ *entries(): IterableIterator<[string, string]> { for (let [key] of this.#map) { - let stringValue = this.get(key); - if (stringValue) { - yield [key, stringValue]; + let str = this.get(key); + if (str) { + yield [key, str]; } } for (let value of this.#setCookieValues) { - let stringValue = value.toString(); - if (stringValue) { - yield [SetCookieKey, stringValue]; + let str = value.toString(); + if (str) { + yield [SetCookieKey, str]; } } } @@ -299,11 +304,7 @@ export class SuperHeaders extends Headers { } set acceptLanguage(value: string | AcceptLanguageInit | undefined | null) { - if (value != null) { - this.#setHeaderValue('accept-language', AcceptLanguage, value); - } else { - this.#map.delete('accept-language'); - } + this.#setHeaderValue('accept-language', AcceptLanguage, value); } /** @@ -318,11 +319,7 @@ export class SuperHeaders extends Headers { } set age(value: string | number | undefined | null) { - if (value != null) { - this.#map.set('age', value); - } else { - this.#map.delete('age'); - } + this.#setNumberValue('age', value); } /** @@ -337,11 +334,23 @@ export class SuperHeaders extends Headers { } set cacheControl(value: string | CacheControlInit | undefined | null) { - if (value != null) { - this.#setHeaderValue('cache-control', CacheControl, value); - } else { - this.#map.delete('cache-control'); - } + this.#setHeaderValue('cache-control', CacheControl, value); + } + + /** + * The `Connection` header controls whether the network connection stays open after the current + * transaction finishes. + * + * [MDN `Connection` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7230#section-6.1) + */ + get connection(): string | null { + return this.get('connection'); + } + + set connection(value: string | undefined | null) { + this.#setValue('connection', value); } /** @@ -356,11 +365,7 @@ export class SuperHeaders extends Headers { } set contentDisposition(value: string | ContentDispositionInit | undefined | null) { - if (value != null) { - this.#setHeaderValue('content-disposition', ContentDisposition, value); - } else { - this.#map.delete('content-disposition'); - } + this.#setHeaderValue('content-disposition', ContentDisposition, value); } /** @@ -375,11 +380,7 @@ export class SuperHeaders extends Headers { } set contentLength(value: string | number | undefined | null) { - if (value != null) { - this.#map.set('content-length', value); - } else { - this.#map.delete('content-length'); - } + this.#setNumberValue('content-length', value); } /** @@ -394,11 +395,7 @@ export class SuperHeaders extends Headers { } set contentType(value: string | ContentTypeInit | undefined | null) { - if (value != null) { - this.#setHeaderValue('content-type', ContentType, value); - } else { - this.#map.delete('content-type'); - } + this.#setHeaderValue('content-type', ContentType, value); } /** @@ -414,11 +411,7 @@ export class SuperHeaders extends Headers { } set cookie(value: string | CookieInit | undefined | null) { - if (value != null) { - this.#setHeaderValue('cookie', Cookie, value); - } else { - this.#map.delete('cookie'); - } + this.#setHeaderValue('cookie', Cookie, value); } /** @@ -432,12 +425,8 @@ export class SuperHeaders extends Headers { return this.#getDateValue('date'); } - set date(value: string | Date | undefined | null) { - if (value != null) { - this.#map.set('date', value); - } else { - this.#map.delete('date'); - } + set date(value: string | DateInit | undefined | null) { + this.#setDateValue('date', value); } /** @@ -451,12 +440,23 @@ export class SuperHeaders extends Headers { return this.#getDateValue('expires'); } - set expires(value: string | Date | undefined | null) { - if (value != null) { - this.#map.set('expires', value); - } else { - this.#map.delete('expires'); - } + set expires(value: string | DateInit | undefined | null) { + this.#setDateValue('expires', value); + } + + /** + * The `Host` header specifies the domain name of the server and (optionally) the TCP port number. + * + * [MDN `Host` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7230#section-5.4) + */ + get host(): string | null { + return this.get('host'); + } + + set host(value: string | undefined | null) { + this.#setValue('host', value); } /** @@ -471,12 +471,8 @@ export class SuperHeaders extends Headers { return this.#getDateValue('if-modified-since'); } - set ifModifiedSince(value: string | Date | undefined | null) { - if (value != null) { - this.#map.set('if-modified-since', value); - } else { - this.#map.delete('if-modified-since'); - } + set ifModifiedSince(value: string | DateInit | undefined | null) { + this.#setDateValue('if-modified-since', value); } /** @@ -491,12 +487,8 @@ export class SuperHeaders extends Headers { return this.#getDateValue('if-unmodified-since'); } - set ifUnmodifiedSince(value: string | Date | undefined | null) { - if (value != null) { - this.#map.set('if-unmodified-since', value); - } else { - this.#map.delete('if-unmodified-since'); - } + set ifUnmodifiedSince(value: string | DateInit | undefined | null) { + this.#setDateValue('if-unmodified-since', value); } /** @@ -510,12 +502,24 @@ export class SuperHeaders extends Headers { return this.#getDateValue('last-modified'); } - set lastModified(value: string | Date | undefined | null) { - if (value != null) { - this.#map.set('last-modified', value); - } else { - this.#map.delete('last-modified'); - } + set lastModified(value: string | DateInit | undefined | null) { + this.#setDateValue('last-modified', value); + } + + /** + * The `Referer` header contains the address of the previous web page from which a link to the + * currently requested page was followed. + * + * [MDN `Referer` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.5.2) + */ + get referer(): string | null { + return this.get('referer'); + } + + set referer(value: string | undefined | null) { + this.#setValue('referer', value); } /** @@ -552,78 +556,68 @@ export class SuperHeaders extends Headers { // helpers - #getDateValue(key: string): Date | null { - let value = this.#map.get(key); - if (value) { - if (value instanceof Date) { - return value; - } - - if (typeof value === 'string') { - let date = new Date(value); - if (isValidDate(date)) { - this.#map.set(key, date); // cache the parsed date - return date; - } else { - this.#map.delete(key); // bad value, remove it - } - } - - this.#map.delete(key); // bad value, remove it + #setValue(key: string, value: string | undefined | null): void { + if (value != null) { + this.#map.set(key, value); + } else { + this.#map.delete(key); } - - return null; } - #getNumberValue(key: string): number | null { + #getHeaderValue<T extends HeaderValue>(key: string, ctor: new (init?: any) => T): T { let value = this.#map.get(key); - if (value !== undefined) { - if (typeof value === 'number') { - return value; - } + if (value !== undefined) { if (typeof value === 'string') { - let num = parseInt(value, 10); - if (!isNaN(num)) { - this.#map.set(key, num); // cache the parsed number - return num; - } else { - this.#map.delete(key); // bad value, remove it - } + let obj = new ctor(value); + this.#map.set(key, obj); // cache the new object + return obj; + } else { + return value as T; } - - this.#map.delete(key); // bad value, remove it } - return null; + let header = new ctor(); + this.#map.set(key, header); + return header; + } + + #setHeaderValue(key: string, ctor: new (init?: string) => HeaderValue, value: any): void { + if (value != null) { + this.#map.set(key, typeof value === 'string' ? value : new ctor(value)); + } else { + this.#map.delete(key); + } } - #getHeaderValue<T extends HeaderValue>(key: string, ctor: new (init?: string) => T): T { + #getDateValue(key: string): Date | null { let value = this.#map.get(key); - if (value !== undefined) { - if (typeof value === 'string') { - let headerValue = new ctor(value); - this.#map.set(key, headerValue); - return headerValue; - } else { - return value as T; - } + return value === undefined ? null : new Date(value as string); + } + + #setDateValue(key: string, value: string | DateInit | undefined | null): void { + if (value != null) { + this.#map.set( + key, + typeof value === 'string' + ? value + : (typeof value === 'number' ? new Date(value) : value).toUTCString(), + ); } else { - let headerValue = new ctor(); - this.#map.set(key, headerValue); - return headerValue; + this.#map.delete(key); } } - #setHeaderValue<T>( - key: string, - ctor: new (init?: string | T) => HeaderValue, - value: string | T, - ): void { - if (typeof value === 'string' || value instanceof ctor) { - this.#map.set(key, value); + #getNumberValue(key: string): number | null { + let value = this.#map.get(key); + return value === undefined ? null : parseInt(value as string, 10); + } + + #setNumberValue(key: string, value: string | number | undefined | null): void { + if (value != null) { + this.#map.set(key, typeof value === 'string' ? value : value.toString()); } else { - this.#map.set(key, new ctor(value)); + this.#map.delete(key); } } } From 25603e4538097461b58f11f2c36ce7bdbeb024c0 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 19 Dec 2024 18:09:28 -0800 Subject: [PATCH 544/730] Add Accept header support --- packages/headers/CHANGELOG.md | 1 + packages/headers/README.md | 35 ++++- .../headers/src/lib/accept-language.test.ts | 42 +++-- packages/headers/src/lib/accept-language.ts | 52 ++++--- packages/headers/src/lib/accept.test.ts | 147 ++++++++++++++++++ packages/headers/src/lib/accept.ts | 144 +++++++++++++++++ packages/headers/src/lib/param-values.ts | 13 +- .../headers/src/lib/super-headers.test.ts | 27 +++- packages/headers/src/lib/super-headers.ts | 38 +++-- 9 files changed, 440 insertions(+), 59 deletions(-) create mode 100644 packages/headers/src/lib/accept.test.ts create mode 100644 packages/headers/src/lib/accept.ts diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index a074b2ed053..5ae2dc28899 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -73,6 +73,7 @@ let headers = new SuperHeaders({ lastModified: ms }); ``` - Adds support for + - `headers.accept` - `headers.connection` - `headers.host` - `headers.referer` diff --git a/packages/headers/README.md b/packages/headers/README.md index e3a7d1b6048..c0a652d4707 100644 --- a/packages/headers/README.md +++ b/packages/headers/README.md @@ -24,13 +24,22 @@ import Headers from '@mjackson/headers'; let headers = new Headers(); -// Accept-Language +// Accept +headers.accept = 'text/html,text/*;q=0.9'; + +console.log(headers.accept.mediaTypes); // [ 'text/html', 'text/*' ] +console.log(Object.fromEntries(headers.accept.entries())); // { 'text/html': 1, 'text/*': 0.9 } + +headers.accept.set('text/plain', 0.9); +headers.accept.set('text/*', 0.8); + +console.log(headers.get('Accept')); // "text/html,text/plain;q=0.9,text/*;q=0.8" +// Accept-Language headers.acceptLanguage = 'en-US,en;q=0.9'; console.log(headers.acceptLanguage.languages); // [ 'en-US', 'en' ] -console.log(headers.acceptLanguage.entries()); -// [Map Entries] { [ 'en-US', 1 ], [ 'en', 0.9 ] } +console.log(Object.fromEntries(headers.acceptLanguage.entries())); // { 'en-US': 1, en: 0.9 } // Content-Type headers.contentType = 'application/json; charset=utf-8'; @@ -168,6 +177,7 @@ The following headers are currently supported: - [Installation](#installation) - [Overview](#overview) - [Low-level API](#low-level-api) + - [Accept](#accept) - [Accept-Language](#accept-language) - [Cache-Control](#cache-control) - [Content-Disposition](#content-disposition) @@ -178,6 +188,25 @@ The following headers are currently supported: If you need support for a header that isn't listed here, please [send a PR](https://github.com/mjackson/remix-the-web/pulls)! The goal is to have first-class support for all common HTTP headers. +### Accept + +```ts +let header = new Accept('text/html;text/*;q=0.9'); +header.get('text/html'); // 1 +header.set('text/html', 0.8); +header.delete('text/html'); +header.has('text/*'); // true + +// Iterate over media type/quality pairs +for (let [mediaType, quality] of header) { + // ... +} + +// Alternative init styles +let header = new Accept({ 'text/html': 1, 'text/*': 0.9 }); +let header = new Accept(['text/html', ['text/*', 0.9]]); +``` + ### Accept-Language ```ts diff --git a/packages/headers/src/lib/accept-language.test.ts b/packages/headers/src/lib/accept-language.test.ts index 09a1146d14f..0a0b9788cd9 100644 --- a/packages/headers/src/lib/accept-language.test.ts +++ b/packages/headers/src/lib/accept-language.test.ts @@ -27,7 +27,7 @@ describe('Accept-Language', () => { assert.equal(header.get('en'), 0.9); }); - it('initializes with another Accept-Language', () => { + it('initializes with another AcceptLanguage', () => { let header = new AcceptLanguage(new AcceptLanguage('en-US,en;q=0.9')); assert.equal(header.get('en-US'), 1); assert.equal(header.get('en'), 0.9); @@ -40,7 +40,7 @@ describe('Accept-Language', () => { }); it('sets and gets languages', () => { - let header = new AcceptLanguage(''); + let header = new AcceptLanguage(); header.set('en', 0.9); assert.equal(header.get('en'), 0.9); }); @@ -64,6 +64,16 @@ describe('Accept-Language', () => { assert.equal(header.size, 0); }); + it('gets all languages', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + assert.deepEqual(header.languages, ['en-US', 'en']); + }); + + it('gets all qualities', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + assert.deepEqual(header.qualities, [1, 0.9]); + }); + it('iterates over entries', () => { let header = new AcceptLanguage('en-US,en;q=0.9'); let entries = Array.from(header.entries()); @@ -73,14 +83,13 @@ describe('Accept-Language', () => { ]); }); - it('gets all languages', () => { - let header = new AcceptLanguage('en-US,en;q=0.9'); - assert.deepEqual(header.languages, ['en-US', 'en']); - }); - - it('gets all qualities', () => { + it('is directly iterable', () => { let header = new AcceptLanguage('en-US,en;q=0.9'); - assert.deepEqual(header.qualities, [1, 0.9]); + let entries = Array.from(header); + assert.deepEqual(entries, [ + ['en-US', 1], + ['en', 0.9], + ]); }); it('uses forEach correctly', () => { @@ -105,20 +114,10 @@ describe('Accept-Language', () => { assert.equal(header.toString(), 'en-US,en;q=0.9'); }); - it('is directly iterable', () => { - let header = new AcceptLanguage('en-US,en;q=0.9'); - let entries = Array.from(header); - assert.deepEqual(entries, [ - ['en-US', 1], - ['en', 0.9], - ]); - }); - it('handles setting empty quality values', () => { - let header = new AcceptLanguage(''); + let header = new AcceptLanguage(); header.set('en-US'); assert.equal(header.get('en-US'), 1); - assert.equal(header.toString(), 'en-US'); }); it('overwrites existing quality values', () => { @@ -128,10 +127,9 @@ describe('Accept-Language', () => { }); it('handles setting wildcard value', () => { - let header = new AcceptLanguage(''); + let header = new AcceptLanguage(); header.set('*'); assert.equal(header.get('*'), 1); - assert.equal(header.toString(), '*'); }); it('sorts initial value', () => { diff --git a/packages/headers/src/lib/accept-language.ts b/packages/headers/src/lib/accept-language.ts index 37af9eda65b..5256fc2bd5c 100644 --- a/packages/headers/src/lib/accept-language.ts +++ b/packages/headers/src/lib/accept-language.ts @@ -19,14 +19,22 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { if (init) { if (typeof init === 'string') { - let params = parseParams(init, ','); - for (let [language, quality] of params) { - if (typeof quality === 'string') { - language = language.slice(0, -2).trim(); - } else { - quality = '1'; + for (let piece of init.split(/\s*,\s*/)) { + let params = parseParams(piece); + if (params.length < 1) continue; + + let language = params[0][0]; + let quality = 1; + + for (let i = 1; i < params.length; i++) { + let [key, value] = params[i]; + if (key === 'q') { + quality = Number(value); + break; + } } - this.#map.set(language, Number(quality)); + + this.#map.set(language, quality); } } else if (isIterable(init)) { for (let language of init) { @@ -52,6 +60,20 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { this.#map = new Map([...this.#map].sort(([, a], [, b]) => b - a)); } + /** + * An array of all locale identifiers in the `Accept-Language` header. + */ + get languages(): string[] { + return Array.from(this.#map.keys()); + } + + /** + * An array of all quality values in the `Accept-Language` header. + */ + get qualities(): number[] { + return Array.from(this.#map.values()); + } + /** * Gets the quality of a language with the given locale identifier from the `Accept-Language` header. */ @@ -60,7 +82,7 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { } /** - * Sets a language with the given quality in the `Accept-Language` header. + * Sets a language with the given quality (defaults to 1) in the `Accept-Language` header. */ set(language: string, quality = 1): void { this.#map.set(language, quality); @@ -92,23 +114,17 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { return this.#map.entries(); } - get languages(): string[] { - return Array.from(this.#map.keys()); - } - - get qualities(): number[] { - return Array.from(this.#map.values()); - } - [Symbol.iterator](): IterableIterator<[string, number]> { return this.entries(); } forEach( - callback: (language: string, quality: number, map: Map<string, number>) => void, + callback: (language: string, quality: number, header: AcceptLanguage) => void, thisArg?: any, ): void { - this.#map.forEach((quality, language, map) => callback(language, quality, map), thisArg); + for (let [language, quality] of this) { + callback.call(thisArg, language, quality, this); + } } /** diff --git a/packages/headers/src/lib/accept.test.ts b/packages/headers/src/lib/accept.test.ts new file mode 100644 index 00000000000..c9d2d69a45e --- /dev/null +++ b/packages/headers/src/lib/accept.test.ts @@ -0,0 +1,147 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { Accept } from './accept.ts'; + +describe('Accept', () => { + it('initializes with an empty string', () => { + let header = new Accept(''); + assert.equal(header.size, 0); + }); + + it('initializes with a string', () => { + let header = new Accept('text/html,application/json;q=0.9'); + assert.equal(header.get('text/html'), 1); + assert.equal(header.get('application/json'), 0.9); + }); + + it('initializes with an array', () => { + let header = new Accept(['text/html', ['application/json', 0.9]]); + assert.equal(header.get('text/html'), 1); + assert.equal(header.get('application/json'), 0.9); + }); + + it('initializes with an object', () => { + let header = new Accept({ 'text/html': 1, 'application/json': 0.9 }); + assert.equal(header.get('text/html'), 1); + assert.equal(header.get('application/json'), 0.9); + }); + + it('initializes with another Accept', () => { + let header = new Accept(new Accept('text/html,application/json;q=0.9')); + assert.equal(header.get('text/html'), 1); + assert.equal(header.get('application/json'), 0.9); + }); + + it('handles whitespace in initial value', () => { + let header = new Accept(' text/html , application/json;q= 0.9 '); + assert.equal(header.get('text/html'), 1); + assert.equal(header.get('application/json'), 0.9); + }); + + it('sets and gets media types', () => { + let header = new Accept(); + header.set('application/json', 0.9); + assert.equal(header.get('application/json'), 0.9); + }); + + it('deletes media types', () => { + let header = new Accept('text/html'); + assert.equal(header.delete('text/html'), true); + assert.equal(header.delete('application/json'), false); + assert.equal(header.get('text/html'), undefined); + }); + + it('checks if media type exists', () => { + let header = new Accept('text/html'); + assert.equal(header.has('text/html'), true); + assert.equal(header.has('application/json'), false); + }); + + it('clears all media types', () => { + let header = new Accept('text/html,application/json;q=0.9'); + header.clear(); + assert.equal(header.size, 0); + }); + + it('gets all media types', () => { + let header = new Accept('text/html,application/json;q=0.9'); + assert.deepEqual(header.mediaTypes, ['text/html', 'application/json']); + }); + + it('gets all qualities', () => { + let header = new Accept('text/html,application/json;q=0.9'); + assert.deepEqual(header.qualities, [1, 0.9]); + }); + + it('iterates over entries', () => { + let header = new Accept('text/html,application/json;q=0.9'); + let entries = Array.from(header.entries()); + assert.deepEqual(entries, [ + ['text/html', 1], + ['application/json', 0.9], + ]); + }); + + it('is directly iterable', () => { + let header = new Accept('text/html,application/json;q=0.9'); + let mediaTypes = Array.from(header); + assert.deepEqual(mediaTypes, [ + ['text/html', 1], + ['application/json', 0.9], + ]); + }); + + it('uses forEach correctly', () => { + let header = new Accept('text/html,application/json;q=0.9'); + let result: [string, number][] = []; + header.forEach((mediaType, quality) => { + result.push([mediaType, quality]); + }); + assert.deepEqual(result, [ + ['text/html', 1], + ['application/json', 0.9], + ]); + }); + + it('returns correct size', () => { + let header = new Accept('text/html,application/json;q=0.9'); + assert.equal(header.size, 2); + }); + + it('converts to string correctly', () => { + let header = new Accept('text/html,application/json;q=0.9'); + assert.equal(header.toString(), 'text/html,application/json;q=0.9'); + }); + + it('handles setting empty quality values', () => { + let header = new Accept(); + header.set('text/html'); + assert.equal(header.get('text/html'), 1); + }); + + it('overwrites existing quality values', () => { + let header = new Accept('text/html,application/json;q=0.9'); + header.set('application/json', 0.8); + assert.equal(header.get('application/json'), 0.8); + }); + + it('handles setting wildcard media types', () => { + let header = new Accept(); + header.set('*/*'); + assert.equal(header.get('*/*'), 1); + }); + + it('sorts initial value', () => { + let header = new Accept('application/json;q=0.9,text/html'); + assert.equal(header.toString(), 'text/html,application/json;q=0.9'); + assert.deepEqual(header.mediaTypes, ['text/html', 'application/json']); + }); + + it('sorts updated value', () => { + let header = new Accept('text/html,application/json;q=0.9'); + header.set('application/json', 0.8); + assert.equal(header.toString(), 'text/html,application/json;q=0.8'); + assert.deepEqual(header.mediaTypes, ['text/html', 'application/json']); + }); +}); diff --git a/packages/headers/src/lib/accept.ts b/packages/headers/src/lib/accept.ts new file mode 100644 index 00000000000..02f3fc06767 --- /dev/null +++ b/packages/headers/src/lib/accept.ts @@ -0,0 +1,144 @@ +import { type HeaderValue } from './header-value.ts'; +import { parseParams } from './param-values.ts'; +import { isIterable } from './utils.ts'; + +export type AcceptInit = Iterable<string | [string, number]> | Record<string, number>; + +/** + * The value of a `Accept` HTTP header. + * + * [MDN `Accept` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2) + */ +export class Accept implements HeaderValue, Iterable<[string, number]> { + #map: Map<string, number>; + + constructor(init?: string | AcceptInit) { + this.#map = new Map(); + + if (init) { + if (typeof init === 'string') { + for (let piece of init.split(/\s*,\s*/)) { + let params = parseParams(piece); + if (params.length < 1) continue; + + let mediaType = params[0][0]; + let quality = 1; + + for (let i = 1; i < params.length; i++) { + let [key, value] = params[i]; + if (key === 'q') { + quality = Number(value); + break; + } + } + + this.#map.set(mediaType, quality); + } + } else if (isIterable(init)) { + for (let mediaType of init) { + if (Array.isArray(mediaType)) { + this.#map.set(mediaType[0], mediaType[1]); + } else { + this.#map.set(mediaType, 1); + } + } + } else { + for (let mediaType of Object.getOwnPropertyNames(init)) { + this.#map.set(mediaType, init[mediaType]); + } + } + + this.#sort(); + } + } + + #sort() { + this.#map = new Map([...this.#map].sort(([, a], [, b]) => b - a)); + } + + /** + * An array of media types in the `Accept` header. + */ + get mediaTypes(): string[] { + return Array.from(this.#map.keys()); + } + + /** + * An array of quality values in the `Accept` header. + */ + get qualities(): number[] { + return Array.from(this.#map.values()); + } + + /** + * Gets the quality of a given media type from the `Accept` header. + */ + get(mediaType: string): number | undefined { + return this.#map.get(mediaType); + } + + /** + * Sets a media type with the given quality (defaults to 1) in the `Accept` header. + */ + set(mediaType: string, quality = 1): void { + this.#map.set(mediaType, quality); + this.#sort(); + } + + /** + * Removes a given mediaType from the `Accept` header. + */ + delete(mediaType: string): boolean { + return this.#map.delete(mediaType); + } + + /** + * True if a given media type is present in the `Accept` header. + */ + has(mediaType: string): boolean { + return this.#map.has(mediaType); + } + + /** + * Removes all media types from the `Accept` header. + */ + clear(): void { + this.#map.clear(); + } + + entries(): IterableIterator<[string, number]> { + return this.#map.entries(); + } + + [Symbol.iterator](): IterableIterator<[string, number]> { + return this.entries(); + } + + forEach( + callback: (mediaType: string, quality: number, header: Accept) => void, + thisArg?: any, + ): void { + for (let [mediaType, quality] of this) { + callback.call(thisArg, mediaType, quality, this); + } + } + + /** + * The number of media types in the `Accept` header. + */ + get size(): number { + return this.#map.size; + } + + toString(): string { + let pairs: string[] = []; + + for (let [mediaType, quality] of this.#map) { + pairs.push(`${mediaType}${quality === 1 ? '' : `;q=${quality}`}`); + } + + return pairs.join(','); + } +} diff --git a/packages/headers/src/lib/param-values.ts b/packages/headers/src/lib/param-values.ts index fa1391d6b45..6e517593358 100644 --- a/packages/headers/src/lib/param-values.ts +++ b/packages/headers/src/lib/param-values.ts @@ -2,14 +2,17 @@ export function parseParams( input: string, delimiter: ';' | ',' = ';', ): [string, string | undefined][] { - let regex = /(?:^|;)\s*([^=;\s]+)(\s*=\s*(?:"((?:[^"\\]|\\.)*)"|((?:[^;]|\\\;)+))?)?/g; - if (delimiter === ',') { - regex = /(?:^|,)\s*([^=,\s]+)(\s*=\s*(?:"((?:[^"\\]|\\.)*)"|((?:[^,]|\\\,)+))?)?/g; - } + // This parser splits on the delimiter and unquotes any quoted values + // like `filename="the\\ filename.txt"`. + let parser = + delimiter === ';' + ? /(?:^|;)\s*([^=;\s]+)(\s*=\s*(?:"((?:[^"\\]|\\.)*)"|((?:[^;]|\\\;)+))?)?/g + : /(?:^|,)\s*([^=,\s]+)(\s*=\s*(?:"((?:[^"\\]|\\.)*)"|((?:[^,]|\\\,)+))?)?/g; + let params: [string, string | undefined][] = []; let match; - while ((match = regex.exec(input)) !== null) { + while ((match = parser.exec(input)) !== null) { let key = match[1].trim(); let value: string | undefined; diff --git a/packages/headers/src/lib/super-headers.test.ts b/packages/headers/src/lib/super-headers.test.ts index 294e3f7cea3..9e3d96761be 100644 --- a/packages/headers/src/lib/super-headers.test.ts +++ b/packages/headers/src/lib/super-headers.test.ts @@ -1,12 +1,12 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; +import { Accept } from './accept.ts'; import { AcceptLanguage } from './accept-language.ts'; import { CacheControl } from './cache-control.ts'; import { ContentDisposition } from './content-disposition.ts'; import { ContentType } from './content-type.ts'; import { Cookie } from './cookie.ts'; -import { SetCookie } from './set-cookie.ts'; import { SuperHeaders } from './super-headers.ts'; describe('SuperHeaders', () => { @@ -157,6 +157,11 @@ describe('SuperHeaders', () => { }); describe('constructor property init', () => { + it('handles the accept property', () => { + let headers = new SuperHeaders({ accept: { 'text/html': 1, 'application/json': 0.9 } }); + assert.equal(headers.get('Accept'), 'text/html,application/json;q=0.9'); + }); + it('handles the acceptLanguage property', () => { let headers = new SuperHeaders({ acceptLanguage: { 'en-US': 1, en: 0.9 } }); assert.equal(headers.get('Accept-Language'), 'en-US,en;q=0.9'); @@ -256,6 +261,26 @@ describe('SuperHeaders', () => { }); describe('property getters and setters', () => { + it('supports the accept property', () => { + let headers = new SuperHeaders(); + + assert.ok(headers.accept instanceof Accept); + + headers.accept = 'text/html,application/json;q=0.9'; + assert.deepEqual(headers.accept.size, 2); + assert.deepEqual(headers.accept.mediaTypes, ['text/html', 'application/json']); + assert.deepEqual(headers.accept.qualities, [1, 0.9]); + + headers.accept = { 'application/json': 0.8, 'text/html': 1 }; + assert.deepEqual(headers.accept.size, 2); + assert.deepEqual(headers.accept.mediaTypes, ['text/html', 'application/json']); + assert.deepEqual(headers.accept.qualities, [1, 0.8]); + + headers.accept = null; + assert.ok(headers.accept instanceof Accept); + assert.equal(headers.accept.toString(), ''); + }); + it('supports the acceptLanguage property', () => { let headers = new SuperHeaders(); diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index ab5ee936ee3..444fd461720 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -1,3 +1,4 @@ +import { type AcceptInit, Accept } from './accept.ts'; import { type AcceptLanguageInit, AcceptLanguage } from './accept-language.ts'; import { type CacheControlInit, CacheControl } from './cache-control.ts'; import { type ContentDispositionInit, ContentDisposition } from './content-disposition.ts'; @@ -14,6 +15,10 @@ const SetCookieKey = 'set-cookie'; type DateInit = number | Date; interface SuperHeadersPropertyInit { + /** + * The [`Accept`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) header value. + */ + accept?: string | AcceptInit; /** * The [`Accept-Language`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) header value. */ @@ -228,14 +233,15 @@ export class SuperHeaders extends Headers { } } - for (let value of this.#setCookieValues) { - let str = value.toString(); - if (str) { - yield [SetCookieKey, str]; - } + for (let value of this.getSetCookie()) { + yield [SetCookieKey, value]; } } + [Symbol.iterator](): IterableIterator<[string, string]> { + return this.entries(); + } + /** * Returns an iterator of all header keys (lowercase). * @@ -258,17 +264,13 @@ export class SuperHeaders extends Headers { } } - [Symbol.iterator](): IterableIterator<[string, string]> { - return this.entries(); - } - /** * Invokes the `callback` for each header key/value pair. * * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/forEach) */ forEach( - callback: (value: string, key: string, parent: SuperHeaders) => void, + callback: (value: string, key: string, headers: SuperHeaders) => void, thisArg?: any, ): void { for (let [key, value] of this) { @@ -291,6 +293,22 @@ export class SuperHeaders extends Headers { // Header-specific getters and setters + /** + * The `Accept` header is used by clients to indicate the media types that are acceptable + * in the response. + * + * [MDN `Accept` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2) + */ + get accept(): Accept { + return this.#getHeaderValue('accept', Accept); + } + + set accept(value: string | AcceptInit | undefined | null) { + this.#setHeaderValue('accept', Accept, value); + } + /** * The `Accept-Language` header contains information about preferred natural language for the * response. From cc1b9fd8c4e0c13b6463309bb76b5f0d703826f3 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 19 Dec 2024 18:13:53 -0800 Subject: [PATCH 545/730] Add Accept to top-level exports --- packages/headers/CHANGELOG.md | 10 ++++++++++ packages/headers/src/headers.ts | 1 + 2 files changed, 11 insertions(+) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 5ae2dc28899..175ce6d05f2 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -73,11 +73,21 @@ let headers = new SuperHeaders({ lastModified: ms }); ``` - Adds support for + - `headers.accept` - `headers.connection` - `headers.host` - `headers.referer` +- Adds low-level `Accept` API + +```ts +import { Accept } from '@mjackson/headers'; + +let header = new Accept({ 'text/html': 1, 'text/*': 0.9 }); +header.get('text/html'); // 1 +``` + ## v0.8.0 (2024-11-14) - Added CommonJS build diff --git a/packages/headers/src/headers.ts b/packages/headers/src/headers.ts index a2d4bce3d16..baa4bdd0ea1 100644 --- a/packages/headers/src/headers.ts +++ b/packages/headers/src/headers.ts @@ -1,3 +1,4 @@ +export { type AcceptInit, Accept } from './lib/accept.ts'; export { type AcceptLanguageInit, AcceptLanguage } from './lib/accept-language.ts'; export { type CacheControlInit, CacheControl } from './lib/cache-control.ts'; export { type ContentDispositionInit, ContentDisposition } from './lib/content-disposition.ts'; From 125989773996b5511d49c9210495399402e3a4ce Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 19 Dec 2024 18:45:43 -0800 Subject: [PATCH 546/730] Small tweaks --- packages/headers/src/lib/set-cookie.ts | 6 ++++-- packages/headers/src/lib/super-headers.ts | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/headers/src/lib/set-cookie.ts b/packages/headers/src/lib/set-cookie.ts index c5f6c7ed7dc..4afbfef436c 100644 --- a/packages/headers/src/lib/set-cookie.ts +++ b/packages/headers/src/lib/set-cookie.ts @@ -95,8 +95,10 @@ export class SetCookie implements HeaderValue, SetCookieInit { break; case 'expires': { if (typeof value === 'string') { - let v = new Date(value); - if (isValidDate(v)) this.expires = v; + let date = new Date(value); + if (isValidDate(date)) { + this.expires = date; + } } break; } diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index 444fd461720..16c51bace0b 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -7,7 +7,7 @@ import { type CookieInit, Cookie } from './cookie.ts'; import { canonicalHeaderName } from './header-names.ts'; import { type HeaderValue } from './header-value.ts'; import { type SetCookieInit, SetCookie } from './set-cookie.ts'; -import { isIterable, isValidDate } from './utils.ts'; +import { isIterable } from './utils.ts'; const CRLF = '\r\n'; const SetCookieKey = 'set-cookie'; @@ -595,9 +595,9 @@ export class SuperHeaders extends Headers { } } - let header = new ctor(); - this.#map.set(key, header); - return header; + let obj = new ctor(); + this.#map.set(key, obj); // cache the new object + return obj; } #setHeaderValue(key: string, ctor: new (init?: string) => HeaderValue, value: any): void { From 087d423555207b49e631c0e619616ec8fe2e835f Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 19 Dec 2024 22:24:49 -0800 Subject: [PATCH 547/730] Finish up support for Accept --- packages/headers/CHANGELOG.md | 42 +++++++-- packages/headers/README.md | 47 +++++++--- .../headers/src/lib/accept-language.test.ts | 92 +++++++++++-------- packages/headers/src/lib/accept-language.ts | 84 ++++++++++++++--- packages/headers/src/lib/accept.test.ts | 71 ++++++++------ packages/headers/src/lib/accept.ts | 86 +++++++++++++---- .../headers/src/lib/super-headers.test.ts | 6 +- 7 files changed, 310 insertions(+), 118 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 175ce6d05f2..3abe2a73c6a 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -72,22 +72,50 @@ let ms = new Date().getTime(); let headers = new SuperHeaders({ lastModified: ms }); ``` -- Adds support for +- Added `AcceptLanguage.prototype.accepts(language)`, `AcceptLanguage.prototype.getQuality(language)`, + `AcceptLanguage.prototype.getPreferred(languages)` - - `headers.accept` - - `headers.connection` - - `headers.host` - - `headers.referer` +```ts +import { AcceptLanguage } from '@mjackson/headers'; + +let header = new AcceptLanguage({ 'en-US': 1, en: 0.9 }); + +header.accepts('en-US'); // true +header.accepts('en-GB'); // true +header.accepts('en'); // true +header.accepts('fr'); // false + +header.getQuality('en-US'); // 1 +header.getQuality('en-GB'); // 0.9 + +header.getPreferred(['en-GB', 'en-US']); // 'en-US' +``` -- Adds low-level `Accept` API +- Added `Accept` support ```ts import { Accept } from '@mjackson/headers'; let header = new Accept({ 'text/html': 1, 'text/*': 0.9 }); -header.get('text/html'); // 1 + +header.accepts('text/html'); // true +header.accepts('text/plain'); // true +header.accepts('text/*'); // true +header.accepts('image/jpeg'); // false + +header.getQuality('text/html'); // 1 +header.getQuality('text/plain'); // 0.9 + +header.getPreferred(['text/html', 'text/plain']); // 'text/html' ``` +- Added property support (getters and setters) for + + - `headers.accept` + - `headers.connection` + - `headers.host` + - `headers.referer` + ## v0.8.0 (2024-11-14) - Added CommonJS build diff --git a/packages/headers/README.md b/packages/headers/README.md index c0a652d4707..b4eb06e6537 100644 --- a/packages/headers/README.md +++ b/packages/headers/README.md @@ -7,7 +7,7 @@ HTTP headers contain a wealth of information: - Who is sending this request? - What's in the payload and how is it encoded? - What is the filename of this file upload? -- and much, much more! +- and much more! The [built-in JavaScript `Headers` interface](https://developer.mozilla.org/en-US/docs/Web/API/Headers) accepts and gives you strings for everything, which you're probably used to parsing and stringifying manually as needed. This library aims to give you a more fluent interface for all of this information. Similar to how the DOM gives you programmatic access to HTML documents, `headers` gives you access to HTTP headers. @@ -30,6 +30,12 @@ headers.accept = 'text/html,text/*;q=0.9'; console.log(headers.accept.mediaTypes); // [ 'text/html', 'text/*' ] console.log(Object.fromEntries(headers.accept.entries())); // { 'text/html': 1, 'text/*': 0.9 } +headers.accept.accepts('text/html'); // true +headers.accept.accepts('text/plain'); // true +headers.accept.accepts('image/jpeg'); // false + +headers.accept.getPreferred(['text/plain', 'text/html']); // 'text/html' + headers.accept.set('text/plain', 0.9); headers.accept.set('text/*', 0.8); @@ -38,8 +44,14 @@ console.log(headers.get('Accept')); // "text/html,text/plain;q=0.9,text/*;q=0.8" // Accept-Language headers.acceptLanguage = 'en-US,en;q=0.9'; -console.log(headers.acceptLanguage.languages); // [ 'en-US', 'en' ] -console.log(Object.fromEntries(headers.acceptLanguage.entries())); // { 'en-US': 1, en: 0.9 } +console.log(headers.acceptLanguage.languages); // [ 'en-us', 'en' ] +console.log(Object.fromEntries(headers.acceptLanguage.entries())); // { 'en-us': 1, en: 0.9 } + +headers.acceptLanguage.accepts('en'); // true +headers.acceptLanguage.accepts('ja'); // false + +headers.acceptLanguage.getPreferred(['en-US', 'en-GB']); // 'en-US' +headers.acceptLanguage.getPreferred(['en', 'fr']); // 'en' // Content-Type headers.contentType = 'application/json; charset=utf-8'; @@ -192,10 +204,16 @@ If you need support for a header that isn't listed here, please [send a PR](http ```ts let header = new Accept('text/html;text/*;q=0.9'); -header.get('text/html'); // 1 -header.set('text/html', 0.8); -header.delete('text/html'); -header.has('text/*'); // true + +header.has('text/html'); // true +header.has('text/plain'); // false + +header.accepts('text/html'); // true +header.accepts('text/plain'); // true +header.accepts('text/*'); // true +header.accepts('image/jpeg'); // false + +header.getPreferred(['text/html', 'text/plain']); // 'text/html' // Iterate over media type/quality pairs for (let [mediaType, quality] of header) { @@ -211,10 +229,17 @@ let header = new Accept(['text/html', ['text/*', 0.9]]); ```ts let header = new AcceptLanguage('en-US,en;q=0.9'); -header.get('en-US'); // 1 -header.set('en-US', 0.8); -header.delete('en-US'); -header.has('en'); // true + +header.has('en-US'); // true +header.has('en-GB'); // false + +header.accepts('en-US'); // true +header.accepts('en-GB'); // true +header.accepts('en'); // true +header.accepts('fr'); // true + +header.getPreferred(['en-US', 'en-GB']); // 'en-US' +header.getPreferred(['en', 'fr']); // 'en' // Iterate over language/quality pairs for (let [language, quality] of header) { diff --git a/packages/headers/src/lib/accept-language.test.ts b/packages/headers/src/lib/accept-language.test.ts index 0a0b9788cd9..430f00168af 100644 --- a/packages/headers/src/lib/accept-language.test.ts +++ b/packages/headers/src/lib/accept-language.test.ts @@ -11,32 +11,64 @@ describe('Accept-Language', () => { it('initializes with a string', () => { let header = new AcceptLanguage('en-US,en;q=0.9'); - assert.equal(header.get('en-US'), 1); - assert.equal(header.get('en'), 0.9); + assert.equal(header.size, 2); }); it('initializes with an array', () => { let header = new AcceptLanguage(['en-US', ['en', 0.9]]); - assert.equal(header.get('en-US'), 1); - assert.equal(header.get('en'), 0.9); + assert.equal(header.size, 2); }); it('initializes with an object', () => { let header = new AcceptLanguage({ 'en-US': 1, en: 0.9 }); - assert.equal(header.get('en-US'), 1); - assert.equal(header.get('en'), 0.9); + assert.equal(header.size, 2); }); it('initializes with another AcceptLanguage', () => { let header = new AcceptLanguage(new AcceptLanguage('en-US,en;q=0.9')); - assert.equal(header.get('en-US'), 1); - assert.equal(header.get('en'), 0.9); + assert.equal(header.size, 2); }); it('handles whitespace in initial value', () => { let header = new AcceptLanguage(' en-US , en;q= 0.9 '); - assert.equal(header.get('en-US'), 1); - assert.equal(header.get('en'), 0.9); + assert.equal(header.size, 2); + }); + + it('gets all languages', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + assert.deepEqual(header.languages, ['en-us', 'en']); + }); + + it('gets all qualities', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + assert.deepEqual(header.qualities, [1, 0.9]); + }); + + it('checks if a language is acceptable', () => { + let header = new AcceptLanguage('en-US,en;q=0.9,fr;q=0.8'); + assert.equal(header.accepts('en-US'), true); + assert.equal(header.accepts('en'), true); + assert.equal(header.accepts('en-GB'), true); + assert.equal(header.accepts('fr'), true); + assert.equal(header.accepts('fi'), false); + }); + + it('gets the correct quality values', () => { + let header = new AcceptLanguage('en-US,en;q=0.9,fr;q=0.8'); + assert.equal(header.getQuality('en-US'), 1); + assert.equal(header.getQuality('*'), 1); + assert.equal(header.getQuality('en'), 1); + assert.equal(header.getQuality('en-GB'), 0.9); + assert.equal(header.getQuality('fr'), 0.8); + assert.equal(header.getQuality('fi'), 0); + }); + + it('gets the preferred language', () => { + let header = new AcceptLanguage('en-US,en;q=0.9'); + assert.equal(header.getPreferred(['en-GB', 'en-US']), 'en-US'); + assert.equal(header.getPreferred(['en-GB', 'en']), 'en'); + assert.equal(header.getPreferred(['fr', 'en-GB']), 'en-GB'); + assert.equal(header.getPreferred(['fi', 'ja']), null); }); it('sets and gets languages', () => { @@ -46,16 +78,10 @@ describe('Accept-Language', () => { }); it('deletes languages', () => { - let header = new AcceptLanguage('en-US'); - assert.equal(header.delete('en-US'), true); - assert.equal(header.delete('en'), false); - assert.equal(header.get('en-US'), undefined); - }); - - it('checks if language exists', () => { let header = new AcceptLanguage('en-US'); assert.equal(header.has('en-US'), true); - assert.equal(header.has('fs'), false); + header.delete('en-US'); + assert.equal(header.has('en-US'), false); }); it('clears all languages', () => { @@ -64,21 +90,11 @@ describe('Accept-Language', () => { assert.equal(header.size, 0); }); - it('gets all languages', () => { - let header = new AcceptLanguage('en-US,en;q=0.9'); - assert.deepEqual(header.languages, ['en-US', 'en']); - }); - - it('gets all qualities', () => { - let header = new AcceptLanguage('en-US,en;q=0.9'); - assert.deepEqual(header.qualities, [1, 0.9]); - }); - it('iterates over entries', () => { let header = new AcceptLanguage('en-US,en;q=0.9'); let entries = Array.from(header.entries()); assert.deepEqual(entries, [ - ['en-US', 1], + ['en-us', 1], ['en', 0.9], ]); }); @@ -87,7 +103,7 @@ describe('Accept-Language', () => { let header = new AcceptLanguage('en-US,en;q=0.9'); let entries = Array.from(header); assert.deepEqual(entries, [ - ['en-US', 1], + ['en-us', 1], ['en', 0.9], ]); }); @@ -99,7 +115,7 @@ describe('Accept-Language', () => { result.push([language, quality]); }); assert.deepEqual(result, [ - ['en-US', 1], + ['en-us', 1], ['en', 0.9], ]); }); @@ -111,7 +127,7 @@ describe('Accept-Language', () => { it('converts to string correctly', () => { let header = new AcceptLanguage('en-US,en;q=0.9'); - assert.equal(header.toString(), 'en-US,en;q=0.9'); + assert.equal(header.toString(), 'en-us,en;q=0.9'); }); it('handles setting empty quality values', () => { @@ -134,17 +150,17 @@ describe('Accept-Language', () => { it('sorts initial value', () => { let header = new AcceptLanguage('en;q=0.9,en-US'); - assert.equal(header.toString(), 'en-US,en;q=0.9'); - assert.deepEqual(header.languages, ['en-US', 'en']); + assert.equal(header.toString(), 'en-us,en;q=0.9'); + assert.deepEqual(header.languages, ['en-us', 'en']); }); it('sorts updated value', () => { let header = new AcceptLanguage('en-US,en;q=0.9'); header.set('fi'); - assert.equal(header.toString(), 'en-US,fi,en;q=0.9'); - assert.deepEqual(header.languages, ['en-US', 'fi', 'en']); + assert.equal(header.toString(), 'en-us,fi,en;q=0.9'); + assert.deepEqual(header.languages, ['en-us', 'fi', 'en']); header.set('en-US', 0.8); - assert.equal(header.toString(), 'fi,en;q=0.9,en-US;q=0.8'); - assert.deepEqual(header.languages, ['fi', 'en', 'en-US']); + assert.equal(header.toString(), 'fi,en;q=0.9,en-us;q=0.8'); + assert.deepEqual(header.languages, ['fi', 'en', 'en-us']); }); }); diff --git a/packages/headers/src/lib/accept-language.ts b/packages/headers/src/lib/accept-language.ts index 5256fc2bd5c..07c8cc1e9d4 100644 --- a/packages/headers/src/lib/accept-language.ts +++ b/packages/headers/src/lib/accept-language.ts @@ -34,20 +34,20 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { } } - this.#map.set(language, quality); + this.#map.set(language.toLowerCase(), quality); } } else if (isIterable(init)) { for (let language of init) { if (Array.isArray(language)) { - this.#map.set(language[0], language[1]); + this.#map.set(language[0].toLowerCase(), language[1]); } else { - this.#map.set(language, 1); + this.#map.set(language.toLowerCase(), 1); } } } else { for (let language in init) { if (Object.prototype.hasOwnProperty.call(init, language)) { - this.#map.set(language, init[language]); + this.#map.set(language.toLowerCase(), init[language]); } } } @@ -75,36 +75,90 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { } /** - * Gets the quality of a language with the given locale identifier from the `Accept-Language` header. + * Returns `true` if the header matches the given language (i.e. it is "acceptable"). + * @param language The locale identifier of the language to check. + * @returns `true` if the language is acceptable, `false` otherwise. */ - get(language: string): number | undefined { - return this.#map.get(language); + accepts(language: string): boolean { + return this.getQuality(language) > 0; } /** - * Sets a language with the given quality (defaults to 1) in the `Accept-Language` header. + * Gets the quality of a language with the given locale identifier. Performs wildcard and subtype + * matching, so `en` matches `en-US` and `en-GB`, and `*` matches all languages. + * @param language The locale identifier of the language to get. + * @returns The quality of the language, or `0` if it is not in the header. + */ + getQuality(language: string): number { + let [base, subtype] = language.toLowerCase().split('-'); + + for (let [key, value] of this) { + let [b, s] = key.split('-'); + if ( + (b === base || b === '*' || base === '*') && + (s === subtype || s === undefined || subtype === undefined) + ) { + return value; + } + } + + return 0; + } + + /** + * Returns the most preferred language from the given list of languages. + * @param languages The locale identifiers of the languages to choose from. + * @returns The most preferred language or `null` if none match. + */ + getPreferred(languages: string[]): string | null { + let sorted = languages + .map((language) => [language, this.getQuality(language)] as const) + .sort((a, b) => b[1] - a[1]); + + let first = sorted[0]; + + return first !== undefined && first[1] > 0 ? first[0] : null; + } + + /** + * Gets the quality of a language with the given locale identifier. If it is not in the header + * verbatim, this returns `null`. + * @param language The locale identifier of the language to get. + * @returns The quality of the language, or `null` if it is not in the header. + */ + get(language: string): number | null { + return this.#map.get(language.toLowerCase()) ?? null; + } + + /** + * Sets a language with the given quality. + * @param language The locale identifier of the language to set. + * @param quality The quality of the language. Defaults to 1. */ set(language: string, quality = 1): void { - this.#map.set(language, quality); + this.#map.set(language.toLowerCase(), quality); this.#sort(); } /** - * Removes a language with the given locale identifier from the `Accept-Language` header. + * Removes a language with the given locale identifier. + * @param language The locale identifier of the language to remove. */ - delete(language: string): boolean { - return this.#map.delete(language); + delete(language: string): void { + this.#map.delete(language.toLowerCase()); } /** - * True if a language with the given locale identifier in the `Accept-Language` header. + * Checks if the header contains a language with the given locale identifier. + * @param language The locale identifier of the language to check. + * @returns `true` if the language is in the header, `false` otherwise. */ has(language: string): boolean { - return this.#map.has(language); + return this.#map.has(language.toLowerCase()); } /** - * Removes all languages from the `Accept-Language` header. + * Removes all languages from the header. */ clear(): void { this.#map.clear(); diff --git a/packages/headers/src/lib/accept.test.ts b/packages/headers/src/lib/accept.test.ts index c9d2d69a45e..d0963469368 100644 --- a/packages/headers/src/lib/accept.test.ts +++ b/packages/headers/src/lib/accept.test.ts @@ -11,32 +11,63 @@ describe('Accept', () => { it('initializes with a string', () => { let header = new Accept('text/html,application/json;q=0.9'); - assert.equal(header.get('text/html'), 1); - assert.equal(header.get('application/json'), 0.9); + assert.equal(header.size, 2); }); it('initializes with an array', () => { let header = new Accept(['text/html', ['application/json', 0.9]]); - assert.equal(header.get('text/html'), 1); - assert.equal(header.get('application/json'), 0.9); + assert.equal(header.size, 2); }); it('initializes with an object', () => { let header = new Accept({ 'text/html': 1, 'application/json': 0.9 }); - assert.equal(header.get('text/html'), 1); - assert.equal(header.get('application/json'), 0.9); + assert.equal(header.size, 2); }); it('initializes with another Accept', () => { let header = new Accept(new Accept('text/html,application/json;q=0.9')); - assert.equal(header.get('text/html'), 1); - assert.equal(header.get('application/json'), 0.9); + assert.equal(header.size, 2); }); it('handles whitespace in initial value', () => { let header = new Accept(' text/html , application/json;q= 0.9 '); - assert.equal(header.get('text/html'), 1); - assert.equal(header.get('application/json'), 0.9); + assert.equal(header.size, 2); + }); + + it('gets all media types', () => { + let header = new Accept('text/html,application/json;q=0.9'); + assert.deepEqual(header.mediaTypes, ['text/html', 'application/json']); + }); + + it('gets all qualities', () => { + let header = new Accept('text/html,application/json;q=0.9'); + assert.deepEqual(header.qualities, [1, 0.9]); + }); + + it('checks if a media type is acceptable', () => { + let header = new Accept('text/html,text/*;q=0.9,application/json;q=0.8'); + assert.equal(header.accepts('text/html'), true); + assert.equal(header.accepts('text/*'), true); + assert.equal(header.accepts('text/plain'), true); + assert.equal(header.accepts('application/json'), true); + assert.equal(header.accepts('image/jpeg'), false); + }); + + it('gets the correct quality values', () => { + let header = new Accept('text/html,text/*;q=0.9,application/json;q=0.8'); + assert.equal(header.getQuality('text/html'), 1); + assert.equal(header.getQuality('*/*'), 1); + assert.equal(header.getQuality('text/*'), 1); + assert.equal(header.getQuality('text/plain'), 0.9); + assert.equal(header.getQuality('application/json'), 0.8); + assert.equal(header.getQuality('image/jpeg'), 0); + }); + + it('gets the preferred media type', () => { + let header = new Accept('text/html,text/*;q=0.9,application/json;q=0.8'); + assert.equal(header.getPreferred(['text/html', 'application/json']), 'text/html'); + assert.equal(header.getPreferred(['text/plain', 'text/html']), 'text/html'); + assert.equal(header.getPreferred(['image/jpeg']), null); }); it('sets and gets media types', () => { @@ -46,16 +77,10 @@ describe('Accept', () => { }); it('deletes media types', () => { - let header = new Accept('text/html'); - assert.equal(header.delete('text/html'), true); - assert.equal(header.delete('application/json'), false); - assert.equal(header.get('text/html'), undefined); - }); - - it('checks if media type exists', () => { let header = new Accept('text/html'); assert.equal(header.has('text/html'), true); - assert.equal(header.has('application/json'), false); + header.delete('text/html'); + assert.equal(header.has('text/html'), false); }); it('clears all media types', () => { @@ -64,16 +89,6 @@ describe('Accept', () => { assert.equal(header.size, 0); }); - it('gets all media types', () => { - let header = new Accept('text/html,application/json;q=0.9'); - assert.deepEqual(header.mediaTypes, ['text/html', 'application/json']); - }); - - it('gets all qualities', () => { - let header = new Accept('text/html,application/json;q=0.9'); - assert.deepEqual(header.qualities, [1, 0.9]); - }); - it('iterates over entries', () => { let header = new Accept('text/html,application/json;q=0.9'); let entries = Array.from(header.entries()); diff --git a/packages/headers/src/lib/accept.ts b/packages/headers/src/lib/accept.ts index 02f3fc06767..58569e7e8c0 100644 --- a/packages/headers/src/lib/accept.ts +++ b/packages/headers/src/lib/accept.ts @@ -34,19 +34,19 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { } } - this.#map.set(mediaType, quality); + this.#map.set(mediaType.toLowerCase(), quality); } } else if (isIterable(init)) { for (let mediaType of init) { if (Array.isArray(mediaType)) { - this.#map.set(mediaType[0], mediaType[1]); + this.#map.set(mediaType[0].toLowerCase(), mediaType[1]); } else { - this.#map.set(mediaType, 1); + this.#map.set(mediaType.toLowerCase(), 1); } } } else { for (let mediaType of Object.getOwnPropertyNames(init)) { - this.#map.set(mediaType, init[mediaType]); + this.#map.set(mediaType.toLowerCase(), init[mediaType]); } } @@ -59,7 +59,7 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { } /** - * An array of media types in the `Accept` header. + * An array of all media types in the `Accept` header. */ get mediaTypes(): string[] { return Array.from(this.#map.keys()); @@ -73,36 +73,90 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { } /** - * Gets the quality of a given media type from the `Accept` header. + * Returns `true` if the header matches the given media type (i.e. it is "acceptable"). + * @param mediaType The media type to check. + * @returns `true` if the media type is acceptable, `false` otherwise. */ - get(mediaType: string): number | undefined { - return this.#map.get(mediaType); + accepts(mediaType: string): boolean { + return this.getQuality(mediaType) > 0; } /** - * Sets a media type with the given quality (defaults to 1) in the `Accept` header. + * Gets the quality of a given media type. Also supports wildcards, so e.g. `text/*` will match `text/html`. + * @param mediaType The media type to get the quality of. + * @returns The quality of the media type. + */ + getQuality(mediaType: string): number { + let [type, subtype] = mediaType.toLowerCase().split('/'); + + for (let [key, value] of this) { + let [t, s] = key.split('/'); + if ( + (t === type || t === '*' || type === '*') && + (s === subtype || s === '*' || subtype === '*') + ) { + return value; + } + } + + return 0; + } + + /** + * Returns the most preferred media type from the given list of media types. + * @param mediaTypes The list of media types to choose from. + * @returns The most preferred media type or `null` if none match. + */ + getPreferred(mediaTypes: string[]): string | null { + let sorted = mediaTypes + .map((mediaType) => [mediaType, this.getQuality(mediaType)] as const) + .sort((a, b) => { + return b[1] - a[1]; + }); + + let first = sorted[0]; + + return first !== undefined && first[1] > 0 ? first[0] : null; + } + + /** + * Returns the quality of a media type. If it is not in the header verbatim, this returns `null`. + * @param mediaType The media type to get the quality of. + * @returns The quality of the media type, or `null` if it is not in the header. + */ + get(mediaType: string): number | null { + return this.#map.get(mediaType.toLowerCase()) ?? null; + } + + /** + * Sets a media type with the given quality. + * @param mediaType The media type to set. + * @param quality The quality of the media type. Defaults to 1. */ set(mediaType: string, quality = 1): void { - this.#map.set(mediaType, quality); + this.#map.set(mediaType.toLowerCase(), quality); this.#sort(); } /** - * Removes a given mediaType from the `Accept` header. + * Removes a given mediaType. + * @param mediaType The media type to remove. */ - delete(mediaType: string): boolean { - return this.#map.delete(mediaType); + delete(mediaType: string): void { + this.#map.delete(mediaType.toLowerCase()); } /** - * True if a given media type is present in the `Accept` header. + * Checks if a media type is in the header. + * @param mediaType The media type to check. + * @returns `true` if the media type is in the header (verbatim), `false` otherwise. */ has(mediaType: string): boolean { - return this.#map.has(mediaType); + return this.#map.has(mediaType.toLowerCase()); } /** - * Removes all media types from the `Accept` header. + * Removes all media types from the header. */ clear(): void { this.#map.clear(); diff --git a/packages/headers/src/lib/super-headers.test.ts b/packages/headers/src/lib/super-headers.test.ts index 9e3d96761be..bfd9553b10c 100644 --- a/packages/headers/src/lib/super-headers.test.ts +++ b/packages/headers/src/lib/super-headers.test.ts @@ -164,7 +164,7 @@ describe('SuperHeaders', () => { it('handles the acceptLanguage property', () => { let headers = new SuperHeaders({ acceptLanguage: { 'en-US': 1, en: 0.9 } }); - assert.equal(headers.get('Accept-Language'), 'en-US,en;q=0.9'); + assert.equal(headers.get('Accept-Language'), 'en-us,en;q=0.9'); }); it('handles the age property', () => { @@ -288,12 +288,12 @@ describe('SuperHeaders', () => { headers.acceptLanguage = 'en-US,en;q=0.9'; assert.deepEqual(headers.acceptLanguage.size, 2); - assert.deepEqual(headers.acceptLanguage.languages, ['en-US', 'en']); + assert.deepEqual(headers.acceptLanguage.languages, ['en-us', 'en']); assert.deepEqual(headers.acceptLanguage.qualities, [1, 0.9]); headers.acceptLanguage = { en: 1, 'en-US': 0.8 }; assert.deepEqual(headers.acceptLanguage.size, 2); - assert.deepEqual(headers.acceptLanguage.languages, ['en', 'en-US']); + assert.deepEqual(headers.acceptLanguage.languages, ['en', 'en-us']); assert.deepEqual(headers.acceptLanguage.qualities, [1, 0.8]); headers.acceptLanguage = null; From 3304dca5a9a2a7630deca5e6207bc1d5b81239a3 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 19 Dec 2024 23:22:46 -0800 Subject: [PATCH 548/730] Add Accept-Encoding support --- packages/headers/CHANGELOG.md | 20 +- packages/headers/README.md | 42 +++- packages/headers/src/headers.ts | 1 + .../headers/src/lib/accept-encoding.test.ts | 151 ++++++++++++++ packages/headers/src/lib/accept-encoding.ts | 192 ++++++++++++++++++ .../headers/src/lib/accept-language.test.ts | 6 +- packages/headers/src/lib/accept-language.ts | 20 +- packages/headers/src/lib/accept.ts | 2 +- .../headers/src/lib/super-headers.test.ts | 26 +++ packages/headers/src/lib/super-headers.ts | 21 ++ 10 files changed, 460 insertions(+), 21 deletions(-) create mode 100644 packages/headers/src/lib/accept-encoding.test.ts create mode 100644 packages/headers/src/lib/accept-encoding.ts diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 3abe2a73c6a..3d1e6a6708a 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -109,9 +109,27 @@ header.getQuality('text/plain'); // 0.9 header.getPreferred(['text/html', 'text/plain']); // 'text/html' ``` -- Added property support (getters and setters) for +- Added `Accept-Encoding` support +```ts +import { AcceptEncoding } from '@mjackson/headers'; + +let header = new AcceptEncoding({ gzip: 1, deflate: 0.9 }); + +header.accepts('gzip'); // true +header.accepts('deflate'); // true +header.accepts('identity'); // true +header.accepts('br'); // false + +header.getQuality('gzip'); // 1 +header.getQuality('deflate'); // 0.9 + +header.getPreferred(['gzip', 'deflate']); // 'gzip' +``` + +- Added `SuperHeaders.prototype` (getters and setters) for: - `headers.accept` + - `headers.acceptEncoding` - `headers.connection` - `headers.host` - `headers.referer` diff --git a/packages/headers/README.md b/packages/headers/README.md index b4eb06e6537..d0419029ff4 100644 --- a/packages/headers/README.md +++ b/packages/headers/README.md @@ -25,7 +25,8 @@ import Headers from '@mjackson/headers'; let headers = new Headers(); // Accept -headers.accept = 'text/html,text/*;q=0.9'; +headers.accept = { 'text/html': 1, 'text/*': 0.9 }; +// or headers.accept = 'text/html,text/*;q=0.9'; console.log(headers.accept.mediaTypes); // [ 'text/html', 'text/*' ] console.log(Object.fromEntries(headers.accept.entries())); // { 'text/html': 1, 'text/*': 0.9 } @@ -41,8 +42,18 @@ headers.accept.set('text/*', 0.8); console.log(headers.get('Accept')); // "text/html,text/plain;q=0.9,text/*;q=0.8" +// Accept-Encoding +headers.acceptEncoding = { gzip: 1, deflate: 0.8 }; +// or headers.acceptEncoding = 'gzip, deflate;q=0.8'; + +headers.acceptEncoding.accepts('gzip'); // true +headers.acceptEncoding.accepts('br'); // false + +headers.acceptEncoding.getPreferred(['gzip', 'deflate']); // 'gzip' + // Accept-Language -headers.acceptLanguage = 'en-US,en;q=0.9'; +headers.acceptLanguage = { 'en-US': 1, en: 0.9 }; +// or headers.acceptLanguage = 'en-US,en;q=0.9'; console.log(headers.acceptLanguage.languages); // [ 'en-us', 'en' ] console.log(Object.fromEntries(headers.acceptLanguage.entries())); // { 'en-us': 1, en: 0.9 } @@ -190,6 +201,7 @@ The following headers are currently supported: - [Overview](#overview) - [Low-level API](#low-level-api) - [Accept](#accept) + - [Accept-Encoding](#accept-encoding) - [Accept-Language](#accept-language) - [Cache-Control](#cache-control) - [Content-Disposition](#content-disposition) @@ -215,7 +227,6 @@ header.accepts('image/jpeg'); // false header.getPreferred(['text/html', 'text/plain']); // 'text/html' -// Iterate over media type/quality pairs for (let [mediaType, quality] of header) { // ... } @@ -225,6 +236,30 @@ let header = new Accept({ 'text/html': 1, 'text/*': 0.9 }); let header = new Accept(['text/html', ['text/*', 0.9]]); ``` +### Accept-Encoding + +```ts +let header = new AcceptEncoding('gzip,deflate;q=0.9'); + +header.has('gzip'); // true +header.has('br'); // false + +header.accepts('gzip'); // true +header.accepts('deflate'); // true +header.accepts('identity'); // true +header.accepts('br'); // true + +header.getPreferred(['gzip', 'deflate']); // 'gzip' + +for (let [encoding, weight] of header) { + // ... +} + +// Alternative init styles +let header = new AcceptEncoding({ gzip: 1, deflate: 0.9 }); +let header = new AcceptEncoding(['gzip', ['deflate', 0.9]]); +``` + ### Accept-Language ```ts @@ -241,7 +276,6 @@ header.accepts('fr'); // true header.getPreferred(['en-US', 'en-GB']); // 'en-US' header.getPreferred(['en', 'fr']); // 'en' -// Iterate over language/quality pairs for (let [language, quality] of header) { // ... } diff --git a/packages/headers/src/headers.ts b/packages/headers/src/headers.ts index baa4bdd0ea1..fb98f848e11 100644 --- a/packages/headers/src/headers.ts +++ b/packages/headers/src/headers.ts @@ -1,4 +1,5 @@ export { type AcceptInit, Accept } from './lib/accept.ts'; +export { type AcceptEncodingInit, AcceptEncoding } from './lib/accept-encoding.ts'; export { type AcceptLanguageInit, AcceptLanguage } from './lib/accept-language.ts'; export { type CacheControlInit, CacheControl } from './lib/cache-control.ts'; export { type ContentDispositionInit, ContentDisposition } from './lib/content-disposition.ts'; diff --git a/packages/headers/src/lib/accept-encoding.test.ts b/packages/headers/src/lib/accept-encoding.test.ts new file mode 100644 index 00000000000..970b12200b9 --- /dev/null +++ b/packages/headers/src/lib/accept-encoding.test.ts @@ -0,0 +1,151 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { AcceptEncoding } from './accept-encoding.ts'; + +describe('Accept-Encoding', () => { + it('initializes with an empty string', () => { + let header = new AcceptEncoding(''); + assert.equal(header.size, 0); + }); + + it('initializes with a string', () => { + let header = new AcceptEncoding('gzip, deflate;q=0.9'); + assert.equal(header.size, 2); + }); + + it('initializes with an array', () => { + let header = new AcceptEncoding(['gzip', ['deflate', 0.9]]); + assert.equal(header.size, 2); + }); + + it('initializes with an object', () => { + let header = new AcceptEncoding({ gzip: 1, deflate: 0.9 }); + assert.equal(header.size, 2); + }); + + it('initializes with another AcceptEncoding', () => { + let header = new AcceptEncoding(new AcceptEncoding('gzip, deflate;q=0.9')); + assert.equal(header.size, 2); + }); + + it('handles whitespace in initial value', () => { + let header = new AcceptEncoding(' gzip , deflate;q= 0.9 '); + assert.equal(header.size, 2); + }); + + it('gets all encodings', () => { + let header = new AcceptEncoding('gzip, deflate;q=0.9'); + assert.deepEqual(header.encodings, ['gzip', 'deflate']); + }); + + it('gets all weights', () => { + let header = new AcceptEncoding('gzip, deflate;q=0.9'); + assert.deepEqual(header.weights, [1, 0.9]); + }); + + it('checks if an encoding is acceptable', () => { + let header = new AcceptEncoding('gzip, deflate;q=0.9,br;q=0.8'); + assert.equal(header.accepts('gzip'), true); + assert.equal(header.accepts('deflate'), true); + assert.equal(header.accepts('br'), true); + assert.equal(header.accepts('compress'), false); + assert.equal(header.accepts('identity'), true); // special case + }); + + it('gets the correct weights', () => { + let header = new AcceptEncoding('gzip, deflate;q=0.9,*;q=0.8'); + assert.equal(header.getWeight('gzip'), 1); + assert.equal(header.getWeight('deflate'), 0.9); + assert.equal(header.getWeight('br'), 0.8); + }); + + it('gets the preferred encoding', () => { + let header = new AcceptEncoding('gzip, deflate;q=0.9,*;q=0.8'); + assert.equal(header.getPreferred(['gzip', 'deflate']), 'gzip'); + assert.equal(header.getPreferred(['deflate', 'br']), 'deflate'); + }); + + it('sets and gets encodings', () => { + let header = new AcceptEncoding(); + header.set('gzip', 1); + assert.equal(header.get('gzip'), 1); + }); + + it('deletes encodings', () => { + let header = new AcceptEncoding('gzip, deflate;q=0.9'); + assert.equal(header.has('gzip'), true); + header.delete('gzip'); + assert.equal(header.has('gzip'), false); + }); + + it('clears all encodings', () => { + let header = new AcceptEncoding('gzip, deflate;q=0.9'); + assert.equal(header.size, 2); + header.clear(); + assert.equal(header.size, 0); + }); + + it('iterates over entries', () => { + let header = new AcceptEncoding('gzip, deflate;q=0.9'); + assert.deepEqual(Array.from(header.entries()), [ + ['gzip', 1], + ['deflate', 0.9], + ]); + }); + + it('is directly iterable', () => { + let header = new AcceptEncoding('gzip, deflate;q=0.9'); + assert.deepEqual(Array.from(header), [ + ['gzip', 1], + ['deflate', 0.9], + ]); + }); + + it('uses forEach correctly', () => { + let header = new AcceptEncoding('gzip, deflate;q=0.9'); + let result: [string, number][] = []; + header.forEach((encoding, weight) => { + result.push([encoding, weight]); + }); + assert.deepEqual(result, [ + ['gzip', 1], + ['deflate', 0.9], + ]); + }); + + it('returns correct size', () => { + let header = new AcceptEncoding('gzip, deflate;q=0.9'); + assert.equal(header.size, 2); + }); + + it('converts to a string', () => { + let header = new AcceptEncoding('gzip, deflate;q=0.9'); + assert.equal(header.toString(), 'gzip,deflate;q=0.9'); + }); + + it('handles setting empty weights', () => { + let header = new AcceptEncoding(); + header.set('deflate'); + assert.equal(header.get('deflate'), 1); + }); + + it('handles setting wildcard value', () => { + let header = new AcceptEncoding(); + header.set('*', 0.8); + assert.equal(header.get('*'), 0.8); + }); + + it('sorts initial value', () => { + let header = new AcceptEncoding('deflate;q=0.9,gzip'); + assert.equal(header.toString(), 'gzip,deflate;q=0.9'); + }); + + it('sorts updated value', () => { + let header = new AcceptEncoding('gzip;q=0.8,deflate'); + header.set('br'); + assert.equal(header.toString(), 'deflate,br,gzip;q=0.8'); + header.set('deflate', 0.9); + assert.equal(header.toString(), 'br,deflate;q=0.9,gzip;q=0.8'); + }); +}); diff --git a/packages/headers/src/lib/accept-encoding.ts b/packages/headers/src/lib/accept-encoding.ts new file mode 100644 index 00000000000..715c06a1001 --- /dev/null +++ b/packages/headers/src/lib/accept-encoding.ts @@ -0,0 +1,192 @@ +import { type HeaderValue } from './header-value.ts'; +import { parseParams } from './param-values.ts'; +import { isIterable } from './utils.ts'; + +export type AcceptEncodingInit = Iterable<string | [string, number]> | Record<string, number>; + +/** + * The value of a `Accept-Encoding` HTTP header. + * + * [MDN `Accept-Encoding` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.4) + */ +export class AcceptEncoding implements HeaderValue, Iterable<[string, number]> { + #map: Map<string, number>; + + constructor(init?: string | AcceptEncodingInit) { + this.#map = new Map(); + + if (init) { + if (typeof init === 'string') { + for (let piece of init.split(/\s*,\s*/)) { + let params = parseParams(piece); + if (params.length < 1) continue; + + let encoding = params[0][0]; + let weight = 1; + + for (let i = 1; i < params.length; i++) { + let [key, value] = params[i]; + if (key === 'q') { + weight = Number(value); + break; + } + } + + this.#map.set(encoding.toLowerCase(), weight); + } + } else if (isIterable(init)) { + for (let value of init) { + if (Array.isArray(value)) { + this.#map.set(value[0].toLowerCase(), value[1]); + } else { + this.#map.set(value.toLowerCase(), 1); + } + } + } else { + for (let encoding of Object.getOwnPropertyNames(init)) { + this.#map.set(encoding.toLowerCase(), init[encoding]); + } + } + + this.#sort(); + } + } + + #sort() { + this.#map = new Map([...this.#map].sort(([, a], [, b]) => b - a)); + } + + /** + * An array of all encodings in the header. + */ + get encodings(): string[] { + return Array.from(this.#map.keys()); + } + + /** + * An array of all weights (q values) in the header. + */ + get weights(): number[] { + return Array.from(this.#map.values()); + } + + /** + * Returns `true` if the header matches the given encoding (i.e. it is "acceptable"). + * @param encoding The encoding to check. + * @returns `true` if the encoding is acceptable, `false` otherwise. + */ + accepts(encoding: string): boolean { + return encoding.toLowerCase() === 'identity' || this.getWeight(encoding) > 0; + } + + /** + * Gets the weight an encoding. Performs wildcard matching so `*` matches all encodings. + * @param encoding The encoding to get. + * @returns The weight of the encoding, or `0` if it is not in the header. + */ + getWeight(encoding: string): number { + let lower = encoding.toLowerCase(); + + for (let [enc, weight] of this) { + if (enc === lower || enc === '*' || lower === '*') { + return weight; + } + } + + return 0; + } + + /** + * Returns the most preferred encoding from the given list of encodings. + * @param encodings The encodings to choose from. + * @returns The most preferred encoding or `null` if none match. + */ + getPreferred(encodings: string[]): string | null { + let sorted = encodings + .map((encoding) => [encoding, this.getWeight(encoding)] as const) + .sort((a, b) => b[1] - a[1]); + + let first = sorted[0]; + + return first !== undefined && first[1] > 0 ? first[0] : null; + } + + /** + * Gets the weight of an encoding. If it is not in the header verbatim, this returns `null`. + * @param encoding The encoding to get. + * @returns The weight of the encoding, or `null` if it is not in the header. + */ + get(encoding: string): number | null { + return this.#map.get(encoding.toLowerCase()) ?? null; + } + + /** + * Sets an encoding with the given weight. + * @param encoding The encoding to set. + * @param weight The weight of the encoding. Defaults to 1. + */ + set(encoding: string, weight = 1): void { + this.#map.set(encoding.toLowerCase(), weight); + this.#sort(); + } + + /** + * Removes the given encoding from the header. + * @param encoding The encoding to remove. + */ + delete(encoding: string): void { + this.#map.delete(encoding.toLowerCase()); + } + + /** + * Checks if the header contains a given encoding. + * @param encoding The encoding to check. + * @returns `true` if the encoding is in the header, `false` otherwise. + */ + has(encoding: string): boolean { + return this.#map.has(encoding.toLowerCase()); + } + + /** + * Removes all encodings from the header. + */ + clear(): void { + this.#map.clear(); + } + + entries(): IterableIterator<[string, number]> { + return this.#map.entries(); + } + + [Symbol.iterator](): IterableIterator<[string, number]> { + return this.entries(); + } + + forEach( + callback: (encoding: string, weight: number, header: AcceptEncoding) => void, + thisArg?: any, + ): void { + for (let [encoding, weight] of this) { + callback.call(thisArg, encoding, weight, this); + } + } + + /** + * The number of encodings in the header. + */ + get size(): number { + return this.#map.size; + } + + toString(): string { + let pairs: string[] = []; + + for (let [encoding, weight] of this.#map) { + pairs.push(`${encoding}${weight === 1 ? '' : `;q=${weight}`}`); + } + + return pairs.join(','); + } +} diff --git a/packages/headers/src/lib/accept-language.test.ts b/packages/headers/src/lib/accept-language.test.ts index 430f00168af..fd212d96b7c 100644 --- a/packages/headers/src/lib/accept-language.test.ts +++ b/packages/headers/src/lib/accept-language.test.ts @@ -86,6 +86,7 @@ describe('Accept-Language', () => { it('clears all languages', () => { let header = new AcceptLanguage('en-US,en;q=0.9'); + assert.equal(header.size, 2); header.clear(); assert.equal(header.size, 0); }); @@ -125,7 +126,7 @@ describe('Accept-Language', () => { assert.equal(header.size, 2); }); - it('converts to string correctly', () => { + it('converts to string', () => { let header = new AcceptLanguage('en-US,en;q=0.9'); assert.equal(header.toString(), 'en-us,en;q=0.9'); }); @@ -151,16 +152,13 @@ describe('Accept-Language', () => { it('sorts initial value', () => { let header = new AcceptLanguage('en;q=0.9,en-US'); assert.equal(header.toString(), 'en-us,en;q=0.9'); - assert.deepEqual(header.languages, ['en-us', 'en']); }); it('sorts updated value', () => { let header = new AcceptLanguage('en-US,en;q=0.9'); header.set('fi'); assert.equal(header.toString(), 'en-us,fi,en;q=0.9'); - assert.deepEqual(header.languages, ['en-us', 'fi', 'en']); header.set('en-US', 0.8); assert.equal(header.toString(), 'fi,en;q=0.9,en-us;q=0.8'); - assert.deepEqual(header.languages, ['fi', 'en', 'en-us']); }); }); diff --git a/packages/headers/src/lib/accept-language.ts b/packages/headers/src/lib/accept-language.ts index 07c8cc1e9d4..f0f8f70f8ec 100644 --- a/packages/headers/src/lib/accept-language.ts +++ b/packages/headers/src/lib/accept-language.ts @@ -37,18 +37,16 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { this.#map.set(language.toLowerCase(), quality); } } else if (isIterable(init)) { - for (let language of init) { - if (Array.isArray(language)) { - this.#map.set(language[0].toLowerCase(), language[1]); + for (let value of init) { + if (Array.isArray(value)) { + this.#map.set(value[0].toLowerCase(), value[1]); } else { - this.#map.set(language.toLowerCase(), 1); + this.#map.set(value.toLowerCase(), 1); } } } else { - for (let language in init) { - if (Object.prototype.hasOwnProperty.call(init, language)) { - this.#map.set(language.toLowerCase(), init[language]); - } + for (let language of Object.getOwnPropertyNames(init)) { + this.#map.set(language.toLowerCase(), init[language]); } } @@ -61,14 +59,14 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { } /** - * An array of all locale identifiers in the `Accept-Language` header. + * An array of all locale identifiers in the header. */ get languages(): string[] { return Array.from(this.#map.keys()); } /** - * An array of all quality values in the `Accept-Language` header. + * An array of all quality values in the header. */ get qualities(): number[] { return Array.from(this.#map.values()); @@ -182,7 +180,7 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { } /** - * The number of languages in the `Accept-Language` header. + * The number of languages in the header. */ get size(): number { return this.#map.size; diff --git a/packages/headers/src/lib/accept.ts b/packages/headers/src/lib/accept.ts index 58569e7e8c0..954f241972a 100644 --- a/packages/headers/src/lib/accept.ts +++ b/packages/headers/src/lib/accept.ts @@ -139,7 +139,7 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { } /** - * Removes a given mediaType. + * Removes the given media type from the header. * @param mediaType The media type to remove. */ delete(mediaType: string): void { diff --git a/packages/headers/src/lib/super-headers.test.ts b/packages/headers/src/lib/super-headers.test.ts index bfd9553b10c..5952da27ab5 100644 --- a/packages/headers/src/lib/super-headers.test.ts +++ b/packages/headers/src/lib/super-headers.test.ts @@ -2,6 +2,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; import { Accept } from './accept.ts'; +import { AcceptEncoding } from './accept-encoding.ts'; import { AcceptLanguage } from './accept-language.ts'; import { CacheControl } from './cache-control.ts'; import { ContentDisposition } from './content-disposition.ts'; @@ -162,6 +163,11 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Accept'), 'text/html,application/json;q=0.9'); }); + it('handles the acceptEncoding property', () => { + let headers = new SuperHeaders({ acceptEncoding: { gzip: 1, deflate: 0.8 } }); + assert.equal(headers.get('Accept-Encoding'), 'gzip,deflate;q=0.8'); + }); + it('handles the acceptLanguage property', () => { let headers = new SuperHeaders({ acceptLanguage: { 'en-US': 1, en: 0.9 } }); assert.equal(headers.get('Accept-Language'), 'en-us,en;q=0.9'); @@ -281,6 +287,26 @@ describe('SuperHeaders', () => { assert.equal(headers.accept.toString(), ''); }); + it('supports the acceptEncoding property', () => { + let headers = new SuperHeaders(); + + assert.ok(headers.acceptEncoding instanceof AcceptEncoding); + + headers.acceptEncoding = 'gzip, deflate'; + assert.deepEqual(headers.acceptEncoding.size, 2); + assert.deepEqual(headers.acceptEncoding.encodings, ['gzip', 'deflate']); + assert.deepEqual(headers.acceptEncoding.weights, [1, 1]); + + headers.acceptEncoding = { gzip: 1, deflate: 0.8 }; + assert.deepEqual(headers.acceptEncoding.size, 2); + assert.deepEqual(headers.acceptEncoding.encodings, ['gzip', 'deflate']); + assert.deepEqual(headers.acceptEncoding.weights, [1, 0.8]); + + headers.acceptEncoding = null; + assert.ok(headers.acceptEncoding instanceof AcceptEncoding); + assert.equal(headers.acceptEncoding.toString(), ''); + }); + it('supports the acceptLanguage property', () => { let headers = new SuperHeaders(); diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index 16c51bace0b..01a5a060f3d 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -1,4 +1,5 @@ import { type AcceptInit, Accept } from './accept.ts'; +import { type AcceptEncodingInit, AcceptEncoding } from './accept-encoding.ts'; import { type AcceptLanguageInit, AcceptLanguage } from './accept-language.ts'; import { type CacheControlInit, CacheControl } from './cache-control.ts'; import { type ContentDispositionInit, ContentDisposition } from './content-disposition.ts'; @@ -19,6 +20,10 @@ interface SuperHeadersPropertyInit { * The [`Accept`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) header value. */ accept?: string | AcceptInit; + /** + * The [`Accept-Encoding`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header value. + */ + acceptEncoding?: string | AcceptEncodingInit; /** * The [`Accept-Language`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) header value. */ @@ -309,6 +314,22 @@ export class SuperHeaders extends Headers { this.#setHeaderValue('accept', Accept, value); } + /** + * The `Accept-Encoding` header contains information about the content encodings that the client + * is willing to accept in the response. + * + * [MDN `Accept-Encoding` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.4) + */ + get acceptEncoding(): AcceptEncoding { + return this.#getHeaderValue('accept-encoding', AcceptEncoding); + } + + set acceptEncoding(value: string | AcceptEncodingInit | undefined | null) { + this.#setHeaderValue('accept-encoding', AcceptEncoding, value); + } + /** * The `Accept-Language` header contains information about preferred natural language for the * response. From 8e3df415fe5f39d003f3028fd5bb5b5ba1c2d1d3 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 19 Dec 2024 23:31:22 -0800 Subject: [PATCH 549/730] s/quality/weight/g --- packages/headers/CHANGELOG.md | 14 +++--- .../headers/src/lib/accept-language.test.ts | 26 +++++----- packages/headers/src/lib/accept-language.ts | 42 ++++++++-------- packages/headers/src/lib/accept.test.ts | 26 +++++----- packages/headers/src/lib/accept.ts | 48 +++++++++---------- .../headers/src/lib/super-headers.test.ts | 8 ++-- 6 files changed, 82 insertions(+), 82 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 3d1e6a6708a..243dfbd26d5 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -72,7 +72,7 @@ let ms = new Date().getTime(); let headers = new SuperHeaders({ lastModified: ms }); ``` -- Added `AcceptLanguage.prototype.accepts(language)`, `AcceptLanguage.prototype.getQuality(language)`, +- Added `AcceptLanguage.prototype.accepts(language)`, `AcceptLanguage.prototype.getWeight(language)`, `AcceptLanguage.prototype.getPreferred(languages)` ```ts @@ -85,8 +85,8 @@ header.accepts('en-GB'); // true header.accepts('en'); // true header.accepts('fr'); // false -header.getQuality('en-US'); // 1 -header.getQuality('en-GB'); // 0.9 +header.getWeight('en-US'); // 1 +header.getWeight('en-GB'); // 0.9 header.getPreferred(['en-GB', 'en-US']); // 'en-US' ``` @@ -103,8 +103,8 @@ header.accepts('text/plain'); // true header.accepts('text/*'); // true header.accepts('image/jpeg'); // false -header.getQuality('text/html'); // 1 -header.getQuality('text/plain'); // 0.9 +header.getWeight('text/html'); // 1 +header.getWeight('text/plain'); // 0.9 header.getPreferred(['text/html', 'text/plain']); // 'text/html' ``` @@ -121,8 +121,8 @@ header.accepts('deflate'); // true header.accepts('identity'); // true header.accepts('br'); // false -header.getQuality('gzip'); // 1 -header.getQuality('deflate'); // 0.9 +header.getWeight('gzip'); // 1 +header.getWeight('deflate'); // 0.9 header.getPreferred(['gzip', 'deflate']); // 'gzip' ``` diff --git a/packages/headers/src/lib/accept-language.test.ts b/packages/headers/src/lib/accept-language.test.ts index fd212d96b7c..a61cbd56d3e 100644 --- a/packages/headers/src/lib/accept-language.test.ts +++ b/packages/headers/src/lib/accept-language.test.ts @@ -39,9 +39,9 @@ describe('Accept-Language', () => { assert.deepEqual(header.languages, ['en-us', 'en']); }); - it('gets all qualities', () => { + it('gets all weights', () => { let header = new AcceptLanguage('en-US,en;q=0.9'); - assert.deepEqual(header.qualities, [1, 0.9]); + assert.deepEqual(header.weights, [1, 0.9]); }); it('checks if a language is acceptable', () => { @@ -53,14 +53,14 @@ describe('Accept-Language', () => { assert.equal(header.accepts('fi'), false); }); - it('gets the correct quality values', () => { + it('gets the correct weight values', () => { let header = new AcceptLanguage('en-US,en;q=0.9,fr;q=0.8'); - assert.equal(header.getQuality('en-US'), 1); - assert.equal(header.getQuality('*'), 1); - assert.equal(header.getQuality('en'), 1); - assert.equal(header.getQuality('en-GB'), 0.9); - assert.equal(header.getQuality('fr'), 0.8); - assert.equal(header.getQuality('fi'), 0); + assert.equal(header.getWeight('en-US'), 1); + assert.equal(header.getWeight('*'), 1); + assert.equal(header.getWeight('en'), 1); + assert.equal(header.getWeight('en-GB'), 0.9); + assert.equal(header.getWeight('fr'), 0.8); + assert.equal(header.getWeight('fi'), 0); }); it('gets the preferred language', () => { @@ -112,8 +112,8 @@ describe('Accept-Language', () => { it('uses forEach correctly', () => { let header = new AcceptLanguage('en-US,en;q=0.9'); let result: [string, number][] = []; - header.forEach((language, quality) => { - result.push([language, quality]); + header.forEach((language, weight) => { + result.push([language, weight]); }); assert.deepEqual(result, [ ['en-us', 1], @@ -131,13 +131,13 @@ describe('Accept-Language', () => { assert.equal(header.toString(), 'en-us,en;q=0.9'); }); - it('handles setting empty quality values', () => { + it('handles setting empty weight values', () => { let header = new AcceptLanguage(); header.set('en-US'); assert.equal(header.get('en-US'), 1); }); - it('overwrites existing quality values', () => { + it('overwrites existing weight values', () => { let header = new AcceptLanguage('en;q=0.9'); header.set('en', 1); assert.equal(header.get('en'), 1); diff --git a/packages/headers/src/lib/accept-language.ts b/packages/headers/src/lib/accept-language.ts index f0f8f70f8ec..63b1804fcb5 100644 --- a/packages/headers/src/lib/accept-language.ts +++ b/packages/headers/src/lib/accept-language.ts @@ -24,17 +24,17 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { if (params.length < 1) continue; let language = params[0][0]; - let quality = 1; + let weight = 1; for (let i = 1; i < params.length; i++) { let [key, value] = params[i]; if (key === 'q') { - quality = Number(value); + weight = Number(value); break; } } - this.#map.set(language.toLowerCase(), quality); + this.#map.set(language.toLowerCase(), weight); } } else if (isIterable(init)) { for (let value of init) { @@ -66,9 +66,9 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { } /** - * An array of all quality values in the header. + * An array of all weight values in the header. */ - get qualities(): number[] { + get weights(): number[] { return Array.from(this.#map.values()); } @@ -78,16 +78,16 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { * @returns `true` if the language is acceptable, `false` otherwise. */ accepts(language: string): boolean { - return this.getQuality(language) > 0; + return this.getWeight(language) > 0; } /** - * Gets the quality of a language with the given locale identifier. Performs wildcard and subtype + * Gets the weight of a language with the given locale identifier. Performs wildcard and subtype * matching, so `en` matches `en-US` and `en-GB`, and `*` matches all languages. * @param language The locale identifier of the language to get. - * @returns The quality of the language, or `0` if it is not in the header. + * @returns The weight of the language, or `0` if it is not in the header. */ - getQuality(language: string): number { + getWeight(language: string): number { let [base, subtype] = language.toLowerCase().split('-'); for (let [key, value] of this) { @@ -110,7 +110,7 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { */ getPreferred(languages: string[]): string | null { let sorted = languages - .map((language) => [language, this.getQuality(language)] as const) + .map((language) => [language, this.getWeight(language)] as const) .sort((a, b) => b[1] - a[1]); let first = sorted[0]; @@ -119,22 +119,22 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { } /** - * Gets the quality of a language with the given locale identifier. If it is not in the header + * Gets the weight of a language with the given locale identifier. If it is not in the header * verbatim, this returns `null`. * @param language The locale identifier of the language to get. - * @returns The quality of the language, or `null` if it is not in the header. + * @returns The weight of the language, or `null` if it is not in the header. */ get(language: string): number | null { return this.#map.get(language.toLowerCase()) ?? null; } /** - * Sets a language with the given quality. + * Sets a language with the given weight. * @param language The locale identifier of the language to set. - * @param quality The quality of the language. Defaults to 1. + * @param weight The weight of the language. Defaults to 1. */ - set(language: string, quality = 1): void { - this.#map.set(language.toLowerCase(), quality); + set(language: string, weight = 1): void { + this.#map.set(language.toLowerCase(), weight); this.#sort(); } @@ -171,11 +171,11 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { } forEach( - callback: (language: string, quality: number, header: AcceptLanguage) => void, + callback: (language: string, weight: number, header: AcceptLanguage) => void, thisArg?: any, ): void { - for (let [language, quality] of this) { - callback.call(thisArg, language, quality, this); + for (let [language, weight] of this) { + callback.call(thisArg, language, weight, this); } } @@ -189,8 +189,8 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { toString(): string { let pairs: string[] = []; - for (let [language, quality] of this.#map) { - pairs.push(`${language}${quality === 1 ? '' : `;q=${quality}`}`); + for (let [language, weight] of this.#map) { + pairs.push(`${language}${weight === 1 ? '' : `;q=${weight}`}`); } return pairs.join(','); diff --git a/packages/headers/src/lib/accept.test.ts b/packages/headers/src/lib/accept.test.ts index d0963469368..935ca28b3bf 100644 --- a/packages/headers/src/lib/accept.test.ts +++ b/packages/headers/src/lib/accept.test.ts @@ -39,9 +39,9 @@ describe('Accept', () => { assert.deepEqual(header.mediaTypes, ['text/html', 'application/json']); }); - it('gets all qualities', () => { + it('gets all weights', () => { let header = new Accept('text/html,application/json;q=0.9'); - assert.deepEqual(header.qualities, [1, 0.9]); + assert.deepEqual(header.weights, [1, 0.9]); }); it('checks if a media type is acceptable', () => { @@ -53,14 +53,14 @@ describe('Accept', () => { assert.equal(header.accepts('image/jpeg'), false); }); - it('gets the correct quality values', () => { + it('gets the correct weight values', () => { let header = new Accept('text/html,text/*;q=0.9,application/json;q=0.8'); - assert.equal(header.getQuality('text/html'), 1); - assert.equal(header.getQuality('*/*'), 1); - assert.equal(header.getQuality('text/*'), 1); - assert.equal(header.getQuality('text/plain'), 0.9); - assert.equal(header.getQuality('application/json'), 0.8); - assert.equal(header.getQuality('image/jpeg'), 0); + assert.equal(header.getWeight('text/html'), 1); + assert.equal(header.getWeight('*/*'), 1); + assert.equal(header.getWeight('text/*'), 1); + assert.equal(header.getWeight('text/plain'), 0.9); + assert.equal(header.getWeight('application/json'), 0.8); + assert.equal(header.getWeight('image/jpeg'), 0); }); it('gets the preferred media type', () => { @@ -110,8 +110,8 @@ describe('Accept', () => { it('uses forEach correctly', () => { let header = new Accept('text/html,application/json;q=0.9'); let result: [string, number][] = []; - header.forEach((mediaType, quality) => { - result.push([mediaType, quality]); + header.forEach((mediaType, weight) => { + result.push([mediaType, weight]); }); assert.deepEqual(result, [ ['text/html', 1], @@ -129,13 +129,13 @@ describe('Accept', () => { assert.equal(header.toString(), 'text/html,application/json;q=0.9'); }); - it('handles setting empty quality values', () => { + it('handles setting empty weight values', () => { let header = new Accept(); header.set('text/html'); assert.equal(header.get('text/html'), 1); }); - it('overwrites existing quality values', () => { + it('overwrites existing weight values', () => { let header = new Accept('text/html,application/json;q=0.9'); header.set('application/json', 0.8); assert.equal(header.get('application/json'), 0.8); diff --git a/packages/headers/src/lib/accept.ts b/packages/headers/src/lib/accept.ts index 954f241972a..eb506101d9b 100644 --- a/packages/headers/src/lib/accept.ts +++ b/packages/headers/src/lib/accept.ts @@ -24,17 +24,17 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { if (params.length < 1) continue; let mediaType = params[0][0]; - let quality = 1; + let weight = 1; for (let i = 1; i < params.length; i++) { let [key, value] = params[i]; if (key === 'q') { - quality = Number(value); + weight = Number(value); break; } } - this.#map.set(mediaType.toLowerCase(), quality); + this.#map.set(mediaType.toLowerCase(), weight); } } else if (isIterable(init)) { for (let mediaType of init) { @@ -59,16 +59,16 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { } /** - * An array of all media types in the `Accept` header. + * An array of all media types in the header. */ get mediaTypes(): string[] { return Array.from(this.#map.keys()); } /** - * An array of quality values in the `Accept` header. + * An array of weight values in the header. */ - get qualities(): number[] { + get weights(): number[] { return Array.from(this.#map.values()); } @@ -78,15 +78,15 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { * @returns `true` if the media type is acceptable, `false` otherwise. */ accepts(mediaType: string): boolean { - return this.getQuality(mediaType) > 0; + return this.getWeight(mediaType) > 0; } /** - * Gets the quality of a given media type. Also supports wildcards, so e.g. `text/*` will match `text/html`. - * @param mediaType The media type to get the quality of. - * @returns The quality of the media type. + * Gets the weight of a given media type. Also supports wildcards, so e.g. `text/*` will match `text/html`. + * @param mediaType The media type to get the weight of. + * @returns The weight of the media type. */ - getQuality(mediaType: string): number { + getWeight(mediaType: string): number { let [type, subtype] = mediaType.toLowerCase().split('/'); for (let [key, value] of this) { @@ -109,7 +109,7 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { */ getPreferred(mediaTypes: string[]): string | null { let sorted = mediaTypes - .map((mediaType) => [mediaType, this.getQuality(mediaType)] as const) + .map((mediaType) => [mediaType, this.getWeight(mediaType)] as const) .sort((a, b) => { return b[1] - a[1]; }); @@ -120,21 +120,21 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { } /** - * Returns the quality of a media type. If it is not in the header verbatim, this returns `null`. - * @param mediaType The media type to get the quality of. - * @returns The quality of the media type, or `null` if it is not in the header. + * Returns the weight of a media type. If it is not in the header verbatim, this returns `null`. + * @param mediaType The media type to get the weight of. + * @returns The weight of the media type, or `null` if it is not in the header. */ get(mediaType: string): number | null { return this.#map.get(mediaType.toLowerCase()) ?? null; } /** - * Sets a media type with the given quality. + * Sets a media type with the given weight. * @param mediaType The media type to set. - * @param quality The quality of the media type. Defaults to 1. + * @param weight The weight of the media type. Defaults to 1. */ - set(mediaType: string, quality = 1): void { - this.#map.set(mediaType.toLowerCase(), quality); + set(mediaType: string, weight = 1): void { + this.#map.set(mediaType.toLowerCase(), weight); this.#sort(); } @@ -171,11 +171,11 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { } forEach( - callback: (mediaType: string, quality: number, header: Accept) => void, + callback: (mediaType: string, weight: number, header: Accept) => void, thisArg?: any, ): void { - for (let [mediaType, quality] of this) { - callback.call(thisArg, mediaType, quality, this); + for (let [mediaType, weight] of this) { + callback.call(thisArg, mediaType, weight, this); } } @@ -189,8 +189,8 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { toString(): string { let pairs: string[] = []; - for (let [mediaType, quality] of this.#map) { - pairs.push(`${mediaType}${quality === 1 ? '' : `;q=${quality}`}`); + for (let [mediaType, weight] of this.#map) { + pairs.push(`${mediaType}${weight === 1 ? '' : `;q=${weight}`}`); } return pairs.join(','); diff --git a/packages/headers/src/lib/super-headers.test.ts b/packages/headers/src/lib/super-headers.test.ts index 5952da27ab5..942e961de61 100644 --- a/packages/headers/src/lib/super-headers.test.ts +++ b/packages/headers/src/lib/super-headers.test.ts @@ -275,12 +275,12 @@ describe('SuperHeaders', () => { headers.accept = 'text/html,application/json;q=0.9'; assert.deepEqual(headers.accept.size, 2); assert.deepEqual(headers.accept.mediaTypes, ['text/html', 'application/json']); - assert.deepEqual(headers.accept.qualities, [1, 0.9]); + assert.deepEqual(headers.accept.weights, [1, 0.9]); headers.accept = { 'application/json': 0.8, 'text/html': 1 }; assert.deepEqual(headers.accept.size, 2); assert.deepEqual(headers.accept.mediaTypes, ['text/html', 'application/json']); - assert.deepEqual(headers.accept.qualities, [1, 0.8]); + assert.deepEqual(headers.accept.weights, [1, 0.8]); headers.accept = null; assert.ok(headers.accept instanceof Accept); @@ -315,12 +315,12 @@ describe('SuperHeaders', () => { headers.acceptLanguage = 'en-US,en;q=0.9'; assert.deepEqual(headers.acceptLanguage.size, 2); assert.deepEqual(headers.acceptLanguage.languages, ['en-us', 'en']); - assert.deepEqual(headers.acceptLanguage.qualities, [1, 0.9]); + assert.deepEqual(headers.acceptLanguage.weights, [1, 0.9]); headers.acceptLanguage = { en: 1, 'en-US': 0.8 }; assert.deepEqual(headers.acceptLanguage.size, 2); assert.deepEqual(headers.acceptLanguage.languages, ['en', 'en-us']); - assert.deepEqual(headers.acceptLanguage.qualities, [1, 0.8]); + assert.deepEqual(headers.acceptLanguage.weights, [1, 0.8]); headers.acceptLanguage = null; assert.ok(headers.acceptLanguage instanceof AcceptLanguage); From 12bbd148ad83bd0ff7f6d5ef37d7375bff3ac434 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 19 Dec 2024 23:45:30 -0800 Subject: [PATCH 550/730] Add Accept-Ranges support --- packages/headers/CHANGELOG.md | 11 ++--- packages/headers/README.md | 12 ++++++ .../headers/src/lib/super-headers.test.ts | 17 ++++++++ packages/headers/src/lib/super-headers.ts | 43 +++++++++++++++---- 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 243dfbd26d5..84255ec6941 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -128,11 +128,12 @@ header.getPreferred(['gzip', 'deflate']); // 'gzip' ``` - Added `SuperHeaders.prototype` (getters and setters) for: - - `headers.accept` - - `headers.acceptEncoding` - - `headers.connection` - - `headers.host` - - `headers.referer` + - `accept` + - `acceptEncoding` + - `acceptRanges` + - `connection` + - `host` + - `referer` ## v0.8.0 (2024-11-14) diff --git a/packages/headers/README.md b/packages/headers/README.md index d0419029ff4..44040aa3e38 100644 --- a/packages/headers/README.md +++ b/packages/headers/README.md @@ -64,6 +64,12 @@ headers.acceptLanguage.accepts('ja'); // false headers.acceptLanguage.getPreferred(['en-US', 'en-GB']); // 'en-US' headers.acceptLanguage.getPreferred(['en', 'fr']); // 'en' +// Accept-Ranges +headers.acceptRanges = 'bytes'; + +// Connection +headers.connection = 'close'; + // Content-Type headers.contentType = 'application/json; charset=utf-8'; @@ -92,6 +98,12 @@ console.log(headers.cookie.get('user_id')); // '12345' headers.cookie.set('theme', 'dark'); console.log(headers.get('Cookie')); // 'session_id=abc123; user_id=12345; theme=dark' +// Host +headers.host = 'example.com'; + +// Referer +headers.referer = 'https://example.com/'; + // Set-Cookie headers.setCookie = ['session_id=abc123; Path=/; HttpOnly']; diff --git a/packages/headers/src/lib/super-headers.test.ts b/packages/headers/src/lib/super-headers.test.ts index 942e961de61..f34b426ea07 100644 --- a/packages/headers/src/lib/super-headers.test.ts +++ b/packages/headers/src/lib/super-headers.test.ts @@ -173,6 +173,11 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Accept-Language'), 'en-us,en;q=0.9'); }); + it('handles the acceptRanges property', () => { + let headers = new SuperHeaders({ acceptRanges: 'bytes' }); + assert.equal(headers.get('Accept-Ranges'), 'bytes'); + }); + it('handles the age property', () => { let headers = new SuperHeaders({ age: 42 }); assert.equal(headers.get('Age'), '42'); @@ -327,6 +332,18 @@ describe('SuperHeaders', () => { assert.equal(headers.acceptLanguage.toString(), ''); }); + it('supports the acceptRanges property', () => { + let headers = new SuperHeaders(); + + assert.equal(headers.acceptRanges, null); + + headers.acceptRanges = 'bytes'; + assert.equal(headers.acceptRanges, 'bytes'); + + headers.acceptRanges = null; + assert.equal(headers.acceptRanges, null); + }); + it('supports the age property', () => { let headers = new SuperHeaders(); diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index 01a5a060f3d..27c125d1266 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -28,6 +28,10 @@ interface SuperHeadersPropertyInit { * The [`Accept-Language`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) header value. */ acceptLanguage?: string | AcceptLanguageInit; + /** + * The [`Accept-Ranges`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Ranges) header value. + */ + acceptRanges?: string; /** * The [`Age`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Age) header value. */ @@ -36,6 +40,10 @@ interface SuperHeadersPropertyInit { * The [`Cache-Control`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) header value. */ cacheControl?: string | CacheControlInit; + /** + * The [`Connection`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection) header value. + */ + connection?: string; /** * The [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) header value. */ @@ -60,6 +68,10 @@ interface SuperHeadersPropertyInit { * The [`Expires`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires) header value. */ expires?: string | DateInit; + /** + * The [`Host`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host) header value. + */ + host?: string; /** * The [`If-Modified-Since`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since) header value. */ @@ -72,6 +84,10 @@ interface SuperHeadersPropertyInit { * The [`Last-Modified`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified) header value. */ lastModified?: string | DateInit; + /** + * The [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header value. + */ + referer?: string; /** * The [`Set-Cookie`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) header value(s). */ @@ -115,15 +131,11 @@ export class SuperHeaders extends Headers { for (let name of Object.getOwnPropertyNames(init)) { let value = init[name]; - if (typeof value === 'string') { - this.set(name, value); + let descriptor = Object.getOwnPropertyDescriptor(SuperHeaders.prototype, name); + if (descriptor?.set) { + descriptor.set.call(this, value); } else { - let descriptor = Object.getOwnPropertyDescriptor(SuperHeaders.prototype, name); - if (descriptor?.set) { - descriptor.set.call(this, value); - } else { - this.set(name, value.toString()); - } + this.set(name, value.toString()); } } } @@ -346,6 +358,21 @@ export class SuperHeaders extends Headers { this.#setHeaderValue('accept-language', AcceptLanguage, value); } + /** + * The `Accept-Ranges` header indicates the server's acceptance of range requests. + * + * [MDN `Accept-Ranges` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Ranges) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7233#section-2.3) + */ + get acceptRanges(): string | null { + return this.get('accept-ranges'); + } + + set acceptRanges(value: string | undefined | null) { + this.#setValue('accept-ranges', value); + } + /** * The `Age` header contains the time in seconds an object was in a proxy cache. * From 360ae02bfd306535ca1a7d0997e6d2128e102017 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 20 Dec 2024 00:13:28 -0800 Subject: [PATCH 551/730] Add Content-Encoding, Content-Language, and Location support --- packages/headers/CHANGELOG.md | 3 + packages/headers/README.md | 49 +++++----- .../headers/src/lib/super-headers.test.ts | 93 +++++++++++++++---- packages/headers/src/lib/super-headers.ts | 63 +++++++++++++ 4 files changed, 169 insertions(+), 39 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 84255ec6941..fb35713238c 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -132,7 +132,10 @@ header.getPreferred(['gzip', 'deflate']); // 'gzip' - `acceptEncoding` - `acceptRanges` - `connection` + - `contentEncoding` + - `contentLanguage` - `host` + - `location` - `referer` ## v0.8.0 (2024-11-14) diff --git a/packages/headers/README.md b/packages/headers/README.md index 44040aa3e38..87dd4dc9a86 100644 --- a/packages/headers/README.md +++ b/packages/headers/README.md @@ -28,8 +28,8 @@ let headers = new Headers(); headers.accept = { 'text/html': 1, 'text/*': 0.9 }; // or headers.accept = 'text/html,text/*;q=0.9'; -console.log(headers.accept.mediaTypes); // [ 'text/html', 'text/*' ] -console.log(Object.fromEntries(headers.accept.entries())); // { 'text/html': 1, 'text/*': 0.9 } +headers.accept.mediaTypes; // [ 'text/html', 'text/*' ] +Object.fromEntries(headers.accept.entries()); // { 'text/html': 1, 'text/*': 0.9 } headers.accept.accepts('text/html'); // true headers.accept.accepts('text/plain'); // true @@ -40,7 +40,7 @@ headers.accept.getPreferred(['text/plain', 'text/html']); // 'text/html' headers.accept.set('text/plain', 0.9); headers.accept.set('text/*', 0.8); -console.log(headers.get('Accept')); // "text/html,text/plain;q=0.9,text/*;q=0.8" +headers.get('Accept'); // 'text/html,text/plain;q=0.9,text/*;q=0.8' // Accept-Encoding headers.acceptEncoding = { gzip: 1, deflate: 0.8 }; @@ -55,8 +55,8 @@ headers.acceptEncoding.getPreferred(['gzip', 'deflate']); // 'gzip' headers.acceptLanguage = { 'en-US': 1, en: 0.9 }; // or headers.acceptLanguage = 'en-US,en;q=0.9'; -console.log(headers.acceptLanguage.languages); // [ 'en-us', 'en' ] -console.log(Object.fromEntries(headers.acceptLanguage.entries())); // { 'en-us': 1, en: 0.9 } +headers.acceptLanguage.languages; // [ 'en-us', 'en' ] +Object.fromEntries(headers.acceptLanguage.entries()); // { 'en-us': 1, en: 0.9 } headers.acceptLanguage.accepts('en'); // true headers.acceptLanguage.accepts('ja'); // false @@ -73,51 +73,58 @@ headers.connection = 'close'; // Content-Type headers.contentType = 'application/json; charset=utf-8'; -console.log(headers.contentType.mediaType); // "application/json" -console.log(headers.contentType.charset); // "utf-8" +headers.contentType.mediaType; // "application/json" +headers.contentType.charset; // "utf-8" headers.contentType.charset = 'iso-8859-1'; -console.log(headers.get('Content-Type')); // "application/json; charset=iso-8859-1" +headers.get('Content-Type'); // "application/json; charset=iso-8859-1" // Content-Disposition headers.contentDisposition = 'attachment; filename="example.pdf"; filename*=UTF-8\'\'%E4%BE%8B%E5%AD%90.pdf'; -console.log(headers.contentDisposition.type); // 'attachment' -console.log(headers.contentDisposition.filename); // 'example.pdf' -console.log(headers.contentDisposition.filenameSplat); // 'UTF-8\'\'%E4%BE%8B%E5%AD%90.pdf' -console.log(headers.contentDisposition.preferredFilename); // '例子.pdf' +headers.contentDisposition.type; // 'attachment' +headers.contentDisposition.filename; // 'example.pdf' +headers.contentDisposition.filenameSplat; // 'UTF-8\'\'%E4%BE%8B%E5%AD%90.pdf' +headers.contentDisposition.preferredFilename; // '例子.pdf' // Cookie headers.cookie = 'session_id=abc123; user_id=12345'; -console.log(headers.cookie.get('session_id')); // 'abc123' -console.log(headers.cookie.get('user_id')); // '12345' +headers.cookie.get('session_id'); // 'abc123' +headers.cookie.get('user_id'); // '12345' headers.cookie.set('theme', 'dark'); -console.log(headers.get('Cookie')); // 'session_id=abc123; user_id=12345; theme=dark' +headers.get('Cookie'); // 'session_id=abc123; user_id=12345; theme=dark' // Host headers.host = 'example.com'; +// Last-Modified +headers.lastModified = new Date(); +// or headers.lastModified = new Date().getTime(); +headers.get('Last-Modified'); // 'Fri, 20 Dec 2024 08:08:05 GMT' + +// Location +headers.location = 'https://example.com'; + // Referer headers.referer = 'https://example.com/'; // Set-Cookie headers.setCookie = ['session_id=abc123; Path=/; HttpOnly']; -console.log(headers.setCookie[0].name); // 'session_id' -console.log(headers.setCookie[0].value); // 'abc123' -console.log(headers.setCookie[0].path); // '/' -console.log(headers.setCookie[0].httpOnly); // true +headers.setCookie[0].name; // 'session_id' +headers.setCookie[0].value; // 'abc123' +headers.setCookie[0].path; // '/' +headers.setCookie[0].httpOnly; // true // Modifying Set-Cookie attributes headers.setCookie[0].maxAge = 3600; headers.setCookie[0].secure = true; -console.log(headers.get('Set-Cookie')); -// session_id=abc123; Path=/; HttpOnly; Max-Age=3600; Secure +headers.get('Set-Cookie'); // 'session_id=abc123; Path=/; HttpOnly; Max-Age=3600; Secure' // Setting multiple cookies is easy, it's just an array headers.setCookie.push('user_id=12345; Path=/api; Secure'); diff --git a/packages/headers/src/lib/super-headers.test.ts b/packages/headers/src/lib/super-headers.test.ts index f34b426ea07..a32ef335117 100644 --- a/packages/headers/src/lib/super-headers.test.ts +++ b/packages/headers/src/lib/super-headers.test.ts @@ -200,6 +200,16 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Content-Disposition'), 'attachment; filename=example.txt'); }); + it('handles the contentEncoding property', () => { + let headers = new SuperHeaders({ contentEncoding: 'gzip' }); + assert.equal(headers.get('Content-Encoding'), 'gzip'); + }); + + it('handles the contentLanguage property', () => { + let headers = new SuperHeaders({ contentLanguage: 'en-US' }); + assert.equal(headers.get('Content-Language'), 'en-US'); + }); + it('handles the contentLength property', () => { let headers = new SuperHeaders({ contentLength: 42 }); assert.equal(headers.get('Content-Length'), '42'); @@ -232,11 +242,6 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Host'), 'example.com'); }); - it('handles the lastModified property', () => { - let headers = new SuperHeaders({ lastModified: new Date('2021-01-01T00:00:00Z') }); - assert.equal(headers.get('Last-Modified'), 'Fri, 01 Jan 2021 00:00:00 GMT'); - }); - it('handles the ifModifiedSince property', () => { let headers = new SuperHeaders({ ifModifiedSince: new Date('2021-01-01T00:00:00Z') }); assert.equal(headers.get('If-Modified-Since'), 'Fri, 01 Jan 2021 00:00:00 GMT'); @@ -247,6 +252,16 @@ describe('SuperHeaders', () => { assert.equal(headers.get('If-Unmodified-Since'), 'Fri, 01 Jan 2021 00:00:00 GMT'); }); + it('handles the lastModified property', () => { + let headers = new SuperHeaders({ lastModified: new Date('2021-01-01T00:00:00Z') }); + assert.equal(headers.get('Last-Modified'), 'Fri, 01 Jan 2021 00:00:00 GMT'); + }); + + it('handles the location property', () => { + let headers = new SuperHeaders({ location: 'https://example.com' }); + assert.equal(headers.get('Location'), 'https://example.com'); + }); + it('handles the referer property', () => { let headers = new SuperHeaders({ referer: 'https://example.com' }); assert.equal(headers.get('Referer'), 'https://example.com'); @@ -413,6 +428,36 @@ describe('SuperHeaders', () => { assert.equal(headers.contentDisposition.toString(), ''); }); + it('supports the contentEncoding property', () => { + let headers = new SuperHeaders(); + + assert.equal(headers.contentEncoding, null); + + headers.contentEncoding = 'gzip'; + assert.equal(headers.contentEncoding, 'gzip'); + + headers.contentEncoding = ['deflate', 'gzip']; + assert.equal(headers.contentEncoding, 'deflate, gzip'); + + headers.contentEncoding = null; + assert.equal(headers.contentEncoding, null); + }); + + it('supports the contentLanguage property', () => { + let headers = new SuperHeaders(); + + assert.equal(headers.contentLanguage, null); + + headers.contentLanguage = 'en-US'; + assert.equal(headers.contentLanguage, 'en-US'); + + headers.contentLanguage = ['en', 'fr']; + assert.equal(headers.contentLanguage, 'en, fr'); + + headers.contentLanguage = null; + assert.equal(headers.contentLanguage, null); + }); + it('supports the contentLength property', () => { let headers = new SuperHeaders(); @@ -506,19 +551,6 @@ describe('SuperHeaders', () => { assert.equal(headers.host, null); }); - it('supports the lastModified property', () => { - let headers = new SuperHeaders(); - - assert.equal(headers.lastModified, null); - - headers.lastModified = new Date('2021-01-01T00:00:00Z'); - assert.ok(headers.lastModified instanceof Date); - assert.equal(headers.lastModified.toUTCString(), 'Fri, 01 Jan 2021 00:00:00 GMT'); - - headers.lastModified = null; - assert.equal(headers.lastModified, null); - }); - it('supports the ifModifiedSince property', () => { let headers = new SuperHeaders(); @@ -545,6 +577,31 @@ describe('SuperHeaders', () => { assert.equal(headers.ifUnmodifiedSince, null); }); + it('supports the lastModified property', () => { + let headers = new SuperHeaders(); + + assert.equal(headers.lastModified, null); + + headers.lastModified = new Date('2021-01-01T00:00:00Z'); + assert.ok(headers.lastModified instanceof Date); + assert.equal(headers.lastModified.toUTCString(), 'Fri, 01 Jan 2021 00:00:00 GMT'); + + headers.lastModified = null; + assert.equal(headers.lastModified, null); + }); + + it('supports the location property', () => { + let headers = new SuperHeaders(); + + assert.equal(headers.location, null); + + headers.location = 'https://example.com'; + assert.equal(headers.location, 'https://example.com'); + + headers.location = null; + assert.equal(headers.location, null); + }); + it('supports the referer property', () => { let headers = new SuperHeaders(); diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index 27c125d1266..2de8db40bd2 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -48,6 +48,14 @@ interface SuperHeadersPropertyInit { * The [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) header value. */ contentDisposition?: string | ContentDispositionInit; + /** + * The [`Content-Encoding`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding) header value. + */ + contentEncoding?: string | string[]; + /** + * The [`Content-Language`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language) header value. + */ + contentLanguage?: string | string[]; /** * The [`Content-Length`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Length) header value. */ @@ -84,6 +92,10 @@ interface SuperHeadersPropertyInit { * The [`Last-Modified`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified) header value. */ lastModified?: string | DateInit; + /** + * The [`Location`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location) header value. + */ + location?: string; /** * The [`Referer`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header value. */ @@ -434,6 +446,42 @@ export class SuperHeaders extends Headers { this.#setHeaderValue('content-disposition', ContentDisposition, value); } + /** + * The `Content-Encoding` header specifies the encoding of the resource. + * + * Note: If multiple encodings have been used, this value may be a comma-separated list. However, most often this + * header will only contain a single value. + * + * [MDN `Content-Encoding` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding) + * + * [HTTP/1.1 Specification](https://httpwg.org/specs/rfc9110.html#field.content-encoding) + */ + get contentEncoding(): string | null { + return this.get('content-encoding'); + } + + set contentEncoding(value: string | string[] | undefined | null) { + this.#setValue('content-encoding', Array.isArray(value) ? value.join(', ') : value); + } + + /** + * The `Content-Language` header describes the natural language(s) of the intended audience for the response content. + * + * Note: If the response content is intended for multiple audiences, this value may be a comma-separated list. However, + * most often this header will only contain a single value. + * + * [MDN `Content-Language` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language) + * + * [HTTP/1.1 Specification](https://httpwg.org/specs/rfc9110.html#field.content-language) + */ + get contentLanguage(): string | null { + return this.get('content-language'); + } + + set contentLanguage(value: string | string[] | undefined | null) { + this.#setValue('content-language', Array.isArray(value) ? value.join(', ') : value); + } + /** * The `Content-Length` header indicates the size of the entity-body in bytes. * @@ -572,6 +620,21 @@ export class SuperHeaders extends Headers { this.#setDateValue('last-modified', value); } + /** + * The `Location` header indicates the URL to redirect to. + * + * [MDN `Location` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.2) + */ + get location(): string | null { + return this.get('location'); + } + + set location(value: string | undefined | null) { + this.#setValue('location', value); + } + /** * The `Referer` header contains the address of the previous web page from which a link to the * currently requested page was followed. From bf5c3e234feeb4ba61e8e97689c461f0a7c60e44 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 20 Dec 2024 00:31:20 -0800 Subject: [PATCH 552/730] Add ETag support --- packages/headers/CHANGELOG.md | 1 + .../headers/src/lib/super-headers.test.ts | 29 +++++++++++++++++++ packages/headers/src/lib/super-headers.ts | 22 ++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index fb35713238c..c0ba5833f5e 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -134,6 +134,7 @@ header.getPreferred(['gzip', 'deflate']); // 'gzip' - `connection` - `contentEncoding` - `contentLanguage` + - `etag` - `host` - `location` - `referer` diff --git a/packages/headers/src/lib/super-headers.test.ts b/packages/headers/src/lib/super-headers.test.ts index a32ef335117..19da6db78bc 100644 --- a/packages/headers/src/lib/super-headers.test.ts +++ b/packages/headers/src/lib/super-headers.test.ts @@ -232,6 +232,11 @@ describe('SuperHeaders', () => { assert.equal(headers.get('Date'), 'Fri, 01 Jan 2021 00:00:00 GMT'); }); + it('handles the etag property', () => { + let headers = new SuperHeaders({ etag: 'abc' }); + assert.equal(headers.get('ETag'), '"abc"'); + }); + it('handles the expires property', () => { let headers = new SuperHeaders({ expires: new Date('2021-01-01T00:00:00Z') }); assert.equal(headers.get('Expires'), 'Fri, 01 Jan 2021 00:00:00 GMT'); @@ -526,6 +531,30 @@ describe('SuperHeaders', () => { assert.equal(headers.date, null); }); + it('supports the etag property', () => { + let headers = new SuperHeaders(); + + assert.equal(headers.etag, null); + + headers.etag = 'abc'; + assert.equal(headers.etag, '"abc"'); + + headers.etag = '"def"'; + assert.equal(headers.etag, '"def"'); + + headers.etag = 'W/"def"'; + assert.equal(headers.etag, 'W/"def"'); + + headers.etag = ''; + assert.equal(headers.etag, '""'); + + headers.etag = '""'; + assert.equal(headers.etag, '""'); + + headers.etag = null; + assert.equal(headers.etag, null); + }); + it('supports the expires property', () => { let headers = new SuperHeaders(); diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index 2de8db40bd2..771761b3561 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -72,6 +72,10 @@ interface SuperHeadersPropertyInit { * The [`Date`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Date) header value. */ date?: string | DateInit; + /** + * The [`ETag`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) header value. + */ + etag?: string; /** * The [`Expires`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires) header value. */ @@ -543,6 +547,24 @@ export class SuperHeaders extends Headers { this.#setDateValue('date', value); } + /** + * The `ETag` header provides a unique identifier for the current version of the resource. + * + * [MDN `ETag` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-2.3) + */ + get etag(): string | null { + return this.get('etag'); + } + + set etag(value: string | undefined | null) { + this.#setValue( + 'etag', + typeof value === 'string' && !/^(W\/)?".*"$/.test(value) ? `"${value}"` : value, + ); + } + /** * The `Expires` header contains the date/time after which the response is considered stale. * From f7442788d4f0b0a1a10c38bb811dde81461e3924 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 20 Dec 2024 07:30:29 -0800 Subject: [PATCH 553/730] Fixup changelog --- packages/headers/CHANGELOG.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index c0ba5833f5e..00dfac3c93e 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -27,7 +27,7 @@ Similarly, the constructor no longer accepts non-string values in an array init let headers = new SuperHeaders([['Content-Type', { mediaType: 'text/html' }]]); // if you need the previous behavior, use the object init instead -let headers = new SuperHeaders({ contentType: 'text/html' }); +let headers = new SuperHeaders({ contentType: { mediaType: 'text/html' } }); ``` - BREAKING CHANGE: `headers.get()` returns `null` for uninitialized custom header values instead of `undefined`. This follows the native `Headers` interface more closely. @@ -43,7 +43,7 @@ headers.get('Host'); // null headers.get('Content-Type'); // null ``` -- BREAKING CHANGE: Removed ability to initialize `AcceptLanguage` with `undefined` quality values. +- BREAKING CHANGE: Removed ability to initialize `AcceptLanguage` with `undefined` weight values. ```ts // before @@ -65,11 +65,12 @@ headers.contentType = null; // same as headers.delete('Content-Type'); headers.contentType; // null ``` -- Allow setting date values (`date`, `expires`, `ifModifiedSince`, `ifUnmodifiedSince`, and `lastModified`) using numbers. +- Allow setting date headers (`date`, `expires`, `ifModifiedSince`, `ifUnmodifiedSince`, and `lastModified`) using numbers. ```ts let ms = new Date().getTime(); let headers = new SuperHeaders({ lastModified: ms }); +headers.date = ms; ``` - Added `AcceptLanguage.prototype.accepts(language)`, `AcceptLanguage.prototype.getWeight(language)`, From acc9ac538a99a2c16b09f68e93a48c377ae0afea Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 20 Dec 2024 07:30:54 -0800 Subject: [PATCH 554/730] Release headers@0.9.0 --- packages/headers/CHANGELOG.md | 2 +- packages/headers/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 00dfac3c93e..7e916bf3fe1 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`headers`](https://github.com/mjackson/remix-the-web/tree/main/packages/headers). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.9.0 (2024-12-20) This release tightens up the type safety and brings `SuperHeaders` more in line with the built-in `Headers` interface. diff --git a/packages/headers/package.json b/packages/headers/package.json index f4a61e3efee..c1c991d4f17 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/headers", - "version": "0.8.0", + "version": "0.9.0", "description": "A toolkit for working with HTTP headers in JavaScript", "author": "Michael Jackson <mjijackson@gmail.com>", "license": "MIT", From 19c3550729e1c0eff32e6ea85515cdba12c983db Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 20 Dec 2024 07:35:05 -0800 Subject: [PATCH 555/730] Fixup changelog --- packages/headers/CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 7e916bf3fe1..2994d87fc13 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -11,7 +11,7 @@ This release tightens up the type safety and brings `SuperHeaders` more in line ```ts // before let headers = new SuperHeaders(); -headers.set('Content-Type', { mediaType: 'text/html' }); // don't do this +headers.set('Content-Type', { mediaType: 'text/html' }); // after headers.set('Content-Type', 'text/html'); @@ -57,7 +57,6 @@ let h3 = new AcceptLanguage({ 'en-US': 1 }); - All setters now also accept `undefined | null` in addition to `string` and custom object values. Setting a header to `undefined | null` is the same as using `headers.delete()`. ```ts -// before let headers = new SuperHeaders({ 'Content-Type': 'text/html' }); headers.contentType; // 'text/html' From 451d9ba5ebb2628d0f323dc18069c534666a8c84 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 20 Dec 2024 08:19:58 -0800 Subject: [PATCH 556/730] Small perf optimization for string getters --- packages/headers/src/lib/super-headers.ts | 53 +++++++++++++---------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index 771761b3561..95d65925f16 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -382,11 +382,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7233#section-2.3) */ get acceptRanges(): string | null { - return this.get('accept-ranges'); + return this.#getStringValue('accept-ranges'); } set acceptRanges(value: string | undefined | null) { - this.#setValue('accept-ranges', value); + this.#setStringValue('accept-ranges', value); } /** @@ -428,11 +428,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7230#section-6.1) */ get connection(): string | null { - return this.get('connection'); + return this.#getStringValue('connection'); } set connection(value: string | undefined | null) { - this.#setValue('connection', value); + this.#setStringValue('connection', value); } /** @@ -461,11 +461,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://httpwg.org/specs/rfc9110.html#field.content-encoding) */ get contentEncoding(): string | null { - return this.get('content-encoding'); + return this.#getStringValue('content-encoding'); } set contentEncoding(value: string | string[] | undefined | null) { - this.#setValue('content-encoding', Array.isArray(value) ? value.join(', ') : value); + this.#setStringValue('content-encoding', Array.isArray(value) ? value.join(', ') : value); } /** @@ -479,11 +479,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://httpwg.org/specs/rfc9110.html#field.content-language) */ get contentLanguage(): string | null { - return this.get('content-language'); + return this.#getStringValue('content-language'); } set contentLanguage(value: string | string[] | undefined | null) { - this.#setValue('content-language', Array.isArray(value) ? value.join(', ') : value); + this.#setStringValue('content-language', Array.isArray(value) ? value.join(', ') : value); } /** @@ -555,11 +555,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-2.3) */ get etag(): string | null { - return this.get('etag'); + return this.#getStringValue('etag'); } set etag(value: string | undefined | null) { - this.#setValue( + this.#setStringValue( 'etag', typeof value === 'string' && !/^(W\/)?".*"$/.test(value) ? `"${value}"` : value, ); @@ -588,11 +588,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7230#section-5.4) */ get host(): string | null { - return this.get('host'); + return this.#getStringValue('host'); } set host(value: string | undefined | null) { - this.#setValue('host', value); + this.#setStringValue('host', value); } /** @@ -650,11 +650,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.2) */ get location(): string | null { - return this.get('location'); + return this.#getStringValue('location'); } set location(value: string | undefined | null) { - this.#setValue('location', value); + this.#setStringValue('location', value); } /** @@ -666,11 +666,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.5.2) */ get referer(): string | null { - return this.get('referer'); + return this.#getStringValue('referer'); } set referer(value: string | undefined | null) { - this.#setValue('referer', value); + this.#setStringValue('referer', value); } /** @@ -707,14 +707,6 @@ export class SuperHeaders extends Headers { // helpers - #setValue(key: string, value: string | undefined | null): void { - if (value != null) { - this.#map.set(key, value); - } else { - this.#map.delete(key); - } - } - #getHeaderValue<T extends HeaderValue>(key: string, ctor: new (init?: any) => T): T { let value = this.#map.get(key); @@ -771,4 +763,17 @@ export class SuperHeaders extends Headers { this.#map.delete(key); } } + + #getStringValue(key: string): string | null { + let value = this.#map.get(key); + return value === undefined ? null : (value as string); + } + + #setStringValue(key: string, value: string | undefined | null): void { + if (value != null) { + this.#map.set(key, value); + } else { + this.#map.delete(key); + } + } } From 99d12088c954097d7859ce4ddb8836eca9fe3bc4 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Fri, 20 Dec 2024 09:52:38 -0800 Subject: [PATCH 557/730] Some cookie changes --- packages/headers/CHANGELOG.md | 5 +++ packages/headers/src/lib/cookie.test.ts | 34 +++++++++++-------- packages/headers/src/lib/cookie.ts | 44 ++++++++++++++----------- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 2994d87fc13..475479bb344 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -2,6 +2,11 @@ This is the changelog for [`headers`](https://github.com/mjackson/remix-the-web/tree/main/packages/headers). It follows [semantic versioning](https://semver.org/). +## HEAD + +- BREAKING CHANGE: `cookie.delete(name)` returns `void` instead of `boolean` +- BREAKING CHANGE: `cookie.forEach()` calls its callback with `(name, value, cookie)` instead of `(value, name, map)` + ## v0.9.0 (2024-12-20) This release tightens up the type safety and brings `SuperHeaders` more in line with the built-in `Headers` interface. diff --git a/packages/headers/src/lib/cookie.test.ts b/packages/headers/src/lib/cookie.test.ts index 3d2d35bb1e6..7367bfea728 100644 --- a/packages/headers/src/lib/cookie.test.ts +++ b/packages/headers/src/lib/cookie.test.ts @@ -43,16 +43,21 @@ describe('Cookie', () => { }); it('sets and gets values', () => { - let header = new Cookie(''); + let header = new Cookie(); header.set('name', 'value'); assert.equal(header.get('name'), 'value'); }); + it('returns `null` for nonexistent values', () => { + let header = new Cookie(); + assert.equal(header.get('name'), null); + }); + it('deletes values', () => { let header = new Cookie('name=value'); - assert.equal(header.delete('name'), true); - assert.equal(header.delete('nonexistent'), false); - assert.equal(header.get('name'), undefined); + assert.equal(header.has('name'), true); + header.delete('name'); + assert.equal(header.has('name'), false); }); it('checks if value exists', () => { @@ -63,19 +68,11 @@ describe('Cookie', () => { it('clears all values', () => { let header = new Cookie('name1=value1; name2=value2'); + assert.equal(header.size, 2); header.clear(); assert.equal(header.size, 0); }); - it('iterates over entries', () => { - let header = new Cookie('name1=value1; name2=value2'); - let entries = Array.from(header.entries()); - assert.deepEqual(entries, [ - ['name1', 'value1'], - ['name2', 'value2'], - ]); - }); - it('iterates over names', () => { let header = new Cookie('name1=value1; name2=value2'); let names = Array.from(header.names()); @@ -88,10 +85,19 @@ describe('Cookie', () => { assert.deepEqual(values, ['value1', 'value2']); }); + it('iterates over entries', () => { + let header = new Cookie('name1=value1; name2=value2'); + let entries = Array.from(header.entries()); + assert.deepEqual(entries, [ + ['name1', 'value1'], + ['name2', 'value2'], + ]); + }); + it('uses forEach correctly', () => { let header = new Cookie('name1=value1; name2=value2'); let result: [string, string][] = []; - header.forEach((value, name) => { + header.forEach((name, value) => { result.push([name, value]); }); assert.deepEqual(result, [ diff --git a/packages/headers/src/lib/cookie.ts b/packages/headers/src/lib/cookie.ts index 3bfd8da9451..2d327b0b935 100644 --- a/packages/headers/src/lib/cookie.ts +++ b/packages/headers/src/lib/cookie.ts @@ -37,44 +37,47 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> { } /** - * Gets the value of a cookie with the given name from the `Cookie` header. + * Gets the value of a cookie with the given name from the header. + * @param name The name of the cookie. + * @returns The value of the cookie, or `null` if the cookie does not exist. */ - get(name: string): string | undefined { - return this.#map.get(name); + get(name: string): string | null { + return this.#map.get(name) ?? null; } /** - * Sets a cookie with the given name and value in the `Cookie` header. + * Sets a cookie with the given name and value in the header. + * @param name The name of the cookie. + * @param value The value of the cookie. */ set(name: string, value: string): void { this.#map.set(name, value); } /** - * Removes a cookie with the given name from the `Cookie` header. + * Removes a cookie with the given name from the header. + * @param name The name of the cookie. */ - delete(name: string): boolean { - return this.#map.delete(name); + delete(name: string): void { + this.#map.delete(name); } /** - * True if a cookie with the given name exists in the `Cookie` header. + * True if a cookie with the given name exists in the header. + * @param name The name of the cookie. + * @returns True if a cookie with the given name exists in the header. */ has(name: string): boolean { return this.#map.has(name); } /** - * Removes all cookies from the `Cookie` header. + * Removes all cookies from the header. */ clear(): void { this.#map.clear(); } - entries(): IterableIterator<[string, string]> { - return this.#map.entries(); - } - names(): IterableIterator<string> { return this.#map.keys(); } @@ -83,19 +86,22 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> { return this.#map.values(); } + entries(): IterableIterator<[string, string]> { + return this.#map.entries(); + } + [Symbol.iterator](): IterableIterator<[string, string]> { return this.entries(); } - forEach( - callback: (value: string, key: string, map: Map<string, string>) => void, - thisArg?: any, - ): void { - this.#map.forEach(callback, thisArg); + forEach(callback: (name: string, value: string, header: Cookie) => void, thisArg?: any): void { + for (let [name, value] of this) { + callback.call(thisArg, name, value, this); + } } /** - * The number of cookies in the `Cookie` header. + * The number of cookies in the header. */ get size(): number { return this.#map.size; From 430b910233149cc68f870580783fbda50cb27636 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Fri, 20 Dec 2024 10:15:59 -0800 Subject: [PATCH 558/730] Several Cookie improvements --- packages/headers/CHANGELOG.md | 13 +++++++- packages/headers/src/lib/accept-encoding.ts | 16 ++++----- packages/headers/src/lib/accept-language.ts | 20 ++++++------ packages/headers/src/lib/accept.ts | 22 ++++++------- packages/headers/src/lib/cookie.test.ts | 22 ++++++------- packages/headers/src/lib/cookie.ts | 36 ++++++++++++--------- 6 files changed, 71 insertions(+), 58 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index 475479bb344..daf01af3add 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -4,8 +4,19 @@ This is the changelog for [`headers`](https://github.com/mjackson/remix-the-web/ ## HEAD -- BREAKING CHANGE: `cookie.delete(name)` returns `void` instead of `boolean` +This release contains several improvements to `Cookie` that bring it more in line with other headers like `Accept`, `AcceptEncoding`, and `AcceptLanguage`. + +- BREAKING CHANGE: `cookie.names()` and `cookie.values()` are now getters that return `string[]` instead of methods that return `IterableIterator<string>` - BREAKING CHANGE: `cookie.forEach()` calls its callback with `(name, value, cookie)` instead of `(value, name, map)` +- BREAKING CHANGE: `cookie.delete(name)` returns `void` instead of `boolean` + +```ts +// before +let cookieNames = Array.from(headers.cookie.names()); + +// after +let cookieNames = headers.cookie.names; +``` ## v0.9.0 (2024-12-20) diff --git a/packages/headers/src/lib/accept-encoding.ts b/packages/headers/src/lib/accept-encoding.ts index 715c06a1001..96e157a4fa7 100644 --- a/packages/headers/src/lib/accept-encoding.ts +++ b/packages/headers/src/lib/accept-encoding.ts @@ -55,7 +55,7 @@ export class AcceptEncoding implements HeaderValue, Iterable<[string, number]> { } #sort() { - this.#map = new Map([...this.#map].sort(([, a], [, b]) => b - a)); + this.#map = new Map([...this.#map].sort((a, b) => b[1] - a[1])); } /** @@ -72,6 +72,13 @@ export class AcceptEncoding implements HeaderValue, Iterable<[string, number]> { return Array.from(this.#map.values()); } + /** + * The number of encodings in the header. + */ + get size(): number { + return this.#map.size; + } + /** * Returns `true` if the header matches the given encoding (i.e. it is "acceptable"). * @param encoding The encoding to check. @@ -173,13 +180,6 @@ export class AcceptEncoding implements HeaderValue, Iterable<[string, number]> { } } - /** - * The number of encodings in the header. - */ - get size(): number { - return this.#map.size; - } - toString(): string { let pairs: string[] = []; diff --git a/packages/headers/src/lib/accept-language.ts b/packages/headers/src/lib/accept-language.ts index 63b1804fcb5..ca2767b6701 100644 --- a/packages/headers/src/lib/accept-language.ts +++ b/packages/headers/src/lib/accept-language.ts @@ -55,23 +55,30 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { } #sort() { - this.#map = new Map([...this.#map].sort(([, a], [, b]) => b - a)); + this.#map = new Map([...this.#map].sort((a, b) => b[1] - a[1])); } /** - * An array of all locale identifiers in the header. + * An array of all languages in the header. */ get languages(): string[] { return Array.from(this.#map.keys()); } /** - * An array of all weight values in the header. + * An array of all weights (q values) in the header. */ get weights(): number[] { return Array.from(this.#map.values()); } + /** + * The number of languages in the header. + */ + get size(): number { + return this.#map.size; + } + /** * Returns `true` if the header matches the given language (i.e. it is "acceptable"). * @param language The locale identifier of the language to check. @@ -179,13 +186,6 @@ export class AcceptLanguage implements HeaderValue, Iterable<[string, number]> { } } - /** - * The number of languages in the header. - */ - get size(): number { - return this.#map.size; - } - toString(): string { let pairs: string[] = []; diff --git a/packages/headers/src/lib/accept.ts b/packages/headers/src/lib/accept.ts index eb506101d9b..684c84c3268 100644 --- a/packages/headers/src/lib/accept.ts +++ b/packages/headers/src/lib/accept.ts @@ -55,7 +55,7 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { } #sort() { - this.#map = new Map([...this.#map].sort(([, a], [, b]) => b - a)); + this.#map = new Map([...this.#map].sort((a, b) => b[1] - a[1])); } /** @@ -66,12 +66,19 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { } /** - * An array of weight values in the header. + * An array of all weights (q values) in the header. */ get weights(): number[] { return Array.from(this.#map.values()); } + /** + * The number of media types in the `Accept` header. + */ + get size(): number { + return this.#map.size; + } + /** * Returns `true` if the header matches the given media type (i.e. it is "acceptable"). * @param mediaType The media type to check. @@ -110,9 +117,7 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { getPreferred(mediaTypes: string[]): string | null { let sorted = mediaTypes .map((mediaType) => [mediaType, this.getWeight(mediaType)] as const) - .sort((a, b) => { - return b[1] - a[1]; - }); + .sort((a, b) => b[1] - a[1]); let first = sorted[0]; @@ -179,13 +184,6 @@ export class Accept implements HeaderValue, Iterable<[string, number]> { } } - /** - * The number of media types in the `Accept` header. - */ - get size(): number { - return this.#map.size; - } - toString(): string { let pairs: string[] = []; diff --git a/packages/headers/src/lib/cookie.test.ts b/packages/headers/src/lib/cookie.test.ts index 7367bfea728..56b2d225da0 100644 --- a/packages/headers/src/lib/cookie.test.ts +++ b/packages/headers/src/lib/cookie.test.ts @@ -42,6 +42,16 @@ describe('Cookie', () => { assert.equal(header.get('name2'), 'value2'); }); + it('gets all names', () => { + let header = new Cookie('name1=value1; name2=value2'); + assert.deepEqual(header.names, ['name1', 'name2']); + }); + + it('gets all values', () => { + let header = new Cookie('name1=value1; name2=value2'); + assert.deepEqual(header.values, ['value1', 'value2']); + }); + it('sets and gets values', () => { let header = new Cookie(); header.set('name', 'value'); @@ -73,18 +83,6 @@ describe('Cookie', () => { assert.equal(header.size, 0); }); - it('iterates over names', () => { - let header = new Cookie('name1=value1; name2=value2'); - let names = Array.from(header.names()); - assert.deepEqual(names, ['name1', 'name2']); - }); - - it('iterates over values', () => { - let header = new Cookie('name1=value1; name2=value2'); - let values = Array.from(header.values()); - assert.deepEqual(values, ['value1', 'value2']); - }); - it('iterates over entries', () => { let header = new Cookie('name1=value1; name2=value2'); let entries = Array.from(header.entries()); diff --git a/packages/headers/src/lib/cookie.ts b/packages/headers/src/lib/cookie.ts index 2d327b0b935..d10d2e541f5 100644 --- a/packages/headers/src/lib/cookie.ts +++ b/packages/headers/src/lib/cookie.ts @@ -36,6 +36,27 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> { } } + /** + * An array of the names of the cookies in the header. + */ + get names(): string[] { + return Array.from(this.#map.keys()); + } + + /** + * An array of the values of the cookies in the header. + */ + get values(): string[] { + return Array.from(this.#map.values()); + } + + /** + * The number of cookies in the header. + */ + get size(): number { + return this.#map.size; + } + /** * Gets the value of a cookie with the given name from the header. * @param name The name of the cookie. @@ -78,14 +99,6 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> { this.#map.clear(); } - names(): IterableIterator<string> { - return this.#map.keys(); - } - - values(): IterableIterator<string> { - return this.#map.values(); - } - entries(): IterableIterator<[string, string]> { return this.#map.entries(); } @@ -100,13 +113,6 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> { } } - /** - * The number of cookies in the header. - */ - get size(): number { - return this.#map.size; - } - toString(): string { let pairs: string[] = []; From e3d5ce6914fb23e95511a7f14480df3046ab670d Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Fri, 20 Dec 2024 10:29:20 -0800 Subject: [PATCH 559/730] Small tweaks to Cookie constructor --- packages/headers/src/lib/cookie.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/headers/src/lib/cookie.ts b/packages/headers/src/lib/cookie.ts index d10d2e541f5..5ce079ef671 100644 --- a/packages/headers/src/lib/cookie.ts +++ b/packages/headers/src/lib/cookie.ts @@ -20,17 +20,15 @@ export class Cookie implements HeaderValue, Iterable<[string, string]> { if (typeof init === 'string') { let params = parseParams(init); for (let [name, value] of params) { - this.#map.set(name, value || ''); + this.#map.set(name, value ?? ''); } } else if (isIterable(init)) { for (let [name, value] of init) { this.#map.set(name, value); } } else { - for (let name in init) { - if (Object.prototype.hasOwnProperty.call(init, name)) { - this.#map.set(name, init[name]); - } + for (let name of Object.getOwnPropertyNames(init)) { + this.#map.set(name, init[name]); } } } From 88f5555b7451f83b64c64b6da664681d4ad14a9d Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Fri, 20 Dec 2024 10:41:59 -0800 Subject: [PATCH 560/730] Use constants for internal key names --- packages/headers/src/lib/super-headers.ts | 117 +++++++++++++--------- 1 file changed, 70 insertions(+), 47 deletions(-) diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index 95d65925f16..a3e4b6dbfa5 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -10,9 +10,6 @@ import { type HeaderValue } from './header-value.ts'; import { type SetCookieInit, SetCookie } from './set-cookie.ts'; import { isIterable } from './utils.ts'; -const CRLF = '\r\n'; -const SetCookieKey = 'set-cookie'; - type DateInit = number | Date; interface SuperHeadersPropertyInit { @@ -114,6 +111,32 @@ export type SuperHeadersInit = | Iterable<[string, string]> | (SuperHeadersPropertyInit & Record<string, string | HeaderValue>); +const CRLF = '\r\n'; + +const AcceptKey = 'accept'; +const AcceptEncodingKey = 'accept-encoding'; +const AcceptLanguageKey = 'accept-language'; +const AcceptRangesKey = 'accept-ranges'; +const AgeKey = 'age'; +const CacheControlKey = 'cache-control'; +const ConnectionKey = 'connection'; +const ContentDispositionKey = 'content-disposition'; +const ContentEncodingKey = 'content-encoding'; +const ContentLanguageKey = 'content-language'; +const ContentLengthKey = 'content-length'; +const ContentTypeKey = 'content-type'; +const CookieKey = 'cookie'; +const DateKey = 'date'; +const ETagKey = 'etag'; +const ExpiresKey = 'expires'; +const HostKey = 'host'; +const IfModifiedSinceKey = 'if-modified-since'; +const IfUnmodifiedSinceKey = 'if-unmodified-since'; +const LastModifiedKey = 'last-modified'; +const LocationKey = 'location'; +const RefererKey = 'referer'; +const SetCookieKey = 'set-cookie'; + /** * An enhanced JavaScript `Headers` interface with type-safe access. * @@ -335,11 +358,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2) */ get accept(): Accept { - return this.#getHeaderValue('accept', Accept); + return this.#getHeaderValue(AcceptKey, Accept); } set accept(value: string | AcceptInit | undefined | null) { - this.#setHeaderValue('accept', Accept, value); + this.#setHeaderValue(AcceptKey, Accept, value); } /** @@ -351,11 +374,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.4) */ get acceptEncoding(): AcceptEncoding { - return this.#getHeaderValue('accept-encoding', AcceptEncoding); + return this.#getHeaderValue(AcceptEncodingKey, AcceptEncoding); } set acceptEncoding(value: string | AcceptEncodingInit | undefined | null) { - this.#setHeaderValue('accept-encoding', AcceptEncoding, value); + this.#setHeaderValue(AcceptEncodingKey, AcceptEncoding, value); } /** @@ -367,11 +390,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.5) */ get acceptLanguage(): AcceptLanguage { - return this.#getHeaderValue('accept-language', AcceptLanguage); + return this.#getHeaderValue(AcceptLanguageKey, AcceptLanguage); } set acceptLanguage(value: string | AcceptLanguageInit | undefined | null) { - this.#setHeaderValue('accept-language', AcceptLanguage, value); + this.#setHeaderValue(AcceptLanguageKey, AcceptLanguage, value); } /** @@ -382,11 +405,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7233#section-2.3) */ get acceptRanges(): string | null { - return this.#getStringValue('accept-ranges'); + return this.#getStringValue(AcceptRangesKey); } set acceptRanges(value: string | undefined | null) { - this.#setStringValue('accept-ranges', value); + this.#setStringValue(AcceptRangesKey, value); } /** @@ -397,11 +420,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7234#section-5.1) */ get age(): number | null { - return this.#getNumberValue('age'); + return this.#getNumberValue(AgeKey); } set age(value: string | number | undefined | null) { - this.#setNumberValue('age', value); + this.#setNumberValue(AgeKey, value); } /** @@ -412,11 +435,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7234#section-5.2) */ get cacheControl(): CacheControl { - return this.#getHeaderValue('cache-control', CacheControl); + return this.#getHeaderValue(CacheControlKey, CacheControl); } set cacheControl(value: string | CacheControlInit | undefined | null) { - this.#setHeaderValue('cache-control', CacheControl, value); + this.#setHeaderValue(CacheControlKey, CacheControl, value); } /** @@ -428,11 +451,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7230#section-6.1) */ get connection(): string | null { - return this.#getStringValue('connection'); + return this.#getStringValue(ConnectionKey); } set connection(value: string | undefined | null) { - this.#setStringValue('connection', value); + this.#setStringValue(ConnectionKey, value); } /** @@ -443,11 +466,11 @@ export class SuperHeaders extends Headers { * [RFC 6266](https://datatracker.ietf.org/doc/html/rfc6266) */ get contentDisposition(): ContentDisposition { - return this.#getHeaderValue('content-disposition', ContentDisposition); + return this.#getHeaderValue(ContentDispositionKey, ContentDisposition); } set contentDisposition(value: string | ContentDispositionInit | undefined | null) { - this.#setHeaderValue('content-disposition', ContentDisposition, value); + this.#setHeaderValue(ContentDispositionKey, ContentDisposition, value); } /** @@ -461,11 +484,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://httpwg.org/specs/rfc9110.html#field.content-encoding) */ get contentEncoding(): string | null { - return this.#getStringValue('content-encoding'); + return this.#getStringValue(ContentEncodingKey); } set contentEncoding(value: string | string[] | undefined | null) { - this.#setStringValue('content-encoding', Array.isArray(value) ? value.join(', ') : value); + this.#setStringValue(ContentEncodingKey, Array.isArray(value) ? value.join(', ') : value); } /** @@ -479,11 +502,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://httpwg.org/specs/rfc9110.html#field.content-language) */ get contentLanguage(): string | null { - return this.#getStringValue('content-language'); + return this.#getStringValue(ContentLanguageKey); } set contentLanguage(value: string | string[] | undefined | null) { - this.#setStringValue('content-language', Array.isArray(value) ? value.join(', ') : value); + this.#setStringValue(ContentLanguageKey, Array.isArray(value) ? value.join(', ') : value); } /** @@ -494,11 +517,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2) */ get contentLength(): number | null { - return this.#getNumberValue('content-length'); + return this.#getNumberValue(ContentLengthKey); } set contentLength(value: string | number | undefined | null) { - this.#setNumberValue('content-length', value); + this.#setNumberValue(ContentLengthKey, value); } /** @@ -509,11 +532,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-3.1.1.5) */ get contentType(): ContentType { - return this.#getHeaderValue('content-type', ContentType); + return this.#getHeaderValue(ContentTypeKey, ContentType); } set contentType(value: string | ContentTypeInit | undefined | null) { - this.#setHeaderValue('content-type', ContentType, value); + this.#setHeaderValue(ContentTypeKey, ContentType, value); } /** @@ -525,11 +548,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc6265#section-5.4) */ get cookie(): Cookie { - return this.#getHeaderValue('cookie', Cookie); + return this.#getHeaderValue(CookieKey, Cookie); } set cookie(value: string | CookieInit | undefined | null) { - this.#setHeaderValue('cookie', Cookie, value); + this.#setHeaderValue(CookieKey, Cookie, value); } /** @@ -540,11 +563,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.2) */ get date(): Date | null { - return this.#getDateValue('date'); + return this.#getDateValue(DateKey); } set date(value: string | DateInit | undefined | null) { - this.#setDateValue('date', value); + this.#setDateValue(DateKey, value); } /** @@ -555,12 +578,12 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-2.3) */ get etag(): string | null { - return this.#getStringValue('etag'); + return this.#getStringValue(ETagKey); } set etag(value: string | undefined | null) { this.#setStringValue( - 'etag', + ETagKey, typeof value === 'string' && !/^(W\/)?".*"$/.test(value) ? `"${value}"` : value, ); } @@ -573,11 +596,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7234#section-5.3) */ get expires(): Date | null { - return this.#getDateValue('expires'); + return this.#getDateValue(ExpiresKey); } set expires(value: string | DateInit | undefined | null) { - this.#setDateValue('expires', value); + this.#setDateValue(ExpiresKey, value); } /** @@ -588,11 +611,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7230#section-5.4) */ get host(): string | null { - return this.#getStringValue('host'); + return this.#getStringValue(HostKey); } set host(value: string | undefined | null) { - this.#setStringValue('host', value); + this.#setStringValue(HostKey, value); } /** @@ -604,11 +627,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-3.3) */ get ifModifiedSince(): Date | null { - return this.#getDateValue('if-modified-since'); + return this.#getDateValue(IfModifiedSinceKey); } set ifModifiedSince(value: string | DateInit | undefined | null) { - this.#setDateValue('if-modified-since', value); + this.#setDateValue(IfModifiedSinceKey, value); } /** @@ -620,11 +643,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-3.4) */ get ifUnmodifiedSince(): Date | null { - return this.#getDateValue('if-unmodified-since'); + return this.#getDateValue(IfUnmodifiedSinceKey); } set ifUnmodifiedSince(value: string | DateInit | undefined | null) { - this.#setDateValue('if-unmodified-since', value); + this.#setDateValue(IfUnmodifiedSinceKey, value); } /** @@ -635,11 +658,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-2.2) */ get lastModified(): Date | null { - return this.#getDateValue('last-modified'); + return this.#getDateValue(LastModifiedKey); } set lastModified(value: string | DateInit | undefined | null) { - this.#setDateValue('last-modified', value); + this.#setDateValue(LastModifiedKey, value); } /** @@ -650,11 +673,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.2) */ get location(): string | null { - return this.#getStringValue('location'); + return this.#getStringValue(LocationKey); } set location(value: string | undefined | null) { - this.#setStringValue('location', value); + this.#setStringValue(LocationKey, value); } /** @@ -666,11 +689,11 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7231#section-5.5.2) */ get referer(): string | null { - return this.#getStringValue('referer'); + return this.#getStringValue(RefererKey); } set referer(value: string | undefined | null) { - this.#setStringValue('referer', value); + this.#setStringValue(RefererKey, value); } /** From fe73e0c4776788a803957b16b27a34831d1db549 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Fri, 20 Dec 2024 10:47:55 -0800 Subject: [PATCH 561/730] Update README --- packages/headers/README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/headers/README.md b/packages/headers/README.md index 87dd4dc9a86..9aca9bc0c30 100644 --- a/packages/headers/README.md +++ b/packages/headers/README.md @@ -25,8 +25,7 @@ import Headers from '@mjackson/headers'; let headers = new Headers(); // Accept -headers.accept = { 'text/html': 1, 'text/*': 0.9 }; -// or headers.accept = 'text/html,text/*;q=0.9'; +headers.accept = 'text/html, text/*;q=0.9'; headers.accept.mediaTypes; // [ 'text/html', 'text/*' ] Object.fromEntries(headers.accept.entries()); // { 'text/html': 1, 'text/*': 0.9 } @@ -43,8 +42,7 @@ headers.accept.set('text/*', 0.8); headers.get('Accept'); // 'text/html,text/plain;q=0.9,text/*;q=0.8' // Accept-Encoding -headers.acceptEncoding = { gzip: 1, deflate: 0.8 }; -// or headers.acceptEncoding = 'gzip, deflate;q=0.8'; +headers.acceptEncoding = 'gzip, deflate;q=0.8'; headers.acceptEncoding.accepts('gzip'); // true headers.acceptEncoding.accepts('br'); // false @@ -52,8 +50,7 @@ headers.acceptEncoding.accepts('br'); // false headers.acceptEncoding.getPreferred(['gzip', 'deflate']); // 'gzip' // Accept-Language -headers.acceptLanguage = { 'en-US': 1, en: 0.9 }; -// or headers.acceptLanguage = 'en-US,en;q=0.9'; +headers.acceptLanguage = 'en-US, en;q=0.9'; headers.acceptLanguage.languages; // [ 'en-us', 'en' ] Object.fromEntries(headers.acceptLanguage.entries()); // { 'en-us': 1, en: 0.9 } From 861205bf24cf8ce38f56c3bce03481f89a430277 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Fri, 20 Dec 2024 10:54:51 -0800 Subject: [PATCH 562/730] Fixup changelog --- packages/headers/CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index daf01af3add..ea51d5b19e5 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -73,11 +73,11 @@ let h3 = new AcceptLanguage({ 'en-US': 1 }); - All setters now also accept `undefined | null` in addition to `string` and custom object values. Setting a header to `undefined | null` is the same as using `headers.delete()`. ```ts -let headers = new SuperHeaders({ 'Content-Type': 'text/html' }); -headers.contentType; // 'text/html' +let headers = new SuperHeaders({ contentType: 'text/html' }); +headers.get('Content-Type'); // 'text/html' headers.contentType = null; // same as headers.delete('Content-Type'); -headers.contentType; // null +headers.get('Content-Type'); // null ``` - Allow setting date headers (`date`, `expires`, `ifModifiedSince`, `ifUnmodifiedSince`, and `lastModified`) using numbers. From 909342e32db98bc5232e8a7547c35289840ab7cc Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Fri, 20 Dec 2024 11:12:20 -0800 Subject: [PATCH 563/730] Fixup README --- packages/headers/README.md | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/packages/headers/README.md b/packages/headers/README.md index 9aca9bc0c30..823fa9a4a91 100644 --- a/packages/headers/README.md +++ b/packages/headers/README.md @@ -19,6 +19,8 @@ npm install @mjackson/headers ## Overview +The following should give you a sense of what kinds of things you can do with this library: + ```ts import Headers from '@mjackson/headers'; @@ -204,33 +206,17 @@ console.log(`${headers}`); // Accept-Language: en-US,en;q=0.9 ``` -## Low-level API - -In addition to the high-level `Headers` API, `headers` also provides a rich set of primitives you can use to work with just about any complex HTTP header value. Each header class includes a spec-compliant parser (the constructor), stringifier (`toString`), and getters/setters for all relevant attributes. Classes for headers that contain a list of fields, like `Cookie`, are `Iterable`. - -All individual header classes may be initialized with either a) the string value of the header or b) an `init` object specific to that header. +## Individual Header Utility Classes -The following headers are currently supported: - -- [headers](#headers) - - [Installation](#installation) - - [Overview](#overview) - - [Low-level API](#low-level-api) - - [Accept](#accept) - - [Accept-Encoding](#accept-encoding) - - [Accept-Language](#accept-language) - - [Cache-Control](#cache-control) - - [Content-Disposition](#content-disposition) - - [Content-Type](#content-type) - - [Cookie](#cookie) - - [Set-Cookie](#set-cookie) - - [License](#license) +In addition to the high-level `Headers` API, `headers` also provides a rich set of primitives you can use to work with just about any complex HTTP header value. Each header class includes a spec-compliant parser (the constructor), stringifier (`toString`), and getters/setters for all relevant attributes. Classes for headers that contain a list of fields, like `Cookie`, are iterable. If you need support for a header that isn't listed here, please [send a PR](https://github.com/mjackson/remix-the-web/pulls)! The goal is to have first-class support for all common HTTP headers. ### Accept ```ts +import { Accept } from '@mjackson/headers'; + let header = new Accept('text/html;text/*;q=0.9'); header.has('text/html'); // true @@ -255,6 +241,8 @@ let header = new Accept(['text/html', ['text/*', 0.9]]); ### Accept-Encoding ```ts +import { AcceptEncoding } from '@mjackson/headers'; + let header = new AcceptEncoding('gzip,deflate;q=0.9'); header.has('gzip'); // true @@ -279,6 +267,8 @@ let header = new AcceptEncoding(['gzip', ['deflate', 0.9]]); ### Accept-Language ```ts +import { AcceptLanguage } from '@mjackson/headers'; + let header = new AcceptLanguage('en-US,en;q=0.9'); header.has('en-US'); // true @@ -403,6 +393,11 @@ let header = new SetCookie({ }); ``` +## Related Packages + +- [`fetch-proxy`](https://github.com/mjackson/remix-the-web/tree/main/packages/fetch-proxy) - Build HTTP proxy servers using the web fetch API +- [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server) - Build HTTP servers on Node.js using the web fetch API + ## License See [LICENSE](https://github.com/mjackson/remix-the-web/blob/main/LICENSE) From b2634164a15a707ab77955a110842d398c039900 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Fri, 20 Dec 2024 15:28:34 -0800 Subject: [PATCH 564/730] Style tweaks --- packages/headers/src/lib/super-headers.ts | 46 ++++++++++------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index a3e4b6dbfa5..beff8bb5a72 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -276,6 +276,24 @@ export class SuperHeaders extends Headers { } } + /** + * Returns an iterator of all header keys (lowercase). + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/keys) + */ + *keys(): IterableIterator<string> { + for (let [key] of this) yield key; + } + + /** + * Returns an iterator of all header values. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/values) + */ + *values(): IterableIterator<string> { + for (let [, value] of this) yield value; + } + /** * Returns an iterator of all header key/value pairs. * @@ -284,9 +302,7 @@ export class SuperHeaders extends Headers { *entries(): IterableIterator<[string, string]> { for (let [key] of this.#map) { let str = this.get(key); - if (str) { - yield [key, str]; - } + if (str) yield [key, str]; } for (let value of this.getSetCookie()) { @@ -298,28 +314,6 @@ export class SuperHeaders extends Headers { return this.entries(); } - /** - * Returns an iterator of all header keys (lowercase). - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/keys) - */ - *keys(): IterableIterator<string> { - for (let [key] of this) { - yield key; - } - } - - /** - * Returns an iterator of all header values. - * - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/values) - */ - *values(): IterableIterator<string> { - for (let [, value] of this) { - yield value; - } - } - /** * Invokes the `callback` for each header key/value pair. * @@ -728,7 +722,7 @@ export class SuperHeaders extends Headers { } } - // helpers + // Helpers #getHeaderValue<T extends HeaderValue>(key: string, ctor: new (init?: any) => T): T { let value = this.#map.get(key); From 7461ca1c87fc4b221326326b5beccc2a83cde535 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Fri, 20 Dec 2024 15:55:46 -0800 Subject: [PATCH 565/730] Make setCookie= slightly more efficient --- packages/headers/src/lib/super-headers.ts | 37 ++++++++++------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index beff8bb5a72..b083f2dadfc 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -146,7 +146,7 @@ const SetCookieKey = 'set-cookie'; */ export class SuperHeaders extends Headers { #map: Map<string, string | HeaderValue>; - #setCookieValues: (string | SetCookie)[] = []; + #setCookies: (string | SetCookie)[] = []; constructor(init?: string | SuperHeadersInit | Headers) { super(); @@ -190,10 +190,9 @@ export class SuperHeaders extends Headers { append(name: string, value: string): void { let key = name.toLowerCase(); if (key === SetCookieKey) { - this.#setCookieValues.push(value); + this.#setCookies.push(value); } else { let existingValue = this.#map.get(key); - // TODO: check if it's an empty string this.#map.set(key, existingValue ? `${existingValue}, ${value}` : value); } } @@ -206,7 +205,7 @@ export class SuperHeaders extends Headers { delete(name: string): void { let key = name.toLowerCase(); if (key === SetCookieKey) { - this.#setCookieValues = []; + this.#setCookies = []; } else { this.#map.delete(key); } @@ -242,9 +241,7 @@ export class SuperHeaders extends Headers { * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/getSetCookie) */ getSetCookie(): string[] { - return this.#setCookieValues.map((value) => - typeof value === 'string' ? value : value.toString(), - ); + return this.#setCookies.map((value) => (typeof value === 'string' ? value : value.toString())); } /** @@ -255,7 +252,7 @@ export class SuperHeaders extends Headers { has(name: string): boolean { let key = name.toLowerCase(); if (key === SetCookieKey) { - return this.#setCookieValues.length > 0; + return this.#setCookies.length > 0; } else { return this.#map.has(key); } @@ -270,7 +267,7 @@ export class SuperHeaders extends Headers { set(name: string, value: string): void { let key = name.toLowerCase(); if (key === SetCookieKey) { - this.#setCookieValues = [value]; + this.#setCookies = [value]; } else { this.#map.set(key, value); } @@ -698,27 +695,25 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc6265#section-4.1) */ get setCookie(): SetCookie[] { - for (let i = 0; i < this.#setCookieValues.length; ++i) { - let value = this.#setCookieValues[i]; + for (let i = 0; i < this.#setCookies.length; ++i) { + let value = this.#setCookies[i]; if (typeof value === 'string') { - this.#setCookieValues[i] = new SetCookie(value); + this.#setCookies[i] = new SetCookie(value); } } - return this.#setCookieValues as SetCookie[]; + return this.#setCookies as SetCookie[]; } - set setCookie(values: (string | SetCookieInit)[] | string | SetCookieInit | undefined | null) { - if (values != null) { - if (Array.isArray(values)) { - this.#setCookieValues = values.map((value) => - typeof value === 'string' || value instanceof SetCookie ? value : new SetCookie(value), - ); + set setCookie(value: (string | SetCookieInit)[] | string | SetCookieInit | undefined | null) { + if (value != null) { + if (Array.isArray(value)) { + this.#setCookies = value.map((v) => (typeof v === 'string' ? v : new SetCookie(v))); } else { - this.#setCookieValues = [new SetCookie(values)]; + this.#setCookies = [typeof value === 'string' ? value : new SetCookie(value)]; } } else { - this.#setCookieValues = []; + this.#setCookies = []; } } From 77d917324b640660c44c35963780a6102c991b4a Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Sat, 21 Dec 2024 10:41:22 -0800 Subject: [PATCH 566/730] Style tweaks --- packages/headers/src/lib/super-headers.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index b083f2dadfc..d0f7729faeb 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -695,23 +695,22 @@ export class SuperHeaders extends Headers { * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc6265#section-4.1) */ get setCookie(): SetCookie[] { - for (let i = 0; i < this.#setCookies.length; ++i) { - let value = this.#setCookies[i]; - if (typeof value === 'string') { - this.#setCookies[i] = new SetCookie(value); + let setCookies = this.#setCookies; + + for (let i = 0; i < setCookies.length; ++i) { + if (typeof setCookies[i] === 'string') { + setCookies[i] = new SetCookie(setCookies[i]); } } - return this.#setCookies as SetCookie[]; + return setCookies as SetCookie[]; } set setCookie(value: (string | SetCookieInit)[] | string | SetCookieInit | undefined | null) { if (value != null) { - if (Array.isArray(value)) { - this.#setCookies = value.map((v) => (typeof v === 'string' ? v : new SetCookie(v))); - } else { - this.#setCookies = [typeof value === 'string' ? value : new SetCookie(value)]; - } + this.#setCookies = (Array.isArray(value) ? value : [value]).map((v) => + typeof v === 'string' ? v : new SetCookie(v), + ); } else { this.#setCookies = []; } From d12f68d804b5d97ab3e9de6cf8545468832214f4 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Sat, 21 Dec 2024 10:53:45 -0800 Subject: [PATCH 567/730] Update TS deps --- .vscode/settings.json | 2 +- pnpm-lock.yaml | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 95486a455ae..3fdc00e57f4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,5 +6,5 @@ "parameters": ["--experimental-strip-types", "--disable-warning=ExperimentalWarning"] } ], - "typescript.tsdk": "node_modules/typescript/lib" + "typescript.tsdk": "./node_modules/typescript/lib" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0da4f1a2e5a..83a2dc84b17 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -814,8 +814,8 @@ packages: '@swc/helpers@0.5.12': resolution: {integrity: sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==} - '@swc/types@0.1.12': - resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==} + '@swc/types@0.1.17': + resolution: {integrity: sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==} '@types/body-parser@1.19.5': resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} @@ -1019,6 +1019,10 @@ packages: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} engines: {node: ^14.18.0 || >=16.10.0} + consola@3.3.0: + resolution: {integrity: sha512-kxltocVQCwQNFvw40dlVRYeAkAvtYjMFZYNlOcsF5wExPpGwPxMwgx4IfDJvBRPtBpnQwItd5WkTaR0ZwT/TmQ==} + engines: {node: ^14.18.0 || >=16.10.0} + content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -1735,6 +1739,9 @@ packages: tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsup@8.3.5: resolution: {integrity: sha512-Tunf6r6m6tnZsG9GYWndg0z8dEV7fD733VBFzFJ5Vcm1FtlXB8xBD/rtrBi2a3YKEV7hHtxiZtW5EAVADoe1pA==} engines: {node: '>=18'} @@ -2191,7 +2198,7 @@ snapshots: '@swc/core@1.5.29(@swc/helpers@0.5.12)': dependencies: '@swc/counter': 0.1.3 - '@swc/types': 0.1.12 + '@swc/types': 0.1.17 optionalDependencies: '@swc/core-darwin-arm64': 1.5.29 '@swc/core-darwin-x64': 1.5.29 @@ -2211,10 +2218,10 @@ snapshots: '@swc/helpers@0.5.12': dependencies: - tslib: 2.7.0 + tslib: 2.8.1 optional: true - '@swc/types@0.1.12': + '@swc/types@0.1.17': dependencies: '@swc/counter': 0.1.3 optional: true @@ -2449,6 +2456,8 @@ snapshots: consola@3.2.3: {} + consola@3.3.0: {} + content-disposition@0.5.4: dependencies: safe-buffer: 5.2.1 @@ -3197,6 +3206,9 @@ snapshots: tslib@2.7.0: {} + tslib@2.8.1: + optional: true + tsup@8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.7.2): dependencies: bundle-require: 5.0.0(esbuild@0.24.0) @@ -3243,7 +3255,7 @@ snapshots: unenv-nightly@1.10.0-1717606461.a117952: dependencies: - consola: 3.2.3 + consola: 3.3.0 defu: 6.1.4 mime: 3.0.0 node-fetch-native: 1.6.4 From 3735f611e5186cab0b866421bddebf0f088af21d Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Sat, 21 Dec 2024 11:10:23 -0800 Subject: [PATCH 568/730] Use local tsc for running tasks in VSCode --- .vscode/task.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .vscode/task.json diff --git a/.vscode/task.json b/.vscode/task.json new file mode 100644 index 00000000000..779ec0d855d --- /dev/null +++ b/.vscode/task.json @@ -0,0 +1,6 @@ +{ + "version": "0.1.0", + "command": "./node_modules/.bin/tsc", + "args": ["-v"], + "echoCommand": true +} From b7354aea9f593ba78ec3530bb8f6ab75f3392f36 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Sat, 21 Dec 2024 11:25:29 -0800 Subject: [PATCH 569/730] Style tweaks --- packages/headers/src/lib/super-headers.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index d0f7729faeb..b41ea47e2bf 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -241,7 +241,7 @@ export class SuperHeaders extends Headers { * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Headers/getSetCookie) */ getSetCookie(): string[] { - return this.#setCookies.map((value) => (typeof value === 'string' ? value : value.toString())); + return this.#setCookies.map((v) => (typeof v === 'string' ? v : v.toString())); } /** @@ -251,11 +251,7 @@ export class SuperHeaders extends Headers { */ has(name: string): boolean { let key = name.toLowerCase(); - if (key === SetCookieKey) { - return this.#setCookies.length > 0; - } else { - return this.#map.has(key); - } + return key === SetCookieKey ? this.#setCookies.length > 0 : this.#map.has(key); } /** From e12adf5b0ce69fded96b5eb1bad1f3c880891569 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Tue, 7 Jan 2025 08:17:40 -0800 Subject: [PATCH 570/730] Handle zero-length files in tar parsing --- packages/tar-parser/CHANGELOG.md | 8 ++ packages/tar-parser/src/lib/tar.test.ts | 111 ++++++++++++------ packages/tar-parser/src/lib/tar.ts | 10 +- .../tar-parser/test/fixtures/npm-11.0.0.tgz | Bin 0 -> 2744723 bytes packages/tar-parser/test/utils.ts | 1 + 5 files changed, 92 insertions(+), 38 deletions(-) create mode 100644 packages/tar-parser/test/fixtures/npm-11.0.0.tgz diff --git a/packages/tar-parser/CHANGELOG.md b/packages/tar-parser/CHANGELOG.md index 836c7c0bb18..ae4cc1e4980 100644 --- a/packages/tar-parser/CHANGELOG.md +++ b/packages/tar-parser/CHANGELOG.md @@ -1,3 +1,11 @@ +# `tar-parser` CHANGELOG + +This is the changelog for [`tar-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/tar-parser). It follows [semantic versioning](https://semver.org/). + +## HEAD + +- Fixed a bug that hangs the process when trying to read zero-length entries. + ## v0.1.0 (2024-12-06) - Initial release diff --git a/packages/tar-parser/src/lib/tar.test.ts b/packages/tar-parser/src/lib/tar.test.ts index 46c0df81dac..0c3b8933dd1 100644 --- a/packages/tar-parser/src/lib/tar.test.ts +++ b/packages/tar-parser/src/lib/tar.test.ts @@ -5,7 +5,33 @@ import { fixtures, readFixture } from '../../test/utils.ts'; import { type TarHeader, parseTar } from './tar.ts'; -async function bufferStream( +async function bufferBytes(stream: ReadableStream<Uint8Array>): Promise<Uint8Array> { + let chunks: Uint8Array[] = []; + let length = 0; + + for await (let chunk of stream) { + chunks.push(chunk); + length += chunk.byteLength; + } + + let result = new Uint8Array(length); + let offset = 0; + + for (let chunk of chunks) { + result.set(chunk, offset); + offset += chunk.byteLength; + } + + return result; +} + +async function computeChecksum(buffer: Uint8Array, algorithm = 'SHA-256'): Promise<string> { + let digest = await crypto.subtle.digest(algorithm, buffer); + let hash = btoa(String.fromCharCode(...new Uint8Array(digest))); + return hash; +} + +async function bufferString( stream: ReadableStream<Uint8Array>, encoding = 'utf-8', ): Promise<string> { @@ -23,55 +49,68 @@ async function bufferStream( describe('TarParser', () => { it('parses express-4.21.1.tgz', async () => { - let entries: [string, number][] = []; - await parseTar(readFixture(fixtures.expressNpmPackage), (entry) => { - entries.push([entry.name, entry.size]); + let entries: [string, number, string][] = []; + await parseTar(readFixture(fixtures.expressNpmPackage), async (entry) => { + let checksum = await computeChecksum(await bufferBytes(entry.body)); + entries.push([entry.name, entry.size, checksum]); }); assert.deepEqual(entries, [ - ['package/LICENSE', 1249], - ['package/lib/application.js', 14593], - ['package/lib/express.js', 2409], - ['package/index.js', 224], - ['package/lib/router/index.js', 15123], - ['package/lib/middleware/init.js', 853], - ['package/lib/router/layer.js', 3296], - ['package/lib/middleware/query.js', 885], - ['package/lib/request.js', 12505], - ['package/lib/response.js', 28729], - ['package/lib/router/route.js', 4399], - ['package/lib/utils.js', 5871], - ['package/lib/view.js', 3325], - ['package/package.json', 2708], - ['package/History.md', 114974], - ['package/Readme.md', 9806], + ['package/LICENSE', 1249, 'laV2KJDlwcmAiSHO8JVmH8SCxeHwu6MURqyFWV32I3w='], + ['package/lib/application.js', 14593, 'WQGzL2Cbo0k1G/dAbb3AxMV7d85vchXqZ8zKWsKijog='], + ['package/lib/express.js', 2409, 'LyVYXAPDBQd5yPXwBZf4ZT9PuKl0SO+O+Msh5luk0V0='], + ['package/index.js', 224, 'TS9a/BkheMWw3EGNLaWCbVKotpmHcbARrt5/26kRgUA='], + ['package/lib/router/index.js', 15123, 'GcXKmwJTlmEtvkZNB/vnEE/5FwxNahx+VQffTbv01cs='], + ['package/lib/middleware/init.js', 853, 'SMHRLxSUsgN3/N7skFYnLv+E7YwIHh5W3CrqOV930Zw='], + ['package/lib/router/layer.js', 3296, 'yQcJ3LqNmmz9HytO9teiLYM+MX8Mh22IQ0LO5alvigI='], + ['package/lib/middleware/query.js', 885, 'btzjljWItC5BlCkAskIY5mW5ffDAscdAkLK5NPpoygg='], + ['package/lib/request.js', 12505, 'ZKwQdSwFFteJywaYu0M1htTOO0b38G7jyyiAdiuL2kA='], + ['package/lib/response.js', 28729, 'S1wzjLZutTsH75ALrPTNUg8FeuU5lkAihvQzTgKAbVY='], + ['package/lib/router/route.js', 4399, 'htsSNXCBWmPcI6qI1z4bPc6QhpKsLjzyD6NQ1p3mMzc='], + ['package/lib/utils.js', 5871, 'kDXG2Ubs5RHnSQQ8yCPjLT7+Zye4qdUqrIlknplYTwk='], + ['package/lib/view.js', 3325, '7GJ4gMG0Ou5YhxZKwunFjwHk7oCG4jqCnt3xrzhYwCE='], + ['package/package.json', 2708, 'd06qwvupH1v8/UepkcjZjQ3nuntgVxdzEnenxQpXGv4='], + ['package/History.md', 114974, 'yiVzE+b51p5Ysuzx296S1oFIRkiXo2JfoJtdSMrO7f0='], + ['package/Readme.md', 9806, 'AW80TvZrgbvgPIUW5UFJgiRFmf7GQB8PzBzLESEj03A='], ]); }); it('parses fetch-proxy-0.1.0.tar.gz', async () => { - let entries: [string, number][] = []; - await parseTar(readFixture(fixtures.fetchProxyGithubArchive), (entry) => { - entries.push([entry.name, entry.size]); + let entries: [string, number, string][] = []; + await parseTar(readFixture(fixtures.fetchProxyGithubArchive), async (entry) => { + let checksum = await computeChecksum(await bufferBytes(entry.body)); + entries.push([entry.name, entry.size, checksum]); }); assert.equal(entries.length, 192); }); it('parses lodash-4.17.21.tgz', async () => { - let entries: [string, number][] = []; - await parseTar(readFixture(fixtures.lodashNpmPackage), (entry) => { - entries.push([entry.name, entry.size]); + let entries: [string, number, string][] = []; + await parseTar(readFixture(fixtures.lodashNpmPackage), async (entry) => { + let checksum = await computeChecksum(await bufferBytes(entry.body)); + entries.push([entry.name, entry.size, checksum]); }); assert.equal(entries.length, 1054); }); + + it('parses npm-11.0.0.tgz', async () => { + let entries: [string, number, string][] = []; + await parseTar(readFixture(fixtures.npmNpmPackage), async (entry) => { + let checksum = await computeChecksum(await bufferBytes(entry.body)); + entries.push([entry.name, entry.size, checksum]); + }); + + assert.equal(entries.length, 2368); + }); }); describe('tar-stream test cases', () => { it('parses one-file.tar', async () => { let entries: [TarHeader, string][] = []; await parseTar(readFixture(fixtures.oneFile), async (entry) => { - entries.push([entry.header, await bufferStream(entry.body)]); + entries.push([entry.header, await bufferString(entry.body)]); }); assert.deepEqual(entries, [ @@ -99,7 +138,7 @@ describe('tar-stream test cases', () => { it('parses multi-file.tar', async () => { let entries: [TarHeader, string][] = []; await parseTar(readFixture(fixtures.multiFile), async (entry) => { - entries.push([entry.header, await bufferStream(entry.body)]); + entries.push([entry.header, await bufferString(entry.body)]); }); assert.deepEqual(entries, [ @@ -145,7 +184,7 @@ describe('tar-stream test cases', () => { it('parses pax.tar', async () => { let entries: [TarHeader, string][] = []; await parseTar(readFixture(fixtures.pax), async (entry) => { - entries.push([entry.header, await bufferStream(entry.body)]); + entries.push([entry.header, await bufferString(entry.body)]); }); assert.deepEqual(entries, [ @@ -216,7 +255,7 @@ describe('tar-stream test cases', () => { it('parses long-name.tar', async () => { let entries: [TarHeader, string][] = []; await parseTar(readFixture(fixtures.longName), async (entry) => { - entries.push([entry.header, await bufferStream(entry.body)]); + entries.push([entry.header, await bufferString(entry.body)]); }); assert.deepEqual(entries, [ @@ -301,7 +340,7 @@ describe('tar-stream test cases', () => { it('parses name-is-100.tar', async () => { let entries: [number, string][] = []; await parseTar(readFixture(fixtures.nameIs100), async (entry) => { - entries.push([entry.header.name.length, await bufferStream(entry.body)]); + entries.push([entry.header.name.length, await bufferString(entry.body)]); }); assert.deepEqual(entries, [[100, 'hello\n']]); @@ -310,7 +349,7 @@ describe('tar-stream test cases', () => { it('parses space.tar', async () => { let entries: [TarHeader, string][] = []; await parseTar(readFixture(fixtures.space), async (entry) => { - entries.push([entry.header, await bufferStream(entry.body)]); + entries.push([entry.header, await bufferString(entry.body)]); }); assert.equal(entries.length, 4); @@ -319,7 +358,7 @@ describe('tar-stream test cases', () => { it('parses gnu-long-path.tar', async () => { let entries: [TarHeader, string][] = []; await parseTar(readFixture(fixtures.gnuLongPath), async (entry) => { - entries.push([entry.header, await bufferStream(entry.body)]); + entries.push([entry.header, await bufferString(entry.body)]); }); assert.equal(entries.length, 1); @@ -364,7 +403,7 @@ describe('tar-stream test cases', () => { it('parses latin1.tar', async () => { let entries: [TarHeader, string][] = []; await parseTar(readFixture(fixtures.latin1), { filenameEncoding: 'latin1' }, async (entry) => { - entries.push([entry.header, await bufferStream(entry.body)]); + entries.push([entry.header, await bufferString(entry.body)]); }); assert.deepEqual(entries, [ @@ -404,7 +443,7 @@ describe('tar-stream test cases', () => { it('parses gnu.tar', async () => { let entries: [TarHeader, string][] = []; await parseTar(readFixture(fixtures.gnu), async (entry) => { - entries.push([entry.header, await bufferStream(entry.body)]); + entries.push([entry.header, await bufferString(entry.body)]); }); assert.deepEqual(entries, [ @@ -432,7 +471,7 @@ describe('tar-stream test cases', () => { it('parses gnu-incremental.tar', async () => { let entries: [TarHeader, string][] = []; await parseTar(readFixture(fixtures.gnuIncremental), async (entry) => { - entries.push([entry.header, await bufferStream(entry.body)]); + entries.push([entry.header, await bufferString(entry.body)]); }); assert.deepEqual(entries, [ diff --git a/packages/tar-parser/src/lib/tar.ts b/packages/tar-parser/src/lib/tar.ts index 7f03c88eedc..6acc0579962 100644 --- a/packages/tar-parser/src/lib/tar.ts +++ b/packages/tar-parser/src/lib/tar.ts @@ -343,13 +343,19 @@ export class TarParser { } if (this.#header.size === 0 || this.#header.type === 'directory') { - handler(new TarEntry(this.#header, new ReadableStream<Uint8Array>())); + let emptyBody = new ReadableStream({ + start(controller) { + controller.close(); + }, + }); + + handler(new TarEntry(this.#header, emptyBody)); this.#bodyController = null; this.#missing = 0; return; } - let body = new ReadableStream<Uint8Array>({ + let body = new ReadableStream({ start: (controller) => { this.#bodyController = controller; }, diff --git a/packages/tar-parser/test/fixtures/npm-11.0.0.tgz b/packages/tar-parser/test/fixtures/npm-11.0.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..312a13398f26c2f65f0c94039427b1af9cb31042 GIT binary patch literal 2744723 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 s1AkDv5ey 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�+oG#LfSN-k%(?uHHyl;-!rFL`*yo>?X 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Ɗdt9Q@b)I%RqIVPk`zkQB%A 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�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%0Dpln-Yl8Z;Ami@3B4Ih9zT=u#EBQm}d7rWG9GA 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�}6(TsEpNqXHPSoeP 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Μ3KvJ)AWnHO4)irw0&BrWV`Z25bi+!0Sq@bftc81 zF!q5phEOI_TMM=IGMZa^;bNBh*|I584ZZYl4_$Ogm-^XSO0j&@3TP3)ErO#k3{|YT zi|Q=tnE~nQ9CyI0<mlK(ZBOo8U107Duy6^hBa8Kc8n+iGYB%+;cog7=UNb9L)+RD^ z@{m9wcn8`GN-h<$OfKq4aOaBpqAT!I8%&EFRQelT0xYmeka2yXBNTme@@Tm$>&*va z<T^6Gu3eCCq(qZ76Pg;iGU+S~+&pf5OeNB`4lW-4g-evGQ<c}(Vr?x~6iG><XbUL! zMn$eRx?aw-6Xb{%9aWM3)bOa!1}zElP@LsO*)?u7Z>^Y9Xx=2xuC0590cx(PbOC!2 zmAq?7!PE>5$bB4%Z2rm+)M@HxoMM+~26nryT%e9QuGS*B6xBi>UC-V{-O<`wUL8#6 z3je5I85$q#4@U0oY&HpUlr7pmXjeLM3H<0XwVng`CI8g(3`6koDcJ%<mlabJ^AU10 z)jYu$+?pu%t*D+pEncq2kXI%dj;{^tkhXz)nUj=f22sAQJn4&OSxob)m0d<zi8)sk zOtw#Cx0XJ=I@4=4e6UwZb-DWd%=R~)o;CP&^E^6Ub*B2BM09}HYLpsB=ORko6H;-y zP5=w05XVd%Vj!K_DII3}OKoy+R(xBhj*5&1)vdymo9EzpBFaC|S&;tEf0(1NI*QyL zhJTI2V8lPP&O$!@1DpeSz5k)^1O?MqJO+x3`9mE80_xxD7}U0Ig*zdimVb;pL7#;` z&Yf^m6uCVN{~Cv(=}rLusD^_;@3E!F!E*p&p7Ig|Fru_xO`mZ*)C=wl?~1Rsix@0h zS+nZ0YoQuOnPGo{%Zd^!Sb7_{uZJcQA@mB~gggRVOX%Yt2ra&ZZ2pn40^=zE52A)c zER<I1HK-aN7GojzjzkYKDhe5rIGUxQk>VMX3)AN`&y)xw$$aV4WNX#GtZ`JeGjcwA zbuld`A1`#|MoV%PFKsy<rqMlx)Mqk#?SMg)o@($~F4on+@X6m~hXD<}^qGk3VlIIZ zIo+64!%eVklYMDz<>D)O)jkTGhp@j=4L9s`oQu=9DmvfC%_d)`_g{PV2K8HE`i@x7 zuT-py5^edrS~#ocl^4+$^bfj1zZvLp_p{at+M+ab*<!8X3DT0uYnClEoZGIMnX)y2 zn`Y=g-i8)ct{h69EhR$@QPN!1vKsk7pcJ)O$0Iw|xkzMqz6wN&f+T)T%Cn%I<-JM@ ztt%_Cb&}=1J6BcH#mR9UwLO)Vp?IBq*SAeh%fD@ldO~T_tj|(H{30zU_E;cY9F4V- zW)<zK`jblN?{8vg1=_o<{@uGRc9%WIm~u2ek0GxjsQIq`0?D%&7~m`_10jmVnaUZ? z3N-eBPVfXKGQcP0GH2{97#<~p0_u->DIkqC9^^6~V@|HH1;m=7+M#g|t^4=X{~?!{ z^F3mb<XOJYO%CS!QNq(0)MZB!dB5k`MfK}-!AHqQ`8V2*zRm>#8l|d>8K^GJ-!G!# zJkBq(-RerEL}h_#JY0*2`h8Vu!B|yr0jO$*wW2kZkJ;@6_3N!#H0STN<9+5TnD?~_ z50nk+^*uw-!WjTMiz&@_f8{z3>nJ&85lfS@1Y-qd$xAj->18w*ltdTeKGOY85&WeE zuZjSRryKGwgS+lobb(PNGDdk&C8r>GiRi^M#-rhxL^(1Vj^bFftXQasAB5k6ouD;b zMCkVC$Lt4o#Yn+RccWm7pHH0C(AdcKm^5soY{VGct>Z2pA?vcb%0A>SwY&?uWy;iH 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 )apgTMorp=bt<a_biEZltt$q# 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%0AjKZ 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≠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 oH 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%0Dv<7%b8BNUY0>23G65hnSH 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%0A`9g#ZVCmK7n($f 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�~xPIiT8g58!hx<c_Ff`AjZ(LVyNd|r5N+Lc2UCX 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%0DPi!R@2J3Pj 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 EbyRT{SZqxEWbbs)$-vG7|B$FzZ&z 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%0D4TuAlEyY!nz1gyf^6TaQIE|qzark7Rx99>{l-&< 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∓{gMqJdjz4!7s;_Q@{ipL`5ln)1GYkL|u~vlkhBi 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 literal 0 HcmV?d00001 diff --git a/packages/tar-parser/test/utils.ts b/packages/tar-parser/test/utils.ts index 135fe77a7a7..a5ec7141181 100644 --- a/packages/tar-parser/test/utils.ts +++ b/packages/tar-parser/test/utils.ts @@ -17,6 +17,7 @@ export const fixtures = { lodashNpmPackage: path.resolve(fixturesDir, 'lodash-4.17.21.tgz'), longName: path.resolve(fixturesDir, 'long-name.tar'), multiFile: path.resolve(fixturesDir, 'multi-file.tar'), + npmNpmPackage: path.resolve(fixturesDir, 'npm-11.0.0.tgz'), nameIs100: path.resolve(fixturesDir, 'name-is-100.tar'), oneFile: path.resolve(fixturesDir, 'one-file.tar'), pax: path.resolve(fixturesDir, 'pax.tar'), From 3aeb60b02673fa6c59510961c86e4c52ffa425d0 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Tue, 7 Jan 2025 08:44:02 -0800 Subject: [PATCH 571/730] Release tar-parser@0.2.0 --- packages/tar-parser/CHANGELOG.md | 2 +- packages/tar-parser/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/tar-parser/CHANGELOG.md b/packages/tar-parser/CHANGELOG.md index ae4cc1e4980..5f2fdab1b3f 100644 --- a/packages/tar-parser/CHANGELOG.md +++ b/packages/tar-parser/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`tar-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/tar-parser). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.2.0 (2025-01-07) - Fixed a bug that hangs the process when trying to read zero-length entries. diff --git a/packages/tar-parser/package.json b/packages/tar-parser/package.json index 16aad2addd2..82a242c7976 100644 --- a/packages/tar-parser/package.json +++ b/packages/tar-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/tar-parser", - "version": "0.1.0", + "version": "0.2.0", "description": "A fast, efficient parser for tar streams in any JavaScript environment", "author": "Michael Jackson <mjijackson@gmail.com>", "license": "MIT", From df634097055f4b5288d09adfbbba5774181f888b Mon Sep 17 00:00:00 2001 From: Ryan Florence <rpflorence@gmail.com> Date: Tue, 7 Jan 2025 15:45:08 -0700 Subject: [PATCH 572/730] failing test --- .../src/lib/local-file-storage.test.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/file-storage/src/lib/local-file-storage.test.ts b/packages/file-storage/src/lib/local-file-storage.test.ts index 2d5dfd250cc..335fa396e51 100644 --- a/packages/file-storage/src/lib/local-file-storage.test.ts +++ b/packages/file-storage/src/lib/local-file-storage.test.ts @@ -43,4 +43,31 @@ describe('LocalFileStorage', () => { assert.ok(!(await storage.has('hello'))); assert.equal(await storage.get('hello'), null); }); + + it('handles race conditions', async () => { + let storage = new LocalFileStorage(directory); + let lastModified = Date.now(); + + let file1 = new File(['Hello, world!'], 'hello1.txt', { + type: 'text/plain', + lastModified, + }); + + let file2 = new File(['Hello, universe!'], 'hello2.txt', { + type: 'text/plain', + lastModified, + }); + + let setPromise = storage.set('one', file1); + await storage.set('two', file2); + + let retrieved1 = await storage.get('one'); + assert.ok(retrieved1); + assert.equal(await retrieved1.text(), 'Hello, world!'); + + await setPromise; + let retrieved2 = await storage.get('two'); + assert.ok(retrieved2); + assert.equal(await retrieved2.text(), 'Hello, universe!'); + }); }); From ac933a64903cbe9086a4ff1177b097082268532c Mon Sep 17 00:00:00 2001 From: Ryan Florence <rpflorence@gmail.com> Date: Tue, 7 Jan 2025 17:20:27 -0700 Subject: [PATCH 573/730] local-file-storage: scalability + race fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit fixes race conditions and potential performance issues ## Race conditions: - Multiple calls to `set` caused race conditions with the central metafile index. - Not only did this cause the set to fail, but it often corrupted the metafile causing a permanent, unrecoverable error since the metafile could no longer be parsed. ## Scalability: - The single metadata file would eventually grow large in a successful application and become both a memory issue and performance bottleneck - Additionally, storing all files in a single directory would eventually slow down the file system’s access of files in the directory. ## Changes: - Removes race conditions with atomic reads/writes - Removes the metafile and instead relies on SHA-256 hashes for file keys - Stores metadata alongside each file as .meta.json instead of central index - removes filename collision handling since it’s unnecessary with hash-based names - Performance - Shards files into subdirectories using first 8 chars of SHA-256 hash to maintain file system performance - Without a metafile, it is no longer a memory or performance bottleneck Should rebase/squash the commits before merging, added the failing test first to prove the bug. --- packages/file-storage/CHANGELOG.md | 5 + .../src/lib/local-file-storage.ts | 141 ++++++------------ 2 files changed, 54 insertions(+), 92 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index c35157d499b..8d08bc224b8 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -2,6 +2,11 @@ This is the changelog for [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage). It follows [semantic versioning](https://semver.org/). +## v0.3.1 + +- Fixes race conditions with concurrent calls to `set` +- Shards storage directories for more scalable file systems + ## v0.3.0 (2024-11-14) - Added CommonJS build diff --git a/packages/file-storage/src/lib/local-file-storage.ts b/packages/file-storage/src/lib/local-file-storage.ts index de4203c469a..f6708f6bed9 100644 --- a/packages/file-storage/src/lib/local-file-storage.ts +++ b/packages/file-storage/src/lib/local-file-storage.ts @@ -2,6 +2,7 @@ import * as fs from 'node:fs'; import * as fsp from 'node:fs/promises'; import * as path from 'node:path'; import { openFile, writeFile } from '@mjackson/lazy-file/fs'; +import * as crypto from 'node:crypto'; import { type FileStorage } from './file-storage.ts'; @@ -15,7 +16,6 @@ import { type FileStorage } from './file-storage.ts'; */ export class LocalFileStorage implements FileStorage { #dirname: string; - #metadata: FileMetadataIndex; /** * @param directory The directory where files are stored @@ -36,132 +36,89 @@ export class LocalFileStorage implements FileStorage { fs.mkdirSync(this.#dirname, { recursive: true }); } - - this.#metadata = new FileMetadataIndex(path.join(directory, '.metadata.json')); } - has(key: string): Promise<boolean> { - return this.#metadata.has(key); + async has(key: string): Promise<boolean> { + let { metaPath } = this.#getFilePaths(key); + try { + await fsp.access(metaPath); + return true; + } catch { + return false; + } } async set(key: string, file: File): Promise<void> { // Remove any existing file with the same key. await this.remove(key); - let storedFile = await storeFile(this.#dirname, file); + let { directory, filePath, metaPath } = this.#getFilePaths(key); + + // Ensure directory exists + await fsp.mkdir(directory, { recursive: true }); + + let handle = await fsp.open(filePath, 'w'); + await writeFile(handle, file); - await this.#metadata.set(key, { - file: storedFile, + let metadata: FileMetadata = { name: file.name, type: file.type, mtime: file.lastModified, - }); + }; + await fsp.writeFile(metaPath, JSON.stringify(metadata)); } async get(key: string): Promise<File | null> { - let metadata = await this.#metadata.get(key); - if (metadata == null) return null; - - let filename = path.join(this.#dirname, metadata.file); - - return openFile(filename, { - name: metadata.name, - type: metadata.type, - lastModified: metadata.mtime, - }); - } - - async remove(key: string): Promise<void> { - let metadata = await this.#metadata.get(key); - if (metadata == null) return; - - let filename = path.join(this.#dirname, metadata.file); + let { filePath, metaPath } = this.#getFilePaths(key); try { - await fsp.unlink(filename); + let metadataContent = await fsp.readFile(metaPath, 'utf-8'); + let metadata: FileMetadata = JSON.parse(metadataContent); + + return openFile(filePath, { + name: metadata.name, + type: metadata.type, + lastModified: metadata.mtime, + }); } catch (error) { if (!isNoEntityError(error)) { throw error; } - } - - await this.#metadata.remove(key); - } -} - -async function storeFile(dirname: string, file: File): Promise<string> { - let filename = randomFilename(); - - let handle: fsp.FileHandle; - try { - handle = await fsp.open(path.join(dirname, filename), 'w'); - } catch (error) { - if ((error as NodeJS.ErrnoException).code === 'EEXIST') { - // Try again with a different filename - return storeFile(dirname, file); - } else { - throw error; + return null; } } - await writeFile(handle, file); - - return filename; -} - -function randomFilename(): string { - return `${new Date().getTime().toString(36)}.${Math.random().toString(36).slice(2, 6)}`; -} - -interface FileMetadata { - file: string; - name: string; - type: string; - mtime: number; -} - -class FileMetadataIndex { - #path: string; - - constructor(path: string) { - this.#path = path; - } + async remove(key: string): Promise<void> { + let { filePath, metaPath } = this.#getFilePaths(key); - async #getAll(): Promise<Record<string, FileMetadata>> { try { - return JSON.parse(await openFile(this.#path).text()); + await Promise.all([fsp.unlink(filePath), fsp.unlink(metaPath)]); } catch (error) { if (!isNoEntityError(error)) { throw error; } - - return {}; } } - async #save(info: Record<string, FileMetadata | undefined>): Promise<void> { - await fsp.writeFile(this.#path, JSON.stringify(info)); - } - - async has(key: string): Promise<boolean> { - let info = await this.#getAll(); - return key in info; - } - - async set(key: string, metadata: FileMetadata): Promise<void> { - let info = await this.#getAll(); - await this.#save({ ...info, [key]: metadata }); - } - - async get(key: string): Promise<FileMetadata | null> { - let info = await this.#getAll(); - return info[key] ?? null; + #getFilePaths(key: string): { directory: string; filePath: string; metaPath: string } { + let hash = crypto.createHash('sha256').update(key).digest('hex'); + let shardDir = hash.slice(0, 8); + let directory = path.join(this.#dirname, shardDir); + let filename = `${hash}.bin`; + let metaname = `${hash}.meta.json`; + + return { + directory, + filePath: path.join(directory, filename), + metaPath: path.join(directory, metaname), + }; } +} - async remove(key: string): Promise<void> { - let info = await this.#getAll(); - await this.#save({ ...info, [key]: undefined }); - } +interface FileMetadata { + name: string; + type: string; + mtime: number; } function isNoEntityError(obj: unknown): obj is NodeJS.ErrnoException & { code: 'ENOENT' } { From 858c8ba49a41797db9645b342e0d6aa1373b77b4 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Tue, 7 Jan 2025 16:58:25 -0800 Subject: [PATCH 574/730] Use web crypto API instead of node:crypto --- packages/file-storage/CHANGELOG.md | 2 +- .../src/lib/local-file-storage.ts | 35 +++++++++++-------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 8d08bc224b8..206c2573e65 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage). It follows [semantic versioning](https://semver.org/). -## v0.3.1 +## HEAD - Fixes race conditions with concurrent calls to `set` - Shards storage directories for more scalable file systems diff --git a/packages/file-storage/src/lib/local-file-storage.ts b/packages/file-storage/src/lib/local-file-storage.ts index f6708f6bed9..87fc3a48b3b 100644 --- a/packages/file-storage/src/lib/local-file-storage.ts +++ b/packages/file-storage/src/lib/local-file-storage.ts @@ -2,10 +2,15 @@ import * as fs from 'node:fs'; import * as fsp from 'node:fs/promises'; import * as path from 'node:path'; import { openFile, writeFile } from '@mjackson/lazy-file/fs'; -import * as crypto from 'node:crypto'; import { type FileStorage } from './file-storage.ts'; +interface FileMetadata { + name: string; + type: string; + mtime: number; +} + /** * A `FileStorage` that is backed by the local filesystem. * @@ -39,7 +44,8 @@ export class LocalFileStorage implements FileStorage { } async has(key: string): Promise<boolean> { - let { metaPath } = this.#getFilePaths(key); + let { metaPath } = await this.#getPaths(key); + try { await fsp.access(metaPath); return true; @@ -52,13 +58,12 @@ export class LocalFileStorage implements FileStorage { // Remove any existing file with the same key. await this.remove(key); - let { directory, filePath, metaPath } = this.#getFilePaths(key); + let { directory, filePath, metaPath } = await this.#getPaths(key); // Ensure directory exists await fsp.mkdir(directory, { recursive: true }); - let handle = await fsp.open(filePath, 'w'); - await writeFile(handle, file); + await writeFile(filePath, file); let metadata: FileMetadata = { name: file.name, @@ -69,7 +74,7 @@ export class LocalFileStorage implements FileStorage { } async get(key: string): Promise<File | null> { - let { filePath, metaPath } = this.#getFilePaths(key); + let { filePath, metaPath } = await this.#getPaths(key); try { let metadataContent = await fsp.readFile(metaPath, 'utf-8'); @@ -84,12 +89,13 @@ export class LocalFileStorage implements FileStorage { if (!isNoEntityError(error)) { throw error; } + return null; } } async remove(key: string): Promise<void> { - let { filePath, metaPath } = this.#getFilePaths(key); + let { filePath, metaPath } = await this.#getPaths(key); try { await Promise.all([fsp.unlink(filePath), fsp.unlink(metaPath)]); @@ -100,11 +106,11 @@ export class LocalFileStorage implements FileStorage { } } - #getFilePaths(key: string): { directory: string; filePath: string; metaPath: string } { - let hash = crypto.createHash('sha256').update(key).digest('hex'); + async #getPaths(key: string): Promise<{ directory: string; filePath: string; metaPath: string }> { + let hash = await computeHash(key); let shardDir = hash.slice(0, 8); let directory = path.join(this.#dirname, shardDir); - let filename = `${hash}.bin`; + let filename = `${hash.slice(8)}.bin`; let metaname = `${hash}.meta.json`; return { @@ -115,10 +121,11 @@ export class LocalFileStorage implements FileStorage { } } -interface FileMetadata { - name: string; - type: string; - mtime: number; +async function computeHash(key: string, algorithm = 'SHA-256'): Promise<string> { + let digest = await crypto.subtle.digest(algorithm, new TextEncoder().encode(key)); + return Array.from(new Uint8Array(digest)) + .map((b) => b.toString(16).padStart(2, '0')) + .join(''); } function isNoEntityError(obj: unknown): obj is NodeJS.ErrnoException & { code: 'ENOENT' } { From 3ef1fdd0f5d4a2cbb2110ae8986376d6036717c0 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Tue, 7 Jan 2025 17:41:55 -0800 Subject: [PATCH 575/730] Fix hash format in test --- packages/tar-parser/src/lib/tar.test.ts | 48 +++++++++++++------------ 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/packages/tar-parser/src/lib/tar.test.ts b/packages/tar-parser/src/lib/tar.test.ts index 0c3b8933dd1..928d7733991 100644 --- a/packages/tar-parser/src/lib/tar.test.ts +++ b/packages/tar-parser/src/lib/tar.test.ts @@ -25,10 +25,12 @@ async function bufferBytes(stream: ReadableStream<Uint8Array>): Promise<Uint8Arr return result; } -async function computeChecksum(buffer: Uint8Array, algorithm = 'SHA-256'): Promise<string> { +async function computeHash(buffer: Uint8Array, algorithm = 'SHA-256'): Promise<string> { let digest = await crypto.subtle.digest(algorithm, buffer); - let hash = btoa(String.fromCharCode(...new Uint8Array(digest))); - return hash; + return Array.from(new Uint8Array(digest)) + .map((byte) => byte.toString(16).padStart(2, '0')) + .join('') + .slice(0, 8); } async function bufferString( @@ -51,34 +53,34 @@ describe('TarParser', () => { it('parses express-4.21.1.tgz', async () => { let entries: [string, number, string][] = []; await parseTar(readFixture(fixtures.expressNpmPackage), async (entry) => { - let checksum = await computeChecksum(await bufferBytes(entry.body)); + let checksum = await computeHash(await bufferBytes(entry.body)); entries.push([entry.name, entry.size, checksum]); }); assert.deepEqual(entries, [ - ['package/LICENSE', 1249, 'laV2KJDlwcmAiSHO8JVmH8SCxeHwu6MURqyFWV32I3w='], - ['package/lib/application.js', 14593, 'WQGzL2Cbo0k1G/dAbb3AxMV7d85vchXqZ8zKWsKijog='], - ['package/lib/express.js', 2409, 'LyVYXAPDBQd5yPXwBZf4ZT9PuKl0SO+O+Msh5luk0V0='], - ['package/index.js', 224, 'TS9a/BkheMWw3EGNLaWCbVKotpmHcbARrt5/26kRgUA='], - ['package/lib/router/index.js', 15123, 'GcXKmwJTlmEtvkZNB/vnEE/5FwxNahx+VQffTbv01cs='], - ['package/lib/middleware/init.js', 853, 'SMHRLxSUsgN3/N7skFYnLv+E7YwIHh5W3CrqOV930Zw='], - ['package/lib/router/layer.js', 3296, 'yQcJ3LqNmmz9HytO9teiLYM+MX8Mh22IQ0LO5alvigI='], - ['package/lib/middleware/query.js', 885, 'btzjljWItC5BlCkAskIY5mW5ffDAscdAkLK5NPpoygg='], - ['package/lib/request.js', 12505, 'ZKwQdSwFFteJywaYu0M1htTOO0b38G7jyyiAdiuL2kA='], - ['package/lib/response.js', 28729, 'S1wzjLZutTsH75ALrPTNUg8FeuU5lkAihvQzTgKAbVY='], - ['package/lib/router/route.js', 4399, 'htsSNXCBWmPcI6qI1z4bPc6QhpKsLjzyD6NQ1p3mMzc='], - ['package/lib/utils.js', 5871, 'kDXG2Ubs5RHnSQQ8yCPjLT7+Zye4qdUqrIlknplYTwk='], - ['package/lib/view.js', 3325, '7GJ4gMG0Ou5YhxZKwunFjwHk7oCG4jqCnt3xrzhYwCE='], - ['package/package.json', 2708, 'd06qwvupH1v8/UepkcjZjQ3nuntgVxdzEnenxQpXGv4='], - ['package/History.md', 114974, 'yiVzE+b51p5Ysuzx296S1oFIRkiXo2JfoJtdSMrO7f0='], - ['package/Readme.md', 9806, 'AW80TvZrgbvgPIUW5UFJgiRFmf7GQB8PzBzLESEj03A='], + ['package/LICENSE', 1249, '95a57628'], + ['package/lib/application.js', 14593, '5901b32f'], + ['package/lib/express.js', 2409, '2f25585c'], + ['package/index.js', 224, '4d2f5afc'], + ['package/lib/router/index.js', 15123, '19c5ca9b'], + ['package/lib/middleware/init.js', 853, '48c1d12f'], + ['package/lib/router/layer.js', 3296, 'c90709dc'], + ['package/lib/middleware/query.js', 885, '6edce396'], + ['package/lib/request.js', 12505, '64ac1075'], + ['package/lib/response.js', 28729, '4b5c338c'], + ['package/lib/router/route.js', 4399, '86db1235'], + ['package/lib/utils.js', 5871, '9035c6d9'], + ['package/lib/view.js', 3325, 'ec627880'], + ['package/package.json', 2708, '774eaac2'], + ['package/History.md', 114974, 'ca257313'], + ['package/Readme.md', 9806, '016f344e'], ]); }); it('parses fetch-proxy-0.1.0.tar.gz', async () => { let entries: [string, number, string][] = []; await parseTar(readFixture(fixtures.fetchProxyGithubArchive), async (entry) => { - let checksum = await computeChecksum(await bufferBytes(entry.body)); + let checksum = await computeHash(await bufferBytes(entry.body)); entries.push([entry.name, entry.size, checksum]); }); @@ -88,7 +90,7 @@ describe('TarParser', () => { it('parses lodash-4.17.21.tgz', async () => { let entries: [string, number, string][] = []; await parseTar(readFixture(fixtures.lodashNpmPackage), async (entry) => { - let checksum = await computeChecksum(await bufferBytes(entry.body)); + let checksum = await computeHash(await bufferBytes(entry.body)); entries.push([entry.name, entry.size, checksum]); }); @@ -98,7 +100,7 @@ describe('TarParser', () => { it('parses npm-11.0.0.tgz', async () => { let entries: [string, number, string][] = []; await parseTar(readFixture(fixtures.npmNpmPackage), async (entry) => { - let checksum = await computeChecksum(await bufferBytes(entry.body)); + let checksum = await computeHash(await bufferBytes(entry.body)); entries.push([entry.name, entry.size, checksum]); }); From 927ab50ef97bbfb845bddebab6e628d16118c190 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Tue, 7 Jan 2025 17:55:20 -0800 Subject: [PATCH 576/730] Fix race condition in test --- packages/tar-parser/src/lib/tar.test.ts | 54 ++++++++++++------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/packages/tar-parser/src/lib/tar.test.ts b/packages/tar-parser/src/lib/tar.test.ts index 928d7733991..555aee8e9f5 100644 --- a/packages/tar-parser/src/lib/tar.test.ts +++ b/packages/tar-parser/src/lib/tar.test.ts @@ -51,37 +51,37 @@ async function bufferString( describe('TarParser', () => { it('parses express-4.21.1.tgz', async () => { - let entries: [string, number, string][] = []; + let entries: Record<string, string> = {}; await parseTar(readFixture(fixtures.expressNpmPackage), async (entry) => { - let checksum = await computeHash(await bufferBytes(entry.body)); - entries.push([entry.name, entry.size, checksum]); + let hash = await computeHash(await bufferBytes(entry.body)); + entries[entry.name] = hash; }); - assert.deepEqual(entries, [ - ['package/LICENSE', 1249, '95a57628'], - ['package/lib/application.js', 14593, '5901b32f'], - ['package/lib/express.js', 2409, '2f25585c'], - ['package/index.js', 224, '4d2f5afc'], - ['package/lib/router/index.js', 15123, '19c5ca9b'], - ['package/lib/middleware/init.js', 853, '48c1d12f'], - ['package/lib/router/layer.js', 3296, 'c90709dc'], - ['package/lib/middleware/query.js', 885, '6edce396'], - ['package/lib/request.js', 12505, '64ac1075'], - ['package/lib/response.js', 28729, '4b5c338c'], - ['package/lib/router/route.js', 4399, '86db1235'], - ['package/lib/utils.js', 5871, '9035c6d9'], - ['package/lib/view.js', 3325, 'ec627880'], - ['package/package.json', 2708, '774eaac2'], - ['package/History.md', 114974, 'ca257313'], - ['package/Readme.md', 9806, '016f344e'], - ]); + assert.deepEqual(entries, { + 'package/LICENSE': '95a57628', + 'package/lib/application.js': '5901b32f', + 'package/lib/express.js': '2f25585c', + 'package/index.js': '4d2f5afc', + 'package/lib/router/index.js': '19c5ca9b', + 'package/lib/middleware/init.js': '48c1d12f', + 'package/lib/router/layer.js': 'c90709dc', + 'package/lib/middleware/query.js': '6edce396', + 'package/lib/request.js': '64ac1075', + 'package/lib/response.js': '4b5c338c', + 'package/lib/router/route.js': '86db1235', + 'package/lib/utils.js': '9035c6d9', + 'package/lib/view.js': 'ec627880', + 'package/package.json': '774eaac2', + 'package/History.md': 'ca257313', + 'package/Readme.md': '016f344e', + }); }); it('parses fetch-proxy-0.1.0.tar.gz', async () => { let entries: [string, number, string][] = []; await parseTar(readFixture(fixtures.fetchProxyGithubArchive), async (entry) => { - let checksum = await computeHash(await bufferBytes(entry.body)); - entries.push([entry.name, entry.size, checksum]); + let hash = await computeHash(await bufferBytes(entry.body)); + entries.push([entry.name, entry.size, hash]); }); assert.equal(entries.length, 192); @@ -90,8 +90,8 @@ describe('TarParser', () => { it('parses lodash-4.17.21.tgz', async () => { let entries: [string, number, string][] = []; await parseTar(readFixture(fixtures.lodashNpmPackage), async (entry) => { - let checksum = await computeHash(await bufferBytes(entry.body)); - entries.push([entry.name, entry.size, checksum]); + let hash = await computeHash(await bufferBytes(entry.body)); + entries.push([entry.name, entry.size, hash]); }); assert.equal(entries.length, 1054); @@ -100,8 +100,8 @@ describe('TarParser', () => { it('parses npm-11.0.0.tgz', async () => { let entries: [string, number, string][] = []; await parseTar(readFixture(fixtures.npmNpmPackage), async (entry) => { - let checksum = await computeHash(await bufferBytes(entry.body)); - entries.push([entry.name, entry.size, checksum]); + let hash = await computeHash(await bufferBytes(entry.body)); + entries.push([entry.name, entry.size, hash]); }); assert.equal(entries.length, 2368); From f630c1e60703e8058195df29832c04096876e130 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Tue, 7 Jan 2025 17:56:43 -0800 Subject: [PATCH 577/730] Release file-storage@0.4.0 --- packages/file-storage/CHANGELOG.md | 2 +- packages/file-storage/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 206c2573e65..847a58ca6d7 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.4.0 (2025-01-08) - Fixes race conditions with concurrent calls to `set` - Shards storage directories for more scalable file systems diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index c299dbc4ed8..b068fc4e6ca 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/file-storage", - "version": "0.3.0", + "version": "0.4.0", "description": "Key/value storage for JavaScript File objects", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From 0ce86bf2138494cff2467ed722ddc0272dc86198 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 10 Jan 2025 13:56:12 -0800 Subject: [PATCH 578/730] Fix missing types --- packages/file-storage/CHANGELOG.md | 4 ++++ packages/file-storage/tsup.config.ts | 14 +++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 847a58ca6d7..86fde2424fa 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -2,6 +2,10 @@ This is the changelog for [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Fix missing types for `file-storage/local` in npm package + ## v0.4.0 (2025-01-08) - Fixes race conditions with concurrent calls to `set` diff --git a/packages/file-storage/tsup.config.ts b/packages/file-storage/tsup.config.ts index 79f2fb41489..d8116825f3f 100644 --- a/packages/file-storage/tsup.config.ts +++ b/packages/file-storage/tsup.config.ts @@ -1,20 +1,20 @@ import { defineConfig } from 'tsup'; export default defineConfig([ - // Platform-neutral build + // Node specific build { - clean: true, + clean: false, dts: true, - entry: ['src/file-storage.ts', 'src/memory.ts'], + entry: ['src/local.ts'], format: ['cjs', 'esm'], - platform: 'neutral', + platform: 'node', }, - // Node specific build + // Platform-neutral build { clean: false, dts: true, - entry: ['src/local.ts'], + entry: ['src/file-storage.ts', 'src/memory.ts'], format: ['cjs', 'esm'], - platform: 'node', + platform: 'neutral', }, ]); From c616c8dfd4620d00a83f68c8263ab3903875d0e3 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Fri, 10 Jan 2025 13:56:38 -0800 Subject: [PATCH 579/730] Release file-storage@0.4.1 --- packages/file-storage/CHANGELOG.md | 2 +- packages/file-storage/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 86fde2424fa..13522cc69fc 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.4.1 (2025-01-10) - Fix missing types for `file-storage/local` in npm package diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index b068fc4e6ca..8eef6a2422a 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/file-storage", - "version": "0.4.0", + "version": "0.4.1", "description": "Key/value storage for JavaScript File objects", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From 24e9b39ad28b20ad5ed7f86d899e2ae0bb9bf702 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 14 Jan 2025 19:39:08 -0800 Subject: [PATCH 580/730] Allow upload handlers to run in parallel Fixes #44 --- packages/form-data-parser/CHANGELOG.md | 4 +++ .../src/lib/form-data.test.ts | 36 +++++++++++++++---- .../form-data-parser/src/lib/form-data.ts | 25 +++++++++++-- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index 6f4063e7b73..f602506281a 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -2,6 +2,10 @@ This is the changelog for [`form-data-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Allow upload handlers to run in parallel. Fixes #44 + ## v0.5.1 (2024-12-12) - Fix dependency on `headers` in package.json diff --git a/packages/form-data-parser/src/lib/form-data.test.ts b/packages/form-data-parser/src/lib/form-data.test.ts index 85ef43cc183..551dfe21bcb 100644 --- a/packages/form-data-parser/src/lib/form-data.test.ts +++ b/packages/form-data-parser/src/lib/form-data.test.ts @@ -93,9 +93,7 @@ describe('parseFormData', () => { ].join('\r\n'), }); - let formData = await parseFormData(request, (fileUpload) => { - return null; - }); + let formData = await parseFormData(request, () => null); assert.equal(formData.get('file'), null); }); @@ -116,10 +114,36 @@ describe('parseFormData', () => { ].join('\r\n'), }); - let formData = await parseFormData(request, (fileUpload) => { - return fileUpload.text(); - }); + let formData = await parseFormData(request, (upload) => upload.text()); assert.equal(formData.get('file'), 'This is an example file.'); }); + + it('allows returning files from the upload handler', async () => { + let request = new Request('http://localhost:8080', { + method: 'POST', + headers: { + 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW', + }, + body: [ + '------WebKitFormBoundary7MA4YWxkTrZu0gW', + 'Content-Disposition: form-data; name="file"; filename="example.txt"', + 'Content-Type: text/plain', + '', + 'This is an example file.', + '------WebKitFormBoundary7MA4YWxkTrZu0gW--', + ].join('\r\n'), + }); + + let formData = await parseFormData(request, async (upload) => { + return new File([await upload.text()], 'example.txt', { type: 'text/plain' }); + }); + + let file = formData.get('file'); + + assert.ok(file instanceof File); + assert.equal(file.name, 'example.txt'); + assert.equal(file.type, 'text/plain'); + assert.equal(await file.text(), 'This is an example file.'); + }); }); diff --git a/packages/form-data-parser/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts index 902e98b4598..5f986f9eeeb 100644 --- a/packages/form-data-parser/src/lib/form-data.ts +++ b/packages/form-data-parser/src/lib/form-data.ts @@ -90,22 +90,41 @@ export async function parseFormData( ): Promise<FormData> { if (isMultipartRequest(request)) { let formData = new FormData(); + let promises: Promise<void | null | string | File>[] = []; for await (let part of parseMultipartRequest(request, parserOptions)) { if (!part.name) continue; if (part.isFile) { - let file = await uploadHandler(new FileUpload(part)); - if (file != null) { - formData.append(part.name, file); + let value = uploadHandler(new FileUpload(part)); + + if (value != null) { + if (isPromise(value)) { + let fieldName = part.name; + promises.push( + value.then((file) => { + if (file != null) { + formData.append(fieldName, file); + } + }), + ); + } else { + formData.append(part.name, value); + } } } else { formData.append(part.name, await part.text()); } } + await Promise.all(promises); + return formData; } return request.formData(); } + +function isPromise<T>(obj: unknown): obj is Promise<T> { + return obj != null && typeof (obj as any).then === 'function'; +} From 32b35e90387dc54211ae1350defb338ff249ef4e Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 14 Jan 2025 19:42:41 -0800 Subject: [PATCH 581/730] Release form-data-parser@0.6.0 --- packages/form-data-parser/CHANGELOG.md | 2 +- packages/form-data-parser/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index f602506281a..2cff852902c 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`form-data-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.6.0 (2025-01-15) - Allow upload handlers to run in parallel. Fixes #44 diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index 7700c12941f..169ca08ab2a 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/form-data-parser", - "version": "0.5.1", + "version": "0.6.0", "description": "A request.formData() wrapper with streaming file upload handling", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From eb26029f8e6f7ab054498649cd3b7f95d58b440a Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 14 Jan 2025 20:22:57 -0800 Subject: [PATCH 582/730] Style tweaks --- .../form-data-parser/src/lib/form-data.ts | 60 +++++++++---------- packages/tar-parser/src/lib/tar.test.ts | 16 ++--- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/packages/form-data-parser/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts index 5f986f9eeeb..c7b19379cc1 100644 --- a/packages/form-data-parser/src/lib/form-data.ts +++ b/packages/form-data-parser/src/lib/form-data.ts @@ -88,41 +88,41 @@ export async function parseFormData( uploadHandler: FileUploadHandler = defaultFileUploadHandler, parserOptions?: MultipartParserOptions, ): Promise<FormData> { - if (isMultipartRequest(request)) { - let formData = new FormData(); - let promises: Promise<void | null | string | File>[] = []; - - for await (let part of parseMultipartRequest(request, parserOptions)) { - if (!part.name) continue; - - if (part.isFile) { - let value = uploadHandler(new FileUpload(part)); - - if (value != null) { - if (isPromise(value)) { - let fieldName = part.name; - promises.push( - value.then((file) => { - if (file != null) { - formData.append(fieldName, file); - } - }), - ); - } else { - formData.append(part.name, value); - } + if (!isMultipartRequest(request)) { + return request.formData(); + } + + let formData = new FormData(); + let promises: Promise<void | null | string | File>[] = []; + + for await (let part of parseMultipartRequest(request, parserOptions)) { + if (!part.name) continue; + + if (part.isFile) { + let value = uploadHandler(new FileUpload(part)); + + if (value != null) { + if (isPromise(value)) { + let fieldName = part.name; + promises.push( + value.then((file) => { + if (file != null) { + formData.append(fieldName, file); + } + }), + ); + } else { + formData.append(part.name, value); } - } else { - formData.append(part.name, await part.text()); } + } else { + formData.append(part.name, await part.text()); } - - await Promise.all(promises); - - return formData; } - return request.formData(); + await Promise.all(promises); + + return formData; } function isPromise<T>(obj: unknown): obj is Promise<T> { diff --git a/packages/tar-parser/src/lib/tar.test.ts b/packages/tar-parser/src/lib/tar.test.ts index 555aee8e9f5..c8e7042251b 100644 --- a/packages/tar-parser/src/lib/tar.test.ts +++ b/packages/tar-parser/src/lib/tar.test.ts @@ -25,14 +25,6 @@ async function bufferBytes(stream: ReadableStream<Uint8Array>): Promise<Uint8Arr return result; } -async function computeHash(buffer: Uint8Array, algorithm = 'SHA-256'): Promise<string> { - let digest = await crypto.subtle.digest(algorithm, buffer); - return Array.from(new Uint8Array(digest)) - .map((byte) => byte.toString(16).padStart(2, '0')) - .join('') - .slice(0, 8); -} - async function bufferString( stream: ReadableStream<Uint8Array>, encoding = 'utf-8', @@ -49,6 +41,14 @@ async function bufferString( return string; } +async function computeHash(buffer: Uint8Array, algorithm = 'SHA-256'): Promise<string> { + let digest = await crypto.subtle.digest(algorithm, buffer); + return Array.from(new Uint8Array(digest)) + .map((byte) => byte.toString(16).padStart(2, '0')) + .join('') + .slice(0, 8); +} + describe('TarParser', () => { it('parses express-4.21.1.tgz', async () => { let entries: Record<string, string> = {}; From fd2a9967880f2d73228267fb6ba633afdbdc70a3 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 14 Jan 2025 20:27:09 -0800 Subject: [PATCH 583/730] Update README --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6497c724bcc..c063efda98f 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@ -This repository is a collection of packages for use with [Remix](https://remix.run) or any web framework you choose. +This is a collection of packages for use with [Remix](https://remix.run), or any web framework you choose. + +It is laying the foundation for the next major release of Remix. ## Philosophy -Each package in this repository has a [single responsibility](https://en.wikipedia.org/wiki/Single-responsibility_principle); it does one thing well. +Each package in this repository has a [single responsibility](https://en.wikipedia.org/wiki/Single-responsibility_principle). To maximize interoperability between packages, we build on web standards. Where standards are missing or incomplete, we augment them in unobtrusive ways to minimize the chance of incompatibility. -What exactly we mean by "web standards"? It means we use: +A few examples of web APIs that we use on the server include: - [The Web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) instead of Node.js streams - [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) instead of Node.js `Buffer`s From e52a782b6cb2dfdf05605c4d779f062714649419 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 16 Jan 2025 15:47:09 -0800 Subject: [PATCH 584/730] Small tweaks --- .../form-data-parser/src/lib/form-data.ts | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/form-data-parser/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts index c7b19379cc1..5b962980955 100644 --- a/packages/form-data-parser/src/lib/form-data.ts +++ b/packages/form-data-parser/src/lib/form-data.ts @@ -70,18 +70,19 @@ export interface FileUploadHandler { } async function defaultFileUploadHandler(file: FileUpload): Promise<File> { - // Do the slow thing and buffer the entire file in memory. + // Buffer the file in memory let buffer = await file.arrayBuffer(); return new File([buffer], file.name, { type: file.type, lastModified: file.lastModified }); } /** - * Parses a `Request` body into a `FormData` object. This is useful for accessing the data contained - * in a HTTP `POST` request generated by a HTML `<form>` element. + * Parses a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) body into a [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) + * object. This is useful when accessing the data contained in a HTTP `multipart/form-data` request + * generated by a HTML `<form>` element. * - * The major difference between this function and using the built-in `request.formData()` API is the - * ability to customize the handling of file uploads. Instead of buffering the entire file in memory, - * the `uploadHandler` allows you to store the file on disk or in a cloud storage service. + * The main difference between this function and using [the built-in `request.formData()` API](https://developer.mozilla.org/en-US/docs/Web/API/Request/formData) + * is the ability to customize the handling of file uploads. Instead of buffering the entire file in + * memory, the `uploadHandler` allows you to stream the file to disk or a cloud storage service. */ export async function parseFormData( request: Request, @@ -96,14 +97,15 @@ export async function parseFormData( let promises: Promise<void | null | string | File>[] = []; for await (let part of parseMultipartRequest(request, parserOptions)) { - if (!part.name) continue; + let fieldName = part.name; + + if (!fieldName) continue; if (part.isFile) { let value = uploadHandler(new FileUpload(part)); if (value != null) { if (isPromise(value)) { - let fieldName = part.name; promises.push( value.then((file) => { if (file != null) { @@ -112,11 +114,11 @@ export async function parseFormData( }), ); } else { - formData.append(part.name, value); + formData.append(fieldName, value); } } } else { - formData.append(part.name, await part.text()); + formData.append(fieldName, await part.text()); } } From ac49c9c4e597c5807ed9c235d03f6787af012dc1 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 16 Jan 2025 15:48:36 -0800 Subject: [PATCH 585/730] Add link in doc comment --- packages/form-data-parser/src/lib/form-data.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/form-data-parser/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts index 5b962980955..7a4791823b2 100644 --- a/packages/form-data-parser/src/lib/form-data.ts +++ b/packages/form-data-parser/src/lib/form-data.ts @@ -12,8 +12,9 @@ import { * be saved to disk or a cloud storage service as quickly as possible to avoid buffering and * backpressure building up in the input stream. * - * Note: Although `FileUpload` implements the `File` interface, its `size` is unknown, so any - * attempt to access `file.size` or use `file.slice()` will throw an error. + * Note: Although `FileUpload` implements the [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) + * interface, its `size` is unknown, so any attempt to access `file.size` or use `file.slice()` will + * throw an error. */ export class FileUpload implements File { readonly name: string; From b6b696a37540cffcf997b3206ad16f9cf457a254 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Thu, 16 Jan 2025 16:01:18 -0800 Subject: [PATCH 586/730] Small var name change --- packages/form-data-parser/src/lib/form-data.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/form-data-parser/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts index 7a4791823b2..90c7713326f 100644 --- a/packages/form-data-parser/src/lib/form-data.ts +++ b/packages/form-data-parser/src/lib/form-data.ts @@ -108,9 +108,9 @@ export async function parseFormData( if (value != null) { if (isPromise(value)) { promises.push( - value.then((file) => { - if (file != null) { - formData.append(fieldName, file); + value.then((asyncValue) => { + if (asyncValue != null) { + formData.append(fieldName, asyncValue); } }), ); From 6c171f81249d5d8102961d7d443f9116a65deac6 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Fri, 17 Jan 2025 10:23:25 -0800 Subject: [PATCH 587/730] Fix type --- packages/form-data-parser/src/lib/form-data.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/form-data-parser/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts index 90c7713326f..0adf9ceb78f 100644 --- a/packages/form-data-parser/src/lib/form-data.ts +++ b/packages/form-data-parser/src/lib/form-data.ts @@ -95,7 +95,7 @@ export async function parseFormData( } let formData = new FormData(); - let promises: Promise<void | null | string | File>[] = []; + let promises: Promise<void>[] = []; for await (let part of parseMultipartRequest(request, parserOptions)) { let fieldName = part.name; From 8a9742667f951544d170e9c535953568caac1c40 Mon Sep 17 00:00:00 2001 From: Michael Jackson <mjijackson@gmail.com> Date: Tue, 21 Jan 2025 13:34:32 -0800 Subject: [PATCH 588/730] Expand FileUploadHandler interface to support Blob --- packages/form-data-parser/CHANGELOG.md | 4 ++++ packages/form-data-parser/src/lib/form-data.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index 2cff852902c..9de53829ed5 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -2,6 +2,10 @@ This is the changelog for [`form-data-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Expand `FileUploadHandler` interface to support returning `Blob` from the upload handler, which is the superclass of `File` + ## v0.6.0 (2025-01-15) - Allow upload handlers to run in parallel. Fixes #44 diff --git a/packages/form-data-parser/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts index 0adf9ceb78f..25d6e8d270a 100644 --- a/packages/form-data-parser/src/lib/form-data.ts +++ b/packages/form-data-parser/src/lib/form-data.ts @@ -67,7 +67,7 @@ export class FileUpload implements File { * A function used for handling file uploads. */ export interface FileUploadHandler { - (file: FileUpload): void | null | string | File | Promise<void | null | string | File>; + (file: FileUpload): void | null | string | Blob | Promise<void | null | string | Blob>; } async function defaultFileUploadHandler(file: FileUpload): Promise<File> { From fa226ba7572a09224b0d4b85bb1be3c76977b713 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 23 Jan 2025 10:16:21 -0800 Subject: [PATCH 589/730] Fix failing test --- packages/headers/src/lib/content-disposition.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/headers/src/lib/content-disposition.test.ts b/packages/headers/src/lib/content-disposition.test.ts index 7acb5f604c3..9e280dff32b 100644 --- a/packages/headers/src/lib/content-disposition.test.ts +++ b/packages/headers/src/lib/content-disposition.test.ts @@ -193,7 +193,7 @@ describe('ContentDisposition', () => { it('correctly decodes windows-1252 encoded filename', () => { let header = new ContentDisposition("attachment; filename*=windows-1252''file%80.txt"); - assert.equal(header.preferredFilename, 'file€.txt'); + assert.equal(header.preferredFilename, 'file\x80.txt'); }); it('handles UTF-8 encoded filename correctly', () => { From 3c9dea911f935d16cece3731ba27f45d2f393294 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 23 Jan 2025 16:55:34 -0800 Subject: [PATCH 590/730] Add support for missing `ReadableStream.prototype[Symbol.asyncIterator]` in Safari Fixes #46 --- packages/multipart-parser/CHANGELOG.md | 4 ++ .../multipart-parser/src/lib/multipart.ts | 49 ++++++++++++++----- .../multipart-parser/src/lib/read-stream.ts | 15 ++++++ packages/tar-parser/CHANGELOG.md | 6 ++- packages/tar-parser/src/lib/read-stream.ts | 15 ++++++ packages/tar-parser/src/lib/tar.ts | 13 +++-- 6 files changed, 84 insertions(+), 18 deletions(-) create mode 100644 packages/multipart-parser/src/lib/read-stream.ts create mode 100644 packages/tar-parser/src/lib/read-stream.ts diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index e57831c6375..9e4fe2c9a70 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -2,6 +2,10 @@ This is the changelog for [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Add support for environments that do not support `ReadableStream.prototype[Symbol.asyncIterator]` (i.e. Safari), see #46 + ## v0.7.2 (2024-12-12) - Fix dependency on `headers` in package.json diff --git a/packages/multipart-parser/src/lib/multipart.ts b/packages/multipart-parser/src/lib/multipart.ts index e2604cc0b7d..0dfb66a03ef 100644 --- a/packages/multipart-parser/src/lib/multipart.ts +++ b/packages/multipart-parser/src/lib/multipart.ts @@ -1,5 +1,6 @@ import Headers from '@mjackson/headers'; +import { readStream } from './read-stream.ts'; import { type SearchFunction, createSearch, @@ -46,18 +47,42 @@ export async function* parseMultipartRequest( yield* parseMultipart(request.body, boundary, options); } +type MultipartMessageSource = + | ReadableStream<Uint8Array> + | Uint8Array + | Iterable<Uint8Array> + | AsyncIterable<Uint8Array>; + /** * Parse a `multipart/*` buffer or stream and yield each part it finds as a `MultipartPart` object. * + * ```ts + * import { parseMultipart } from '@mjackson/multipart-parser'; + * + * let boundary = '----WebKitFormBoundaryzv5Z4JY8k9lG0yQW'; + * + * for await (let part of parseMultipart(message, boundary)) { + * if (part.isFile) { + * console.log(part.filename); + * if (part.mediaType.startsWith('text/')) { + * let text = await part.text(); + * // ... + * } else { + * let buffer = await part.bytes(); + * // ... + * } + * } else { + * let text = await part.text(); + * // ... + * } + * } + * ``` + * * Note: This is a low-level API that requires manual handling of the stream and boundary. If you're * building a web server, consider using `parseMultipartRequest(request)` instead. */ export async function* parseMultipart( - message: - | ReadableStream<Uint8Array> - | Uint8Array - | Iterable<Uint8Array> - | AsyncIterable<Uint8Array>, + message: MultipartMessageSource, boundary: string, options?: MultipartParserOptions, ): AsyncGenerator<MultipartPart> { @@ -160,11 +185,7 @@ export class MultipartParser { * Resolves when the parse is finished and all handlers resolve. */ async parse( - message: - | ReadableStream<Uint8Array> - | Uint8Array - | Iterable<Uint8Array> - | AsyncIterable<Uint8Array>, + message: MultipartMessageSource, handler: (part: MultipartPart) => void, ): Promise<void> { if (this.#state !== MultipartParserStateStart) { @@ -177,7 +198,11 @@ export class MultipartParser { results.push(handler(part)); } - if (message instanceof ReadableStream || isAsyncIterable(message)) { + if (message instanceof ReadableStream) { + for await (let chunk of readStream(message)) { + this.#write(chunk, handlePart); + } + } else if (isAsyncIterable(message)) { for await (let chunk of message) { this.#write(chunk, handlePart); } @@ -410,7 +435,7 @@ export class MultipartPart { let chunks: Uint8Array[] = []; let totalLength = 0; - for await (let chunk of this.#body) { + for await (let chunk of readStream(this.#body)) { chunks.push(chunk); totalLength += chunk.length; } diff --git a/packages/multipart-parser/src/lib/read-stream.ts b/packages/multipart-parser/src/lib/read-stream.ts new file mode 100644 index 00000000000..e33a40a91b0 --- /dev/null +++ b/packages/multipart-parser/src/lib/read-stream.ts @@ -0,0 +1,15 @@ +// We need this little helper for environments that do not support +// ReadableStream.prototype[Symbol.asyncIterator] yet. See #46 +export async function* readStream(stream: ReadableStream<Uint8Array>): AsyncIterable<Uint8Array> { + let reader = stream.getReader(); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + yield value; + } + } finally { + reader.releaseLock(); + } +} diff --git a/packages/tar-parser/CHANGELOG.md b/packages/tar-parser/CHANGELOG.md index 5f2fdab1b3f..3d197a33c7c 100644 --- a/packages/tar-parser/CHANGELOG.md +++ b/packages/tar-parser/CHANGELOG.md @@ -2,9 +2,13 @@ This is the changelog for [`tar-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/tar-parser). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Add support for environments that do not support `ReadableStream.prototype[Symbol.asyncIterator]` (i.e. Safari), see #46 + ## v0.2.0 (2025-01-07) -- Fixed a bug that hangs the process when trying to read zero-length entries. +- Fix a bug that hangs the process when trying to read zero-length entries. ## v0.1.0 (2024-12-06) diff --git a/packages/tar-parser/src/lib/read-stream.ts b/packages/tar-parser/src/lib/read-stream.ts new file mode 100644 index 00000000000..e33a40a91b0 --- /dev/null +++ b/packages/tar-parser/src/lib/read-stream.ts @@ -0,0 +1,15 @@ +// We need this little helper for environments that do not support +// ReadableStream.prototype[Symbol.asyncIterator] yet. See #46 +export async function* readStream(stream: ReadableStream<Uint8Array>): AsyncIterable<Uint8Array> { + let reader = stream.getReader(); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + yield value; + } + } finally { + reader.releaseLock(); + } +} diff --git a/packages/tar-parser/src/lib/tar.ts b/packages/tar-parser/src/lib/tar.ts index 6acc0579962..07e457b9ecc 100644 --- a/packages/tar-parser/src/lib/tar.ts +++ b/packages/tar-parser/src/lib/tar.ts @@ -1,3 +1,4 @@ +import { readStream } from './read-stream.ts'; import { buffersEqual, concatChunks, @@ -153,9 +154,7 @@ type TarArchiveSource = export type ParseTarOptions = ParseTarHeaderOptions; /** - * Parses a tar archive and calls the given handler for each entry it contains. - * - * Example: + * Parse a tar archive and call the given handler for each entry it contains. * * ```ts * import { parseTar } from '@mjackson/tar-parser'; @@ -236,7 +235,11 @@ export class TarParser { results.push(handler(entry)); } - if (archive instanceof ReadableStream || isAsyncIterable(archive)) { + if (archive instanceof ReadableStream) { + for await (let chunk of readStream(archive)) { + this.#write(chunk, handleEntry); + } + } else if (isAsyncIterable(archive)) { for await (let chunk of archive) { this.#write(chunk, handleEntry); } @@ -474,7 +477,7 @@ export class TarEntry { let result = new Uint8Array(this.size); let offset = 0; - for await (let chunk of this.#body) { + for await (let chunk of readStream(this.#body)) { result.set(chunk, offset); offset += chunk.length; } From b68eaef379b902feff1a061bbe6dbe71523c5b47 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 23 Jan 2025 17:11:23 -0800 Subject: [PATCH 591/730] Release tar-parser@0.2.1 --- packages/tar-parser/CHANGELOG.md | 2 +- packages/tar-parser/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/tar-parser/CHANGELOG.md b/packages/tar-parser/CHANGELOG.md index 3d197a33c7c..d9a77679a40 100644 --- a/packages/tar-parser/CHANGELOG.md +++ b/packages/tar-parser/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`tar-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/tar-parser). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.2.1 (2025-01-24) - Add support for environments that do not support `ReadableStream.prototype[Symbol.asyncIterator]` (i.e. Safari), see #46 diff --git a/packages/tar-parser/package.json b/packages/tar-parser/package.json index 82a242c7976..001d16d5460 100644 --- a/packages/tar-parser/package.json +++ b/packages/tar-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/tar-parser", - "version": "0.2.0", + "version": "0.2.1", "description": "A fast, efficient parser for tar streams in any JavaScript environment", "author": "Michael Jackson <mjijackson@gmail.com>", "license": "MIT", From 7d5e0e772c1d9620ea233daacd996e2fdd1dd4fa Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 23 Jan 2025 17:11:35 -0800 Subject: [PATCH 592/730] Release multipart-parser@0.7.3 --- packages/multipart-parser/CHANGELOG.md | 2 +- packages/multipart-parser/jsr.json | 2 +- packages/multipart-parser/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index 9e4fe2c9a70..95097d6daf9 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.7.3 (2025-01-24) - Add support for environments that do not support `ReadableStream.prototype[Symbol.asyncIterator]` (i.e. Safari), see #46 diff --git a/packages/multipart-parser/jsr.json b/packages/multipart-parser/jsr.json index 121c0e159b5..e3896ba8c11 100644 --- a/packages/multipart-parser/jsr.json +++ b/packages/multipart-parser/jsr.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.7.2", + "version": "0.7.3", "exports": "./src/multipart-parser.ts", "publish": { "include": [ diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 93dc5017e95..4a676d772dd 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.7.2", + "version": "0.7.3", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From e212ed71c0a485693cf8d3e2c47e1ea9416fe101 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Thu, 23 Jan 2025 17:26:33 -0800 Subject: [PATCH 593/730] Move request-specific interfaces into multipart-request module --- .../src/lib/multipart-request.ts | 45 +++++++++++++++++++ .../src/lib/multipart.node.ts | 2 +- .../src/lib/multipart.test.ts | 6 +-- .../multipart-parser/src/lib/multipart.ts | 39 ---------------- .../src/multipart-parser.node.ts | 3 +- .../multipart-parser/src/multipart-parser.ts | 9 ++-- 6 files changed, 57 insertions(+), 47 deletions(-) create mode 100644 packages/multipart-parser/src/lib/multipart-request.ts diff --git a/packages/multipart-parser/src/lib/multipart-request.ts b/packages/multipart-parser/src/lib/multipart-request.ts new file mode 100644 index 00000000000..a5c31c038f3 --- /dev/null +++ b/packages/multipart-parser/src/lib/multipart-request.ts @@ -0,0 +1,45 @@ +import { + type MultipartParserOptions, + type MultipartPart, + parseMultipart, + MultipartParseError, +} from './multipart.ts'; + +/** + * Extracts the boundary string from a `multipart/*` content type. + */ +export function getMultipartBoundary(contentType: string): string | null { + let match = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(contentType); + return match ? (match[1] ?? match[2]) : null; +} + +/** + * Returns true if the given request contains multipart data. + */ +export function isMultipartRequest(request: Request): boolean { + let contentType = request.headers.get('Content-Type'); + return contentType != null && contentType.startsWith('multipart/'); +} + +/** + * Parse a multipart [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and yield each part as + * a `MultipartPart` object. Useful in HTTP server contexts for handling incoming `multipart/*` requests. + */ +export async function* parseMultipartRequest( + request: Request, + options?: MultipartParserOptions, +): AsyncGenerator<MultipartPart> { + if (!isMultipartRequest(request)) { + throw new MultipartParseError('Request is not a multipart request'); + } + if (!request.body) { + throw new MultipartParseError('Request body is empty'); + } + + let boundary = getMultipartBoundary(request.headers.get('Content-Type')!); + if (!boundary) { + throw new MultipartParseError('Invalid Content-Type header: missing boundary'); + } + + yield* parseMultipart(request.body, boundary, options); +} diff --git a/packages/multipart-parser/src/lib/multipart.node.ts b/packages/multipart-parser/src/lib/multipart.node.ts index 4c560f175f0..d6fbdbea8fb 100644 --- a/packages/multipart-parser/src/lib/multipart.node.ts +++ b/packages/multipart-parser/src/lib/multipart.node.ts @@ -2,12 +2,12 @@ import type * as http from 'node:http'; import { Readable } from 'node:stream'; import { - getMultipartBoundary, parseMultipart as parseMultipartWeb, MultipartParseError, type MultipartParserOptions, MultipartPart, } from './multipart.ts'; +import { getMultipartBoundary } from './multipart-request.ts'; /** * Returns true if the given request is a multipart request. diff --git a/packages/multipart-parser/src/lib/multipart.test.ts b/packages/multipart-parser/src/lib/multipart.test.ts index 4866415fc95..888709ee88e 100644 --- a/packages/multipart-parser/src/lib/multipart.test.ts +++ b/packages/multipart-parser/src/lib/multipart.test.ts @@ -3,12 +3,12 @@ import { describe, it } from 'node:test'; import { createMockRequest, createMultipartMockRequest, getRandomBytes } from '../../test/utils.ts'; +import { MultipartParseError } from './multipart.ts'; import { + getMultipartBoundary, isMultipartRequest, parseMultipartRequest, - MultipartParseError, - getMultipartBoundary, -} from './multipart.ts'; +} from './multipart-request.ts'; const CRLF = '\r\n'; diff --git a/packages/multipart-parser/src/lib/multipart.ts b/packages/multipart-parser/src/lib/multipart.ts index 0dfb66a03ef..7ac99975229 100644 --- a/packages/multipart-parser/src/lib/multipart.ts +++ b/packages/multipart-parser/src/lib/multipart.ts @@ -8,45 +8,6 @@ import { createPartialTailSearch, } from './search.ts'; -/** - * Extracts the boundary string from a `multipart/*` content type. - */ -export function getMultipartBoundary(contentType: string): string | null { - let match = /boundary=(?:"([^"]+)"|([^;]+))/i.exec(contentType); - return match ? (match[1] ?? match[2]) : null; -} - -/** - * Returns true if the given request contains multipart data. - */ -export function isMultipartRequest(request: Request): boolean { - let contentType = request.headers.get('Content-Type'); - return contentType != null && contentType.startsWith('multipart/'); -} - -/** - * Parse a multipart [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and yield each part as - * a `MultipartPart` object. Useful in HTTP server contexts for handling incoming `multipart/*` requests. - */ -export async function* parseMultipartRequest( - request: Request, - options?: MultipartParserOptions, -): AsyncGenerator<MultipartPart> { - if (!isMultipartRequest(request)) { - throw new MultipartParseError('Request is not a multipart request'); - } - if (!request.body) { - throw new MultipartParseError('Request body is empty'); - } - - let boundary = getMultipartBoundary(request.headers.get('Content-Type')!); - if (!boundary) { - throw new MultipartParseError('Invalid Content-Type header: missing boundary'); - } - - yield* parseMultipart(request.body, boundary, options); -} - type MultipartMessageSource = | ReadableStream<Uint8Array> | Uint8Array diff --git a/packages/multipart-parser/src/multipart-parser.node.ts b/packages/multipart-parser/src/multipart-parser.node.ts index b5a1e33617c..34a4773a11c 100644 --- a/packages/multipart-parser/src/multipart-parser.node.ts +++ b/packages/multipart-parser/src/multipart-parser.node.ts @@ -1,11 +1,12 @@ // Re-export all core functionality export { - getMultipartBoundary, MultipartParseError, type MultipartParserOptions, MultipartParser, MultipartPart, } from './lib/multipart.ts'; +export { getMultipartBoundary } from './lib/multipart-request.ts'; + // Export Node.js-specific functionality export { isMultipartRequest, parseMultipartRequest, parseMultipart } from './lib/multipart.node.ts'; diff --git a/packages/multipart-parser/src/multipart-parser.ts b/packages/multipart-parser/src/multipart-parser.ts index 6357e0d4a2b..d31773bd020 100644 --- a/packages/multipart-parser/src/multipart-parser.ts +++ b/packages/multipart-parser/src/multipart-parser.ts @@ -1,10 +1,13 @@ export { - getMultipartBoundary, - isMultipartRequest, - parseMultipartRequest, parseMultipart, MultipartParseError, type MultipartParserOptions, MultipartParser, MultipartPart, } from './lib/multipart.ts'; + +export { + getMultipartBoundary, + isMultipartRequest, + parseMultipartRequest, +} from './lib/multipart-request.ts'; From 3ff74a535abf0a6e836842b520b53470c322913b Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Fri, 24 Jan 2025 11:19:49 -0800 Subject: [PATCH 594/730] Improved error handling in multipart parser Fixes #28 --- packages/multipart-parser/CHANGELOG.md | 55 +++++++ packages/multipart-parser/README.md | 83 ++++++----- .../bench/parsers/multipart-parser.ts | 4 +- .../multipart-parser/examples/bun/server.ts | 16 +- .../examples/cf-workers/src/index.ts | 6 +- .../multipart-parser/examples/deno/main.ts | 4 +- .../multipart-parser/examples/node/server.js | 17 ++- .../{search.test.ts => buffer-search.test.ts} | 2 +- .../src/lib/{search.ts => buffer-search.ts} | 0 ...part.test.ts => multipart-request.test.ts} | 109 ++++++++------ .../src/lib/multipart-request.ts | 31 +++- .../src/lib/multipart.node.test.ts | 17 ++- .../src/lib/multipart.node.ts | 52 +++++-- .../multipart-parser/src/lib/multipart.ts | 141 ++++++++---------- .../multipart-parser/src/lib/read-stream.ts | 12 +- .../src/multipart-parser.node.ts | 3 + .../multipart-parser/src/multipart-parser.ts | 5 +- 17 files changed, 337 insertions(+), 220 deletions(-) rename packages/multipart-parser/src/lib/{search.test.ts => buffer-search.test.ts} (92%) rename packages/multipart-parser/src/lib/{search.ts => buffer-search.ts} (100%) rename packages/multipart-parser/src/lib/{multipart.test.ts => multipart-request.test.ts} (75%) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index 95097d6daf9..ca269bec443 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -2,6 +2,61 @@ This is the changelog for [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser). It follows [semantic versioning](https://semver.org/). +## HEAD + +This release improves error handling and simplifies some of the internals of the parser. + +- BREAKING CHANGE: Change `parseMultipartRequest` and `parseMultipart` interfaces from `for await...of` to `await` + callback API. + +```ts +import { parseMultipartRequest } from '@mjackson/multipart-parser'; + +// before +for await (let part of parseMultipartRequest(request)) { + // ... +} + +// after +await parseMultipartRequest(request, (part) => { + // ... +}); +``` + +This change greatly simplifies the implementation of `parseMultipartRequest`/`parseMultipart` and fixes a subtle bug that did not properly catch parse errors when `maxFileSize` was exceeded (see #28). + +- Add `MaxHeaderSizeExceededError` and `MaxFileSizeExceededError` to make it easier to have finer-grained error handling. + +```ts +import * as http from 'node:http'; +import { + MultipartParseError, + MaxFileSizeExceededError, + parseMultipartRequest, +} from '@mjackson/multipart-parser/node'; + +const tenMb = 10 * Math.pow(2, 20); + +const server = http.createServer(async (req, res) => { + try { + await parseMultipartRequest(req, { maxFileSize: tenMb }, (part) => { + // ... + }); + } catch (error) { + if (error instanceof MaxFileSizeExceededError) { + res.writeHead(413); + res.end(error.message); + } else if (error instanceof MultipartParseError) { + res.writeHead(400); + res.end('Invalid multipart request'); + } else { + console.error(error); + res.writeHead(500); + res.end('Internal Server Error'); + } + } +}); +``` + ## v0.7.3 (2025-01-24) - Add support for environments that do not support `ReadableStream.prototype[Symbol.asyncIterator]` (i.e. Safari), see #46 diff --git a/packages/multipart-parser/README.md b/packages/multipart-parser/README.md index 5abfddbeee3..b2f022a4efb 100644 --- a/packages/multipart-parser/README.md +++ b/packages/multipart-parser/README.md @@ -35,10 +35,9 @@ The most common use case for `multipart-parser` is handling file uploads when yo ```ts import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser'; -async function handleMultipartRequest(request: Request): void { +async function handleRequest(request: Request): void { try { - // The parser `yield`s each MultipartPart as it becomes available - for await (let part of parseMultipartRequest(request)) { + await parseMultipartRequest(request, (part) => { console.log(part.name); console.log(part.filename); @@ -47,7 +46,7 @@ async function handleMultipartRequest(request: Request): void { } else { // TODO: part.body is a ReadableStream<Uint8Array>, stream it to a file } - } + }); } catch (error) { if (error instanceof MultipartParseError) { console.error('Failed to parse multipart request:', error.message); @@ -64,20 +63,17 @@ If however you're building a server for Node.js that relies on node-specific API ```ts import * as http from 'node:http'; - -import { MultipartParseError } from '@mjackson/multipart-parser'; -// Note: Import from multipart-parser/node for node-specific APIs -import { parseMultipartRequest } from '@mjackson/multipart-parser/node'; +import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser/node'; const server = http.createServer(async (req, res) => { try { - for await (let part of parseMultipartRequest(req)) { + await parseMultipartRequest(req, (part) => { console.log(part.name); console.log(part.filename); console.log(part.mediaType); // ... - } + }); } catch (error) { if (error instanceof MultipartParseError) { console.error('Failed to parse multipart request:', error.message); @@ -90,9 +86,44 @@ const server = http.createServer(async (req, res) => { server.listen(8080); ``` +## Limiting File Upload Size + +A common use case when handling file uploads is limiting the size of uploaded files to prevent malicious users from sending very large files that may overload your server's memory and/or storage capacity. You can set a file upload size limit using the `maxFileSize` option, and return a 413 "Payload Too Large" response when you receive a request that exceeds the limit. + +```ts +import * as http from 'node:http'; +import { + MultipartParseError, + MaxFileSizeExceededError, + parseMultipartRequest, +} from '@mjackson/multipart-parser/node'; + +const tenMb = 10 * Math.pow(2, 20); + +const server = http.createServer(async (req, res) => { + try { + await parseMultipartRequest(req, { maxFileSize: tenMb }, (part) => { + // ... + }); + } catch (error) { + if (error instanceof MaxFileSizeExceededError) { + res.writeHead(413); + res.end(error.message); + } else if (error instanceof MultipartParseError) { + res.writeHead(400); + res.end('Invalid multipart request'); + } else { + console.error(error); + res.writeHead(500); + res.end('Internal Server Error'); + } + } +}); +``` + ## Low-level API -If you're working directly with multipart boundaries and buffers/streams of multipart data that are not necessarily part of a request, `multipart-parser` provides a lower-level API that you can use directly: +If you're working directly with multipart boundaries and buffers/streams of multipart data that are not necessarily part of a request, `multipart-parser` provides a low-level `parseMultipart()` API that you can use directly: ```ts import { parseMultipart } from '@mjackson/multipart-parser'; @@ -105,33 +136,9 @@ let multipartMessage = new Uint8Array(); let boundary = '----WebKitFormBoundary56eac3x'; -for await (let part of parseMultipart(multipartMessage, boundary)) { - // Do whatever you want with the part... -} -``` - -If you'd prefer a callback-based API, instantiate your own `MultipartParser` and go for it: - -```ts -import { MultipartParseError, MultipartParser } from '@mjackson/multipart-parser'; - -let multipartMessage = new Uint8Array(); // or ReadableStream<Uint8Array>, etc. -let boundary = '...'; - -let parser = new MultipartParser(boundary); - -try { - // parse() resolves once the parse is finished and all your callbacks are done - await parser.parse(multipartMessage, async (part) => { - // Do whatever you need... - }); -} catch (error) { - if (error instanceof MultipartParseError) { - // The parse failed - } else { - // One of your handlers failed - } -} +await parseMultipart(multipartMessage, { boundary }, (part) => { + // ... +}); ``` ## Examples diff --git a/packages/multipart-parser/bench/parsers/multipart-parser.ts b/packages/multipart-parser/bench/parsers/multipart-parser.ts index 681af5b7fcf..c976aba4de4 100644 --- a/packages/multipart-parser/bench/parsers/multipart-parser.ts +++ b/packages/multipart-parser/bench/parsers/multipart-parser.ts @@ -1,11 +1,11 @@ -import { MultipartParser } from '@mjackson/multipart-parser'; +import { parseMultipart } from '@mjackson/multipart-parser'; import { MultipartMessage } from '../messages.ts'; export async function parse(message: MultipartMessage): Promise<number> { let start = performance.now(); - await new MultipartParser(message.boundary).parse(message.generateChunks(), (_part) => { + await parseMultipart(message.generateChunks(), { boundary: message.boundary }, (_part) => { // Do nothing }); diff --git a/packages/multipart-parser/examples/bun/server.ts b/packages/multipart-parser/examples/bun/server.ts index 58662783e4e..4e404a369da 100644 --- a/packages/multipart-parser/examples/bun/server.ts +++ b/packages/multipart-parser/examples/bun/server.ts @@ -33,7 +33,7 @@ const server = Bun.serve({ try { let parts: any[] = []; - for await (let part of parseMultipartRequest(request)) { + await parseMultipartRequest(request, async (part) => { if (part.isFile) { let tmpfile = tmp.fileSync(); let bytesWritten = await writeFile(Bun.file(tmpfile.name), part.body); @@ -51,7 +51,7 @@ const server = Bun.serve({ value: await part.text(), }); } - } + }); return new Response(JSON.stringify({ parts }, null, 2), { headers: { 'Content-Type': 'application/json' }, @@ -77,12 +77,14 @@ async function writeFile(file: BunFile, stream: ReadableStream<Uint8Array>): Pro let writer = file.writer(); let bytesWritten = 0; - for await (let chunk of stream) { - writer.write(chunk); - bytesWritten += chunk.byteLength; + try { + for await (let chunk of stream) { + writer.write(chunk); + bytesWritten += chunk.byteLength; + } + } finally { + await writer.end(); } - await writer.end(); - return bytesWritten; } diff --git a/packages/multipart-parser/examples/cf-workers/src/index.ts b/packages/multipart-parser/examples/cf-workers/src/index.ts index 2c8953ab72a..06956dcb930 100644 --- a/packages/multipart-parser/examples/cf-workers/src/index.ts +++ b/packages/multipart-parser/examples/cf-workers/src/index.ts @@ -29,9 +29,9 @@ export default { if (request.method === 'POST') { try { let bucket = env.MULTIPART_UPLOADS; - let parts = []; + let parts: any[] = []; - for await (let part of parseMultipartRequest(request)) { + await parseMultipartRequest(request, async (part) => { if (part.isFile) { let uniqueKey = `upload-${new Date().getTime()}-${Math.random() .toString(36) @@ -66,7 +66,7 @@ export default { value: await part.text(), }); } - } + }); return new Response(JSON.stringify({ parts }, null, 2), { headers: { 'Content-Type': 'application/json' }, diff --git a/packages/multipart-parser/examples/deno/main.ts b/packages/multipart-parser/examples/deno/main.ts index 01b49a9dcf1..936bf016825 100644 --- a/packages/multipart-parser/examples/deno/main.ts +++ b/packages/multipart-parser/examples/deno/main.ts @@ -35,7 +35,7 @@ async function requestHandler(request: Request): Promise<Response> { // deno-lint-ignore no-explicit-any let parts: any[] = []; - for await (let part of parseMultipartRequest(request)) { + await parseMultipartRequest(request, async (part) => { if (part.isFile) { let tmpfile = tmp.fileSync(); await Deno.writeFile(tmpfile.name, part.body); @@ -53,7 +53,7 @@ async function requestHandler(request: Request): Promise<Response> { value: await part.text(), }); } - } + }); return new Response(JSON.stringify({ parts }, null, 2), { headers: { 'Content-Type': 'application/json' }, diff --git a/packages/multipart-parser/examples/node/server.js b/packages/multipart-parser/examples/node/server.js index 023d17ad90b..8ce0fa57fe4 100644 --- a/packages/multipart-parser/examples/node/server.js +++ b/packages/multipart-parser/examples/node/server.js @@ -30,9 +30,10 @@ const server = http.createServer(async (req, res) => { if (req.method === 'POST') { try { + /** @type any[] */ let parts = []; - for await (let part of parseMultipartRequest(req)) { + await parseMultipartRequest(req, async (part) => { if (part.isFile) { let tmpfile = tmp.fileSync(); let byteLength = await writeFile(tmpfile.name, part.body); @@ -55,7 +56,7 @@ const server = http.createServer(async (req, res) => { value: await part.text(), }); } - } + }); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ parts }, null, 2)); @@ -88,12 +89,14 @@ async function writeFile(filename, stream) { let file = fs.createWriteStream(filename); let bytesWritten = 0; - for await (let chunk of stream) { - file.write(chunk); - bytesWritten += chunk.byteLength; + try { + for await (let chunk of stream) { + file.write(chunk); + bytesWritten += chunk.byteLength; + } + } finally { + file.end(); } - file.end(); - return bytesWritten; } diff --git a/packages/multipart-parser/src/lib/search.test.ts b/packages/multipart-parser/src/lib/buffer-search.test.ts similarity index 92% rename from packages/multipart-parser/src/lib/search.test.ts rename to packages/multipart-parser/src/lib/buffer-search.test.ts index d805a737c4c..33aa220d986 100644 --- a/packages/multipart-parser/src/lib/search.test.ts +++ b/packages/multipart-parser/src/lib/buffer-search.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { createSearch, createPartialTailSearch } from './search.ts'; +import { createSearch, createPartialTailSearch } from './buffer-search.ts'; function buf(string: string): Uint8Array { return new TextEncoder().encode(string); diff --git a/packages/multipart-parser/src/lib/search.ts b/packages/multipart-parser/src/lib/buffer-search.ts similarity index 100% rename from packages/multipart-parser/src/lib/search.ts rename to packages/multipart-parser/src/lib/buffer-search.ts diff --git a/packages/multipart-parser/src/lib/multipart.test.ts b/packages/multipart-parser/src/lib/multipart-request.test.ts similarity index 75% rename from packages/multipart-parser/src/lib/multipart.test.ts rename to packages/multipart-parser/src/lib/multipart-request.test.ts index 888709ee88e..90550f9146c 100644 --- a/packages/multipart-parser/src/lib/multipart.test.ts +++ b/packages/multipart-parser/src/lib/multipart-request.test.ts @@ -3,7 +3,12 @@ import { describe, it } from 'node:test'; import { createMockRequest, createMultipartMockRequest, getRandomBytes } from '../../test/utils.ts'; -import { MultipartParseError } from './multipart.ts'; +import { + MultipartParseError, + MaxHeaderSizeExceededError, + MaxFileSizeExceededError, + type MultipartPart, +} from './multipart.ts'; import { getMultipartBoundary, isMultipartRequest, @@ -59,9 +64,9 @@ describe('parseMultipartRequest', async () => { let request = createMultipartMockRequest(boundary); let parts = []; - for await (let part of parseMultipartRequest(request)) { + await parseMultipartRequest(request, (part) => { parts.push(part); - } + }); assert.equal(parts.length, 0); }); @@ -71,10 +76,10 @@ describe('parseMultipartRequest', async () => { field1: 'value1', }); - let parts = []; - for await (let part of parseMultipartRequest(request)) { + let parts: MultipartPart[] = []; + await parseMultipartRequest(request, (part) => { parts.push(part); - } + }); assert.equal(parts.length, 1); assert.equal(parts[0].name, 'field1'); @@ -87,10 +92,10 @@ describe('parseMultipartRequest', async () => { field2: 'value2', }); - let parts = []; - for await (let part of parseMultipartRequest(request)) { + let parts: MultipartPart[] = []; + await parseMultipartRequest(request, (part) => { parts.push(part); - } + }); assert.equal(parts.length, 2); assert.equal(parts[0].name, 'field1'); @@ -104,10 +109,10 @@ describe('parseMultipartRequest', async () => { empty: '', }); - let parts = []; - for await (let part of parseMultipartRequest(request)) { + let parts: MultipartPart[] = []; + await parseMultipartRequest(request, (part) => { parts.push(part); - } + }); assert.equal(parts.length, 1); assert.equal(parts[0].name, 'empty'); @@ -123,10 +128,10 @@ describe('parseMultipartRequest', async () => { }, }); - let parts = []; - for await (let part of parseMultipartRequest(request)) { + let parts: MultipartPart[] = []; + await parseMultipartRequest(request, (part) => { parts.push(part); - } + }); assert.equal(parts.length, 1); assert.equal(parts[0].name, 'file1'); @@ -146,10 +151,10 @@ describe('parseMultipartRequest', async () => { }, }); - let parts = []; - for await (let part of parseMultipartRequest(request)) { + let parts: MultipartPart[] = []; + await parseMultipartRequest(request, (part) => { parts.push(part); - } + }); assert.equal(parts.length, 3); assert.equal(parts[0].name, 'field1'); @@ -172,15 +177,15 @@ describe('parseMultipartRequest', async () => { }, }); - let parts = []; - for await (let part of parseMultipartRequest(request)) { + let parts: { name?: string; filename?: string; mediaType?: string; content: Uint8Array }[] = []; + await parseMultipartRequest(request, async (part) => { parts.push({ name: part.name, filename: part.filename, mediaType: part.mediaType, content: await part.bytes(), }); - } + }); assert.equal(parts.length, 1); assert.equal(parts[0].name, 'file1'); @@ -195,7 +200,7 @@ describe('parseMultipartRequest', async () => { }); await assert.rejects(async () => { - await parseMultipartRequest(request).next(); + await parseMultipartRequest(request, () => {}); }, MultipartParseError); }); @@ -205,7 +210,7 @@ describe('parseMultipartRequest', async () => { }); await assert.rejects(async () => { - await parseMultipartRequest(request).next(); + await parseMultipartRequest(request, () => {}); }, MultipartParseError); }); @@ -225,15 +230,11 @@ describe('parseMultipartRequest', async () => { }); await assert.rejects(async () => { - for await (let part of parseMultipartRequest(request, { maxHeaderSize: 4 * 1024 })) { - for await (let _ of part.body) { - // Consume all parts - } - } - }, MultipartParseError); + await parseMultipartRequest(request, { maxHeaderSize: 4 * 1024 }, () => {}); + }, MaxHeaderSizeExceededError); }); - it('throws when file exceeds maximum size', async () => { + it('throws when a file exceeds maximum size', async () => { let request = createMultipartMockRequest(boundary, { file1: { filename: 'random.dat', @@ -243,12 +244,36 @@ describe('parseMultipartRequest', async () => { }); await assert.rejects(async () => { - for await (let part of parseMultipartRequest(request, { maxFileSize: 10 * 1024 * 1024 })) { - for await (let _ of part.body) { - // Consume all parts - } - } - }, MultipartParseError); + await parseMultipartRequest(request, { maxFileSize: 10 * 1024 * 1024 }, () => {}); + }, MaxFileSizeExceededError); + }); + + it('errors the stream when a file exceeds maximum size', async () => { + let request = createMultipartMockRequest(boundary, { + file1: { + filename: 'random.dat', + mediaType: 'application/octet-stream', + content: getRandomBytes(11 * 1024 * 1024), // 11 MB file + }, + }); + + let parts: MultipartPart[] = []; + try { + await parseMultipartRequest(request, { maxFileSize: 10 * 1024 * 1024 }, (part) => { + parts.push(part); + }); + } catch (error) { + // Ignore the parse error. + } + + assert.equal(parts.length, 1); + assert.equal(parts[0].name, 'file1'); + assert.equal(parts[0].filename, 'random.dat'); + assert.equal(parts[0].mediaType, 'application/octet-stream'); + + await assert.rejects(async () => { + await parts[0].bytes(); + }, MaxFileSizeExceededError); }); it('parses malformed parts', async () => { @@ -259,10 +284,10 @@ describe('parseMultipartRequest', async () => { body: [`--${boundary}`, 'Invalid-Header', '', 'Some content', `--${boundary}--`].join(CRLF), }); - let parts = []; - for await (let part of parseMultipartRequest(request)) { + let parts: MultipartPart[] = []; + await parseMultipartRequest(request, (part) => { parts.push(part); - } + }); assert.equal(parts.length, 1); assert.equal(parts[0].headers.get('Invalid-Header'), null); @@ -284,11 +309,7 @@ describe('parseMultipartRequest', async () => { }); await assert.rejects(async () => { - for await (let part of parseMultipartRequest(request)) { - for await (let _ of part.body) { - // Consume all parts - } - } + await parseMultipartRequest(request, () => {}); }, MultipartParseError); }); }); diff --git a/packages/multipart-parser/src/lib/multipart-request.ts b/packages/multipart-parser/src/lib/multipart-request.ts index a5c31c038f3..5f5203e1669 100644 --- a/packages/multipart-parser/src/lib/multipart-request.ts +++ b/packages/multipart-parser/src/lib/multipart-request.ts @@ -1,8 +1,8 @@ import { + MultipartParseError, + type MultipartPartHandler, type MultipartParserOptions, - type MultipartPart, parseMultipart, - MultipartParseError, } from './multipart.ts'; /** @@ -25,10 +25,25 @@ export function isMultipartRequest(request: Request): boolean { * Parse a multipart [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and yield each part as * a `MultipartPart` object. Useful in HTTP server contexts for handling incoming `multipart/*` requests. */ -export async function* parseMultipartRequest( +export async function parseMultipartRequest( + request: Request, + handler: MultipartPartHandler, +): Promise<void>; +export async function parseMultipartRequest( request: Request, - options?: MultipartParserOptions, -): AsyncGenerator<MultipartPart> { + options: MultipartParserOptions, + handler: MultipartPartHandler, +): Promise<void>; +export async function parseMultipartRequest( + request: Request, + options: MultipartParserOptions | MultipartPartHandler, + handler?: MultipartPartHandler, +): Promise<void> { + if (typeof options === 'function') { + handler = options; + options = {}; + } + if (!isMultipartRequest(request)) { throw new MultipartParseError('Request is not a multipart request'); } @@ -41,5 +56,9 @@ export async function* parseMultipartRequest( throw new MultipartParseError('Invalid Content-Type header: missing boundary'); } - yield* parseMultipart(request.body, boundary, options); + await parseMultipart( + request.body, + { boundary, maxHeaderSize: options.maxHeaderSize, maxFileSize: options.maxFileSize }, + handler!, + ); } diff --git a/packages/multipart-parser/src/lib/multipart.node.test.ts b/packages/multipart-parser/src/lib/multipart.node.test.ts index b3a14b15ff8..d4733f7c290 100644 --- a/packages/multipart-parser/src/lib/multipart.node.test.ts +++ b/packages/multipart-parser/src/lib/multipart.node.test.ts @@ -4,6 +4,7 @@ import { describe, it } from 'node:test'; import { getRandomBytes } from '../../test/utils.ts'; import { createMultipartMockRequest } from '../../test/utils.node.ts'; +import { type MultipartPart } from './multipart.ts'; import { parseMultipartRequest } from './multipart.node.ts'; describe('parseMultipartRequest (node)', () => { @@ -13,9 +14,9 @@ describe('parseMultipartRequest (node)', () => { let request = createMultipartMockRequest(boundary); let parts = []; - for await (let part of parseMultipartRequest(request)) { + await parseMultipartRequest(request, (part) => { parts.push(part); - } + }); assert.equal(parts.length, 0); }); @@ -25,10 +26,10 @@ describe('parseMultipartRequest (node)', () => { field1: 'value1', }); - let parts = []; - for await (let part of parseMultipartRequest(request)) { + let parts: MultipartPart[] = []; + await parseMultipartRequest(request, (part) => { parts.push(part); - } + }); assert.equal(parts.length, 1); assert.equal(parts[0].name, 'field1'); @@ -45,15 +46,15 @@ describe('parseMultipartRequest (node)', () => { }, }); - let parts = []; - for await (let part of parseMultipartRequest(request)) { + let parts: { name?: string; filename?: string; mediaType?: string; content: Uint8Array }[] = []; + await parseMultipartRequest(request, async (part) => { parts.push({ name: part.name, filename: part.filename, mediaType: part.mediaType, content: await part.bytes(), }); - } + }); assert.equal(parts.length, 1); assert.equal(parts[0].name, 'file1'); diff --git a/packages/multipart-parser/src/lib/multipart.node.ts b/packages/multipart-parser/src/lib/multipart.node.ts index d6fbdbea8fb..f5040a53f8f 100644 --- a/packages/multipart-parser/src/lib/multipart.node.ts +++ b/packages/multipart-parser/src/lib/multipart.node.ts @@ -2,10 +2,11 @@ import type * as http from 'node:http'; import { Readable } from 'node:stream'; import { - parseMultipart as parseMultipartWeb, MultipartParseError, + type MultipartPartHandler, + type ParseMultipartOptions, + parseMultipart as parseMultipartWeb, type MultipartParserOptions, - MultipartPart, } from './multipart.ts'; import { getMultipartBoundary } from './multipart-request.ts'; @@ -20,10 +21,25 @@ export function isMultipartRequest(req: http.IncomingMessage): boolean { /** * Parse a multipart Node.js request and yield each part as a `MultipartPart` object. */ -export async function* parseMultipartRequest( +export async function parseMultipartRequest( + req: http.IncomingMessage, + handler: MultipartPartHandler, +): Promise<void>; +export async function parseMultipartRequest( req: http.IncomingMessage, - options?: MultipartParserOptions, -): AsyncGenerator<MultipartPart> { + options: MultipartParserOptions, + handler: MultipartPartHandler, +): Promise<void>; +export async function parseMultipartRequest( + req: http.IncomingMessage, + options: MultipartParserOptions | MultipartPartHandler, + handler?: MultipartPartHandler, +): Promise<void> { + if (typeof options === 'function') { + handler = options; + options = {}; + } + if (!isMultipartRequest(req)) { throw new MultipartParseError('Request is not a multipart request'); } @@ -33,7 +49,11 @@ export async function* parseMultipartRequest( throw new MultipartParseError('Invalid Content-Type header: missing boundary'); } - yield* parseMultipart(req, boundary, options); + await parseMultipart( + req, + { boundary, maxHeaderSize: options.maxHeaderSize, maxFileSize: options.maxFileSize }, + handler!, + ); } /** @@ -42,18 +62,18 @@ export async function* parseMultipartRequest( * Note: This is a low-level API that requires manual handling of the stream and boundary. If you're * building a web server, consider using `parseMultipartRequest(request)` instead. */ -export async function* parseMultipart( - data: Readable | Buffer | Iterable<Buffer> | AsyncIterable<Buffer>, - boundary: string, - options?: MultipartParserOptions, -): AsyncGenerator<MultipartPart> { - if (data instanceof Readable) { - yield* parseMultipartWeb(Readable.toWeb(data), boundary, options); +export async function parseMultipart( + message: Readable | Buffer | Iterable<Buffer> | AsyncIterable<Buffer>, + options: ParseMultipartOptions, + handler: MultipartPartHandler, +): Promise<void> { + if (message instanceof Readable) { + await parseMultipartWeb(Readable.toWeb(message), options, handler); } else { - yield* parseMultipartWeb( - data as Uint8Array | Iterable<Uint8Array> | AsyncIterable<Uint8Array>, - boundary, + await parseMultipartWeb( + message as Uint8Array | Iterable<Uint8Array> | AsyncIterable<Uint8Array>, options, + handler, ); } } diff --git a/packages/multipart-parser/src/lib/multipart.ts b/packages/multipart-parser/src/lib/multipart.ts index 7ac99975229..37fbb8ec644 100644 --- a/packages/multipart-parser/src/lib/multipart.ts +++ b/packages/multipart-parser/src/lib/multipart.ts @@ -6,7 +6,28 @@ import { createSearch, type PartialTailSearchFunction, createPartialTailSearch, -} from './search.ts'; +} from './buffer-search.ts'; + +export class MultipartParseError extends Error { + constructor(message: string) { + super(message); + this.name = 'MultipartParseError'; + } +} + +export class MaxHeaderSizeExceededError extends MultipartParseError { + constructor(maxHeaderSize: number) { + super(`Multipart header size exceeds maximum allowed size of ${maxHeaderSize} bytes`); + this.name = 'MaxHeaderSizeExceededError'; + } +} + +export class MaxFileSizeExceededError extends MultipartParseError { + constructor(maxFileSize: number) { + super(`File size exceeds maximum allowed size of ${maxFileSize} bytes`); + this.name = 'MaxFileSizeExceededError'; + } +} type MultipartMessageSource = | ReadableStream<Uint8Array> @@ -14,6 +35,14 @@ type MultipartMessageSource = | Iterable<Uint8Array> | AsyncIterable<Uint8Array>; +export type MultipartPartHandler = (part: MultipartPart) => void; + +export interface ParseMultipartOptions { + boundary: string; + maxHeaderSize?: number; + maxFileSize?: number; +} + /** * Parse a `multipart/*` buffer or stream and yield each part it finds as a `MultipartPart` object. * @@ -22,9 +51,10 @@ type MultipartMessageSource = * * let boundary = '----WebKitFormBoundaryzv5Z4JY8k9lG0yQW'; * - * for await (let part of parseMultipart(message, boundary)) { + * await parseMultipart(message, { boundary }, async (part) => { * if (part.isFile) { * console.log(part.filename); + * * if (part.mediaType.startsWith('text/')) { * let text = await part.text(); * // ... @@ -36,71 +66,28 @@ type MultipartMessageSource = * let text = await part.text(); * // ... * } - * } + * }); * ``` * * Note: This is a low-level API that requires manual handling of the stream and boundary. If you're * building a web server, consider using `parseMultipartRequest(request)` instead. */ -export async function* parseMultipart( +export async function parseMultipart( message: MultipartMessageSource, - boundary: string, - options?: MultipartParserOptions, -): AsyncGenerator<MultipartPart> { - let parser = new MultipartParser(boundary, options); - - let parts: MultipartPart[] = []; - let resolveNext: (() => void) | null = null; - let parseError: Error | null = null; - let done = false; - - parser - .parse(message, (part) => { - parts.push(part); - - if (resolveNext) { - resolveNext(); - resolveNext = null; - } - }) - .catch((error) => { - parseError = error; - }) - .finally(() => { - done = true; - if (resolveNext) resolveNext(); - }); - - while (!done) { - if (parts.length === 0) { - await new Promise<void>((resolve) => { - resolveNext = resolve; - }); - } - - while (parts.length > 0) { - yield parts.shift()!; - } - } - - if (parseError) { - throw parseError; - } + options: ParseMultipartOptions, + handler: MultipartPartHandler, +): Promise<void> { + let parser = new MultipartParser(options.boundary, { + maxHeaderSize: options.maxHeaderSize, + maxFileSize: options.maxFileSize, + }); + + await parser.parse(message, handler); } const findDoubleNewline = createSearch('\r\n\r\n'); -export class MultipartParseError extends Error { - constructor(message: string) { - super(message); - this.name = 'MultipartParseError'; - } -} - -export interface MultipartParserOptions { - maxHeaderSize?: number; - maxFileSize?: number; -} +export type MultipartParserOptions = Omit<ParseMultipartOptions, 'boundary'>; const MultipartParserStateStart = 0; const MultipartParserStateAfterBoundary = 1; @@ -145,18 +132,22 @@ export class MultipartParser { * Parse a stream/buffer multipart message and call the given handler for each part it contains. * Resolves when the parse is finished and all handlers resolve. */ - async parse( - message: MultipartMessageSource, - handler: (part: MultipartPart) => void, - ): Promise<void> { + async parse(message: MultipartMessageSource, handler: MultipartPartHandler): Promise<void> { if (this.#state !== MultipartParserStateStart) { this.#reset(); } - let results: unknown[] = []; + let promises: Promise<unknown>[] = []; function handlePart(part: MultipartPart): void { - results.push(handler(part)); + let result = handler(part); + if (isPromise(result)) { + promises.push(result); + + // This hack marks the promise as "handled" in Node.js to suppress + // "unhandledRejection" warnings and avoid crashing the process. + result.catch(() => {}); + } } if (message instanceof ReadableStream) { @@ -181,7 +172,7 @@ export class MultipartParser { throw new MultipartParseError('Unexpected end of stream'); } - await Promise.all(results); + await Promise.all(promises); } #reset(): void { @@ -191,7 +182,7 @@ export class MultipartParser { this.#bodyLength = 0; } - #write(chunk: Uint8Array, handler: (part: MultipartPart) => void): void { + #write(chunk: Uint8Array, handler: MultipartPartHandler): void { if (this.#state === MultipartParserStateDone) { throw new MultipartParseError('Unexpected data after end of stream'); } @@ -265,9 +256,7 @@ export class MultipartParser { if (headerEndIndex === -1) { if (chunkLength - index > this.maxHeaderSize) { - throw new MultipartParseError( - `Header size exceeds maximum allowed size of ${this.maxHeaderSize} bytes`, - ); + throw new MaxHeaderSizeExceededError(this.maxHeaderSize); } this.#buffer = chunk.subarray(index); @@ -275,9 +264,7 @@ export class MultipartParser { } if (headerEndIndex - index > this.maxHeaderSize) { - throw new MultipartParseError( - `Header size exceeds maximum allowed size of ${this.maxHeaderSize} bytes`, - ); + throw new MaxHeaderSizeExceededError(this.maxHeaderSize); } let header = chunk.subarray(index, headerEndIndex); @@ -286,6 +273,7 @@ export class MultipartParser { new ReadableStream({ start: (controller) => { this.#bodyController = controller; + this.#bodyLength = 0; }, }), ); @@ -318,12 +306,8 @@ export class MultipartParser { #writeBody(chunk: Uint8Array): void { if (this.#bodyLength + chunk.length > this.maxFileSize) { - let error = new MultipartParseError( - `File size exceeds maximum allowed size of ${this.maxFileSize} bytes`, - ); - + let error = new MaxFileSizeExceededError(this.maxFileSize); this.#bodyController!.error(error); - throw error; } @@ -334,7 +318,6 @@ export class MultipartParser { #closeBody(): void { this.#bodyController!.close(); this.#bodyController = null; - this.#bodyLength = 0; } } @@ -346,6 +329,10 @@ function isAsyncIterable<T>(value: unknown): value is AsyncIterable<T> { return typeof value === 'object' && value != null && Symbol.asyncIterator in value; } +function isPromise<T>(value: unknown): value is Promise<T> { + return typeof value === 'object' && value != null && typeof (value as any).then === 'function'; +} + /** * A part of a `multipart/*` HTTP message. */ diff --git a/packages/multipart-parser/src/lib/read-stream.ts b/packages/multipart-parser/src/lib/read-stream.ts index e33a40a91b0..44a873071b4 100644 --- a/packages/multipart-parser/src/lib/read-stream.ts +++ b/packages/multipart-parser/src/lib/read-stream.ts @@ -3,13 +3,9 @@ export async function* readStream(stream: ReadableStream<Uint8Array>): AsyncIterable<Uint8Array> { let reader = stream.getReader(); - try { - while (true) { - const { done, value } = await reader.read(); - if (done) break; - yield value; - } - } finally { - reader.releaseLock(); + while (true) { + const { done, value } = await reader.read(); + if (done) break; + yield value; } } diff --git a/packages/multipart-parser/src/multipart-parser.node.ts b/packages/multipart-parser/src/multipart-parser.node.ts index 34a4773a11c..3c73de99530 100644 --- a/packages/multipart-parser/src/multipart-parser.node.ts +++ b/packages/multipart-parser/src/multipart-parser.node.ts @@ -1,6 +1,9 @@ // Re-export all core functionality export { MultipartParseError, + MaxHeaderSizeExceededError, + MaxFileSizeExceededError, + type ParseMultipartOptions, type MultipartParserOptions, MultipartParser, MultipartPart, diff --git a/packages/multipart-parser/src/multipart-parser.ts b/packages/multipart-parser/src/multipart-parser.ts index d31773bd020..e1e214bab86 100644 --- a/packages/multipart-parser/src/multipart-parser.ts +++ b/packages/multipart-parser/src/multipart-parser.ts @@ -1,6 +1,9 @@ export { - parseMultipart, MultipartParseError, + MaxHeaderSizeExceededError, + MaxFileSizeExceededError, + type ParseMultipartOptions, + parseMultipart, type MultipartParserOptions, MultipartParser, MultipartPart, From 64357cf9947ae8379a9513ea890f2b54f567ae86 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Fri, 24 Jan 2025 11:21:05 -0800 Subject: [PATCH 595/730] Add TarEntryHandler --- packages/tar-parser/src/lib/read-stream.ts | 12 ++++-------- packages/tar-parser/src/lib/tar.ts | 19 +++++++++---------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/packages/tar-parser/src/lib/read-stream.ts b/packages/tar-parser/src/lib/read-stream.ts index e33a40a91b0..44a873071b4 100644 --- a/packages/tar-parser/src/lib/read-stream.ts +++ b/packages/tar-parser/src/lib/read-stream.ts @@ -3,13 +3,9 @@ export async function* readStream(stream: ReadableStream<Uint8Array>): AsyncIterable<Uint8Array> { let reader = stream.getReader(); - try { - while (true) { - const { done, value } = await reader.read(); - if (done) break; - yield value; - } - } finally { - reader.releaseLock(); + while (true) { + const { done, value } = await reader.read(); + if (done) break; + yield value; } } diff --git a/packages/tar-parser/src/lib/tar.ts b/packages/tar-parser/src/lib/tar.ts index 07e457b9ecc..8fcf6143fea 100644 --- a/packages/tar-parser/src/lib/tar.ts +++ b/packages/tar-parser/src/lib/tar.ts @@ -151,6 +151,8 @@ type TarArchiveSource = | Iterable<Uint8Array> | AsyncIterable<Uint8Array>; +type TarEntryHandler = (entry: TarEntry) => void; + export type ParseTarOptions = ParseTarHeaderOptions; /** @@ -168,19 +170,16 @@ export type ParseTarOptions = ParseTarHeaderOptions; * @param handler A function to call for each entry in the archive * @returns A promise that resolves when the parse is finished */ -export async function parseTar( - archive: TarArchiveSource, - handler: (entry: TarEntry) => void, -): Promise<void>; +export async function parseTar(archive: TarArchiveSource, handler: TarEntryHandler): Promise<void>; export async function parseTar( archive: TarArchiveSource, options: ParseTarOptions, - handler: (entry: TarEntry) => void, + handler: TarEntryHandler, ): Promise<void>; export async function parseTar( archive: TarArchiveSource, - options: ParseTarOptions | ((entry: TarEntry) => void), - handler?: (entry: TarEntry) => void, + options: ParseTarOptions | TarEntryHandler, + handler?: TarEntryHandler, ): Promise<void> { let opts: ParseTarOptions | undefined; if (typeof options === 'function') { @@ -226,7 +225,7 @@ export class TarParser { * @param handler A function to call for each entry in the archive * @returns A promise that resolves when the parse is finished */ - async parse(archive: TarArchiveSource, handler: (entry: TarEntry) => void): Promise<void> { + async parse(archive: TarArchiveSource, handler: TarEntryHandler): Promise<void> { this.#reset(); let results: unknown[] = []; @@ -272,7 +271,7 @@ export class TarParser { this.#pax = null; } - #write(chunk: Uint8Array, handler: (entry: TarEntry) => void): void { + #write(chunk: Uint8Array, handler: TarEntryHandler): void { if (this.#buffer !== null) { this.#buffer = concatChunks(this.#buffer, chunk); } else { @@ -307,7 +306,7 @@ export class TarParser { } } - #parseHeader(handler: (entry: TarEntry) => void): void { + #parseHeader(handler: TarEntryHandler): void { let block = this.#read(TarBlockSize); if (isZeroBlock(block)) { From 99f3c54f978c3ffccc46ce80eeec86ceee07c5f8 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Fri, 24 Jan 2025 11:21:17 -0800 Subject: [PATCH 596/730] Release multipart-parser@0.8.0 --- packages/multipart-parser/CHANGELOG.md | 2 +- packages/multipart-parser/jsr.json | 2 +- packages/multipart-parser/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index ca269bec443..faca870504c 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.8.0 (2025-01-24) This release improves error handling and simplifies some of the internals of the parser. diff --git a/packages/multipart-parser/jsr.json b/packages/multipart-parser/jsr.json index e3896ba8c11..2bdb27c327b 100644 --- a/packages/multipart-parser/jsr.json +++ b/packages/multipart-parser/jsr.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.7.3", + "version": "0.8.0", "exports": "./src/multipart-parser.ts", "publish": { "include": [ diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 4a676d772dd..b063fe7cb92 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.7.3", + "version": "0.8.0", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson <mjijackson@gmail.com>", "repository": { From 8097ce8e080b3c60cd9bbafc13382f8ab1defc63 Mon Sep 17 00:00:00 2001 From: Michael Jackson <michael@jackson.us> Date: Sat, 25 Jan 2025 09:18:52 -0800 Subject: [PATCH 597/730] Update multipart-parser dep to v0.8 in form-data-parser Fixes #28 --- packages/form-data-parser/CHANGELOG.md | 22 +++++ .../form-data-parser/examples/node/README.md | 3 + .../examples/node/package.json | 18 ++++ .../form-data-parser/examples/node/server.js | 98 +++++++++++++++++++ .../examples/node/tsconfig.json | 12 +++ .../form-data-parser/src/lib/form-data.ts | 49 +++++----- .../multipart-parser/examples/node/README.md | 2 +- packages/multipart-parser/global.d.ts | 7 -- pnpm-lock.yaml | 22 +++++ pnpm-workspace.yaml | 1 + 10 files changed, 200 insertions(+), 34 deletions(-) create mode 100644 packages/form-data-parser/examples/node/README.md create mode 100644 packages/form-data-parser/examples/node/package.json create mode 100644 packages/form-data-parser/examples/node/server.js create mode 100644 packages/form-data-parser/examples/node/tsconfig.json diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index 9de53829ed5..43b39d98c3f 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -4,6 +4,28 @@ This is the changelog for [`form-data-parser`](https://github.com/mjackson/remix ## HEAD +- BREAKING CHANGE: Override `parseFormData` signature so the upload handler is always last in the argument list. `parserOptions` are now an optional 2nd arg. + +```ts +import { parseFormData } from '@mjackson/form-data-parser'; + +// before +await parseFormData( + request, + (fileUpload) => { + // ... + }, + { maxFileSize }, +); + +// after +await parseFormData(request, { maxFileSize }, (fileUpload) => { + // ... +}); +``` + +- Upgrade [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser) to v0.8 to fix an issue where errors would crash the process when `maxFileSize` was exceeded (see #28) +- Add an [example of how to use `form-data-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser/examples/node) together with [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage) to handle multipart uploads on Node.js - Expand `FileUploadHandler` interface to support returning `Blob` from the upload handler, which is the superclass of `File` ## v0.6.0 (2025-01-15) diff --git a/packages/form-data-parser/examples/node/README.md b/packages/form-data-parser/examples/node/README.md new file mode 100644 index 00000000000..05546e455c3 --- /dev/null +++ b/packages/form-data-parser/examples/node/README.md @@ -0,0 +1,3 @@ +# form-data-parser Node Example + +This example is a [Node.js server](https://nodejs.org/) that handles file uploads and streams them to a tmp file on disk. diff --git a/packages/form-data-parser/examples/node/package.json b/packages/form-data-parser/examples/node/package.json new file mode 100644 index 00000000000..41d4fa5f416 --- /dev/null +++ b/packages/form-data-parser/examples/node/package.json @@ -0,0 +1,18 @@ +{ + "name": "form-data-parser-node-example", + "private": true, + "type": "module", + "dependencies": { + "@mjackson/file-storage": "workspace:*", + "@mjackson/form-data-parser": "workspace:*", + "@mjackson/multipart-parser": "workspace:*", + "@mjackson/node-fetch-server": "workspace:*" + }, + "devDependencies": { + "@types/node": "^20.14.10", + "typescript": "^5.7.2" + }, + "scripts": { + "start": "node server.js" + } +} diff --git a/packages/form-data-parser/examples/node/server.js b/packages/form-data-parser/examples/node/server.js new file mode 100644 index 00000000000..d11f6fe2fd3 --- /dev/null +++ b/packages/form-data-parser/examples/node/server.js @@ -0,0 +1,98 @@ +import * as http from 'node:http'; +import * as os from 'node:os'; +import { LocalFileStorage } from '@mjackson/file-storage/local'; +import { parseFormData } from '@mjackson/form-data-parser'; +import { MultipartParseError, MaxFileSizeExceededError } from '@mjackson/multipart-parser'; +import { createRequestListener } from '@mjackson/node-fetch-server'; + +const PORT = 3000; +const maxFileSize = 1000; + +const fileStorage = new LocalFileStorage(os.tmpdir()); + +const server = http.createServer( + createRequestListener(async (request) => { + if (request.method === 'GET') { + return new Response( + `<!DOCTYPE html> +<html> + <head> + <title>form-data-parser Node Example + + +

form-data-parser Node Example

+ +

Enter some text:

+

Select an image:

+

+ + +`, + { + headers: { + 'Content-Type': 'text/html', + }, + }, + ); + } + + if (request.method === 'POST') { + try { + let formData = await parseFormData(request, { maxFileSize }, async (fileUpload) => { + let key = 'image-upload'; + await fileStorage.set(key, fileUpload); + let file = await fileStorage.get(key); + return file && file.size === 0 ? null : file; + }); + + let text1 = formData.get('text1'); + let image1 = formData.get('image1'); + + let imgSrc = ''; + if (image1) { + let imageFile = /** @type File */ (image1); + let buffer = await imageFile.arrayBuffer(); + let base64 = Buffer.from(buffer).toString('base64'); + imgSrc = `data:${imageFile.type};base64,${base64}`; + } + + return new Response( + ` + + + form-data-parser Submitted Data + + +

form-data-parser Submitted Data

+ ${text1 ? `

You entered this text: ${text1}

` : '

You did not enter any text.

'} + ${image1 ? `

You uploaded this image:

` : '

You did not upload an image.

'} + +`, + { + headers: { + 'Content-Type': 'text/html', + }, + }, + ); + } catch (error) { + if (error instanceof MaxFileSizeExceededError) { + return new Response(error.message, { status: 413 }); + } + + if (error instanceof MultipartParseError) { + return new Response(error.message, { status: 400 }); + } + + console.error(error); + + return new Response('Internal Server Error', { status: 500 }); + } + } + + return new Response('Method Not Allowed', { status: 405 }); + }), +); + +server.listen(PORT, () => { + console.log(`Server listening on http://localhost:${PORT} ...`); +}); diff --git a/packages/form-data-parser/examples/node/tsconfig.json b/packages/form-data-parser/examples/node/tsconfig.json new file mode 100644 index 00000000000..2b13bc370b0 --- /dev/null +++ b/packages/form-data-parser/examples/node/tsconfig.json @@ -0,0 +1,12 @@ +{ + "include": ["server.js"], + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "module": "NodeNext", + "moduleResolution": "NodeNext", + "types": ["node"], + "noEmit": true, + "strict": true + } +} diff --git a/packages/form-data-parser/src/lib/form-data.ts b/packages/form-data-parser/src/lib/form-data.ts index 25d6e8d270a..e08682e4090 100644 --- a/packages/form-data-parser/src/lib/form-data.ts +++ b/packages/form-data-parser/src/lib/form-data.ts @@ -87,47 +87,44 @@ async function defaultFileUploadHandler(file: FileUpload): Promise { */ export async function parseFormData( request: Request, - uploadHandler: FileUploadHandler = defaultFileUploadHandler, - parserOptions?: MultipartParserOptions, + handler?: FileUploadHandler, +): Promise; +export async function parseFormData( + request: Request, + parserOptions: MultipartParserOptions, + handler?: FileUploadHandler, +): Promise; +export async function parseFormData( + request: Request, + parserOptions?: MultipartParserOptions | FileUploadHandler, + handler: FileUploadHandler = defaultFileUploadHandler, ): Promise { + if (typeof parserOptions === 'function') { + handler = parserOptions; + parserOptions = {}; + } else if (parserOptions == null) { + parserOptions = {}; + } + if (!isMultipartRequest(request)) { return request.formData(); } let formData = new FormData(); - let promises: Promise[] = []; - for await (let part of parseMultipartRequest(request, parserOptions)) { + await parseMultipartRequest(request, parserOptions, async (part) => { let fieldName = part.name; - - if (!fieldName) continue; + if (!fieldName) return; if (part.isFile) { - let value = uploadHandler(new FileUpload(part)); - + let value = await handler(new FileUpload(part)); if (value != null) { - if (isPromise(value)) { - promises.push( - value.then((asyncValue) => { - if (asyncValue != null) { - formData.append(fieldName, asyncValue); - } - }), - ); - } else { - formData.append(fieldName, value); - } + formData.append(fieldName, value); } } else { formData.append(fieldName, await part.text()); } - } - - await Promise.all(promises); + }); return formData; } - -function isPromise(obj: unknown): obj is Promise { - return obj != null && typeof (obj as any).then === 'function'; -} diff --git a/packages/multipart-parser/examples/node/README.md b/packages/multipart-parser/examples/node/README.md index ac7af04f8fb..08f14bbffe3 100644 --- a/packages/multipart-parser/examples/node/README.md +++ b/packages/multipart-parser/examples/node/README.md @@ -1,3 +1,3 @@ # multipart-parser Node Example -This example is a simple [Node.js server](https://nodejs.org/) that handles file uploads and streams them to a tmp file on disk. +This example is a [Node.js server](https://nodejs.org/) that handles file uploads and streams them to a tmp file on disk. diff --git a/packages/multipart-parser/global.d.ts b/packages/multipart-parser/global.d.ts index dbb97336eb9..b41d4c606fe 100644 --- a/packages/multipart-parser/global.d.ts +++ b/packages/multipart-parser/global.d.ts @@ -1,8 +1 @@ declare var Deno: { version: { deno: string } } | undefined; - -// See https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62651 - -interface ReadableStream { - values(options?: { preventCancel?: boolean }): AsyncIterableIterator; - [Symbol.asyncIterator](): AsyncIterableIterator; -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 83a2dc84b17..1e21998bbfe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,6 +54,28 @@ importers: specifier: ^8.3.5 version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.7.2) + packages/form-data-parser/examples/node: + dependencies: + '@mjackson/file-storage': + specifier: workspace:* + version: link:../../../file-storage + '@mjackson/form-data-parser': + specifier: workspace:* + version: link:../.. + '@mjackson/multipart-parser': + specifier: workspace:* + version: link:../../../multipart-parser + '@mjackson/node-fetch-server': + specifier: workspace:* + version: link:../../../node-fetch-server + devDependencies: + '@types/node': + specifier: ^20.14.10 + version: 20.16.1 + typescript: + specifier: ^5.7.2 + version: 5.7.2 + packages/headers: devDependencies: '@types/node': diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index b6f382b8a1d..dc4b22e4ab0 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,5 +1,6 @@ packages: - packages/* + - packages/form-data-parser/examples/* - packages/multipart-parser/bench - packages/multipart-parser/examples/* - packages/node-fetch-server/bench From 8d3d98c21df935b9119e8e7ac8cbdeb65d319278 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 25 Jan 2025 09:40:59 -0800 Subject: [PATCH 598/730] Handle stream errors in `writeFile` --- packages/lazy-file/CHANGELOG.md | 6 +++++- packages/lazy-file/src/fs.ts | 20 +++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/lazy-file/CHANGELOG.md b/packages/lazy-file/CHANGELOG.md index 1653b32dd0a..abcabe46f38 100644 --- a/packages/lazy-file/CHANGELOG.md +++ b/packages/lazy-file/CHANGELOG.md @@ -2,9 +2,13 @@ This is the changelog for [`lazy-file`](https://github.com/mjackson/remix-the-web/tree/main/packages/lazy-file). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Handle stream errors in `lazy-file/fs`' `writeFile`. When there is an error in the stream, call `writeStream.end()` on the underlying file stream before rejecting the promise. + ## v3.3.0 (2024-11-14) -- Added CommonJS build +- Add CommonJS build ## v3.2.0 (2024-09-12) diff --git a/packages/lazy-file/src/fs.ts b/packages/lazy-file/src/fs.ts index f30e03c2209..a75e6e4833b 100644 --- a/packages/lazy-file/src/fs.ts +++ b/packages/lazy-file/src/fs.ts @@ -77,18 +77,24 @@ export { type OpenFileOptions as GetFileOptions, openFile as getFile }; * @returns A promise that resolves when the file is written */ export function writeFile(to: string | number | fs.promises.FileHandle, file: File): Promise { - return new Promise(async (resolve) => { + return new Promise(async (resolve, reject) => { let writeStream = typeof to === 'string' ? fs.createWriteStream(to) : fs.createWriteStream('ignored', { fd: to }); - for await (let chunk of file.stream()) { - writeStream.write(chunk); - } + try { + for await (let chunk of file.stream()) { + writeStream.write(chunk); + } - writeStream.end(() => { - resolve(); - }); + writeStream.end(() => { + resolve(); + }); + } catch (error) { + writeStream.end(() => { + reject(error); + }); + } }); } From afe93436238591b1f6f14c3f99bec548a5915760 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 25 Jan 2025 09:43:11 -0800 Subject: [PATCH 599/730] Iterate manually over `response.body` I'm honestly not sure if there is a problem in Node itself or in undici, but I'm seeing issues with the stream reader not releasing its lock properly when using `for await...of` to iterate over `response.body` in `sendResponse`. In any case, there may be a variety of `Response` implementations that people eventually want to use with this, and async iterators are hard to get right, so dropping down to the lower-level `getReader()` API for stream iteration seems like a prudent move. --- packages/node-fetch-server/CHANGELOG.md | 4 ++++ packages/node-fetch-server/global.d.ts | 6 ------ packages/node-fetch-server/src/lib/read-stream.ts | 9 +++++++++ packages/node-fetch-server/src/lib/request-listener.ts | 3 ++- 4 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 packages/node-fetch-server/global.d.ts create mode 100644 packages/node-fetch-server/src/lib/read-stream.ts diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 939a79efbd9..fafe4bc96cc 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -2,6 +2,10 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Iterate manually over response bodies in `sendResponse` instead of using `for await...of`. This seems to avoid an issue where the iterator tries to read from a stream after the lock has been released. + ## v0.5.0 (2024-12-09) - Expose `createHeaders(req: http.IncomingMessage): Headers` API for creating headers from the headers of incoming request objects. diff --git a/packages/node-fetch-server/global.d.ts b/packages/node-fetch-server/global.d.ts deleted file mode 100644 index b8041179bc5..00000000000 --- a/packages/node-fetch-server/global.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -// See https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62651 - -interface ReadableStream { - values(options?: { preventCancel?: boolean }): AsyncIterableIterator; - [Symbol.asyncIterator](): AsyncIterableIterator; -} diff --git a/packages/node-fetch-server/src/lib/read-stream.ts b/packages/node-fetch-server/src/lib/read-stream.ts new file mode 100644 index 00000000000..e12edd7d74a --- /dev/null +++ b/packages/node-fetch-server/src/lib/read-stream.ts @@ -0,0 +1,9 @@ +export async function* readStream(stream: ReadableStream): AsyncIterable { + let reader = stream.getReader(); + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + yield value; + } +} diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 5b6d8e0f9b2..14de6c15049 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -1,6 +1,7 @@ import type * as http from 'node:http'; import { type ClientAddress, type ErrorHandler, type FetchHandler } from './fetch-handler.ts'; +import { readStream } from './read-stream.ts'; export interface RequestListenerOptions { /** @@ -204,7 +205,7 @@ export async function sendResponse(res: http.ServerResponse, response: Response) res.writeHead(response.status, headers); if (response.body != null && res.req.method !== 'HEAD') { - for await (let chunk of response.body) { + for await (let chunk of readStream(response.body)) { res.write(chunk); } } From 1c641189aac45bef0edb8b5e6fa64666d531917a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 25 Jan 2025 09:47:44 -0800 Subject: [PATCH 600/730] Release node-fetch-server@0.5.1 --- packages/node-fetch-server/CHANGELOG.md | 2 +- packages/node-fetch-server/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index fafe4bc96cc..bfdc9908e5a 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.5.1 (2025-01-25) - Iterate manually over response bodies in `sendResponse` instead of using `for await...of`. This seems to avoid an issue where the iterator tries to read from a stream after the lock has been released. diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 93388880cd4..e8519c2dff4 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/node-fetch-server", - "version": "0.5.0", + "version": "0.5.1", "description": "Build servers for Node.js using the web fetch API", "author": "Michael Jackson ", "repository": { From 01f9dcb0f42f0bb1a8db8e553430fb07eb11c669 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 25 Jan 2025 09:49:48 -0800 Subject: [PATCH 601/730] Release lazy-file@3.3.1 --- packages/lazy-file/CHANGELOG.md | 2 +- packages/lazy-file/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/lazy-file/CHANGELOG.md b/packages/lazy-file/CHANGELOG.md index abcabe46f38..308e0863ad0 100644 --- a/packages/lazy-file/CHANGELOG.md +++ b/packages/lazy-file/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`lazy-file`](https://github.com/mjackson/remix-the-web/tree/main/packages/lazy-file). It follows [semantic versioning](https://semver.org/). -## HEAD +## v3.3.1 (2025-01-25) - Handle stream errors in `lazy-file/fs`' `writeFile`. When there is an error in the stream, call `writeStream.end()` on the underlying file stream before rejecting the promise. diff --git a/packages/lazy-file/package.json b/packages/lazy-file/package.json index 3a2a534774d..325ab38e8f2 100644 --- a/packages/lazy-file/package.json +++ b/packages/lazy-file/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/lazy-file", - "version": "3.3.0", + "version": "3.3.1", "description": "Lazy, streaming files for JavaScript", "author": "Michael Jackson ", "repository": { From 7318e459d1c9f7ba4f3292e890d8e7d5008a6c3d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 25 Jan 2025 10:56:49 -0800 Subject: [PATCH 602/730] Release form-data-parser@0.7.0 --- packages/form-data-parser/CHANGELOG.md | 2 +- packages/form-data-parser/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/form-data-parser/CHANGELOG.md b/packages/form-data-parser/CHANGELOG.md index 43b39d98c3f..07f7179afeb 100644 --- a/packages/form-data-parser/CHANGELOG.md +++ b/packages/form-data-parser/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`form-data-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.7.0 (2025-01-25) - BREAKING CHANGE: Override `parseFormData` signature so the upload handler is always last in the argument list. `parserOptions` are now an optional 2nd arg. diff --git a/packages/form-data-parser/package.json b/packages/form-data-parser/package.json index 169ca08ab2a..cd4f9b7140c 100644 --- a/packages/form-data-parser/package.json +++ b/packages/form-data-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/form-data-parser", - "version": "0.6.0", + "version": "0.7.0", "description": "A request.formData() wrapper with streaming file upload handling", "author": "Michael Jackson ", "repository": { From 1f41583519b8ab1bdbb52421992f865415417bdb Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 25 Jan 2025 11:05:12 -0800 Subject: [PATCH 603/730] Increase max upload size --- .../form-data-parser/examples/node/server.js | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/form-data-parser/examples/node/server.js b/packages/form-data-parser/examples/node/server.js index d11f6fe2fd3..0c3c5a6a6e1 100644 --- a/packages/form-data-parser/examples/node/server.js +++ b/packages/form-data-parser/examples/node/server.js @@ -6,7 +6,8 @@ import { MultipartParseError, MaxFileSizeExceededError } from '@mjackson/multipa import { createRequestListener } from '@mjackson/node-fetch-server'; const PORT = 3000; -const maxFileSize = 1000; + +const oneMb = 1024 * 1024; const fileStorage = new LocalFileStorage(os.tmpdir()); @@ -23,7 +24,7 @@ const server = http.createServer(

form-data-parser Node Example

Enter some text:

-

Select an image:

+

Select an image (max size 10MB):

@@ -38,12 +39,16 @@ const server = http.createServer( if (request.method === 'POST') { try { - let formData = await parseFormData(request, { maxFileSize }, async (fileUpload) => { - let key = 'image-upload'; - await fileStorage.set(key, fileUpload); - let file = await fileStorage.get(key); - return file && file.size === 0 ? null : file; - }); + let formData = await parseFormData( + request, + { maxFileSize: 10 * oneMb }, + async (fileUpload) => { + let key = 'image-upload'; + await fileStorage.set(key, fileUpload); + let file = await fileStorage.get(key); + return file && file.size === 0 ? null : file; + }, + ); let text1 = formData.get('text1'); let image1 = formData.get('image1'); From 42f1e8d352101d756d2a4c28d73f5c6271171822 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 25 Jan 2025 11:32:50 -0800 Subject: [PATCH 604/730] Add `fileStorage.put(key, file)` method --- packages/file-storage/CHANGELOG.md | 13 +++++++++++ packages/file-storage/src/lib/file-storage.ts | 23 ++++++++++++++++--- .../src/lib/local-file-storage.ts | 5 ++++ .../src/lib/memory-file-storage.ts | 5 ++++ 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 13522cc69fc..c57aee9a3fd 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -2,6 +2,19 @@ This is the changelog for [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Add `fileStorage.put(key, file)` method as a convenience around `fileStorage.set(key, file)` + `fileStorage.get(key)`, which is a very common pattern when you need immediate access to the file you just put in storage + +```ts +// before +await fileStorage.set(key, file); +let newFile = await fileStorage.get(key)!; + +// after +let newFile = await fileStorage.put(key, file); +``` + ## v0.4.1 (2025-01-10) - Fix missing types for `file-storage/local` in npm package diff --git a/packages/file-storage/src/lib/file-storage.ts b/packages/file-storage/src/lib/file-storage.ts index c895f37b0aa..7a1b695931d 100644 --- a/packages/file-storage/src/lib/file-storage.ts +++ b/packages/file-storage/src/lib/file-storage.ts @@ -3,19 +3,36 @@ */ export interface FileStorage { /** - * Returns `true` if a file with the given key exists, `false` otherwise. + * Checks if a file with the given key exists. + * @param key The key to look up + * @returns `true` if a file with the given key exists, `false` otherwise */ has(key: string): boolean | Promise; /** - * Puts a file in storage at the given key. + * Puts a [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in storage at the given key. + * @param key The key to store the file under + * @param file The file to store + * @returns A promise that resolves when the file has been stored */ set(key: string, file: File): void | Promise; /** - * Returns the file with the given key, or `null` if no such key exists. + * Gets the [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) with a given key. + * @param key The key to look up + * @returns The file with the given key, or `null` if no such key exists */ get(key: string): File | null | Promise; + /** + * Puts a [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in storage and returns + * a new file backed by this storage. + * @param key The key to store the file under + * @param file The file to store + * @returns A new File object backed by this storage + */ + put(key: string, file: File): File | Promise; /** * Removes the file with the given key from storage. + * @param key The key to remove + * @returns A promise that resolves when the file has been removed */ remove(key: string): void | Promise; } diff --git a/packages/file-storage/src/lib/local-file-storage.ts b/packages/file-storage/src/lib/local-file-storage.ts index 87fc3a48b3b..619f572e84a 100644 --- a/packages/file-storage/src/lib/local-file-storage.ts +++ b/packages/file-storage/src/lib/local-file-storage.ts @@ -94,6 +94,11 @@ export class LocalFileStorage implements FileStorage { } } + async put(key: string, file: File): Promise { + await this.set(key, file); + return (await this.get(key))!; + } + async remove(key: string): Promise { let { filePath, metaPath } = await this.#getPaths(key); diff --git a/packages/file-storage/src/lib/memory-file-storage.ts b/packages/file-storage/src/lib/memory-file-storage.ts index 13ece16a3d4..5afae3a8064 100644 --- a/packages/file-storage/src/lib/memory-file-storage.ts +++ b/packages/file-storage/src/lib/memory-file-storage.ts @@ -18,6 +18,11 @@ export class MemoryFileStorage implements FileStorage { return this.#map.get(key) ?? null; } + put(key: string, file: File): File { + this.set(key, file); + return this.get(key)!; + } + remove(key: string): void { this.#map.delete(key); } From 200a83dc80bfbe548ee6bd4443c9fcf7734f1eb0 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 25 Jan 2025 11:33:46 -0800 Subject: [PATCH 605/730] Release file-storage@0.5.0 --- packages/file-storage/CHANGELOG.md | 2 +- packages/file-storage/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index c57aee9a3fd..da3c46fe146 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.5.0 (2025-01-25) - Add `fileStorage.put(key, file)` method as a convenience around `fileStorage.set(key, file)` + `fileStorage.get(key)`, which is a very common pattern when you need immediate access to the file you just put in storage diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index 8eef6a2422a..a2fc426b5e1 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/file-storage", - "version": "0.4.1", + "version": "0.5.0", "description": "Key/value storage for JavaScript File objects", "author": "Michael Jackson ", "repository": { From 03cecb9a33caaf3a0f488868cd9e9b5d16f307bf Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 25 Jan 2025 11:38:28 -0800 Subject: [PATCH 606/730] Update example --- packages/form-data-parser/examples/node/server.js | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/packages/form-data-parser/examples/node/server.js b/packages/form-data-parser/examples/node/server.js index 0c3c5a6a6e1..1ece4b81aac 100644 --- a/packages/form-data-parser/examples/node/server.js +++ b/packages/form-data-parser/examples/node/server.js @@ -39,16 +39,10 @@ const server = http.createServer( if (request.method === 'POST') { try { - let formData = await parseFormData( - request, - { maxFileSize: 10 * oneMb }, - async (fileUpload) => { - let key = 'image-upload'; - await fileStorage.set(key, fileUpload); - let file = await fileStorage.get(key); - return file && file.size === 0 ? null : file; - }, - ); + let formData = await parseFormData(request, { maxFileSize: 10 * oneMb }, async (upload) => { + let file = await fileStorage.put('image-upload', upload); + return file.size === 0 ? null : file; + }); let text1 = formData.get('text1'); let image1 = formData.get('image1'); From c4ab401a6ddd0ecd341388f46a4c9b46a99069c6 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 25 Jan 2025 15:17:15 -0800 Subject: [PATCH 607/730] Simplify example --- packages/form-data-parser/examples/node/server.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/form-data-parser/examples/node/server.js b/packages/form-data-parser/examples/node/server.js index 1ece4b81aac..c8a3c86ba8d 100644 --- a/packages/form-data-parser/examples/node/server.js +++ b/packages/form-data-parser/examples/node/server.js @@ -47,12 +47,11 @@ const server = http.createServer( let text1 = formData.get('text1'); let image1 = formData.get('image1'); - let imgSrc = ''; + let dataUrl = ''; if (image1) { let imageFile = /** @type File */ (image1); - let buffer = await imageFile.arrayBuffer(); - let base64 = Buffer.from(buffer).toString('base64'); - imgSrc = `data:${imageFile.type};base64,${base64}`; + let buffer = Buffer.from(await imageFile.arrayBuffer()); + dataUrl = `data:${imageFile.type};base64,${buffer.toString('base64')}`; } return new Response( @@ -64,7 +63,7 @@ const server = http.createServer(

form-data-parser Submitted Data

${text1 ? `

You entered this text: ${text1}

` : '

You did not enter any text.

'} - ${image1 ? `

You uploaded this image:

` : '

You did not upload an image.

'} + ${image1 ? `

You uploaded this image:

` : '

You did not upload an image.

'} `, { From 6ffc7533f80fe6947dc1a14e42641af0eb722dad Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 25 Jan 2025 15:25:27 -0800 Subject: [PATCH 608/730] Create a unique temp directory for storing uploaded files --- packages/form-data-parser/examples/node/server.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/form-data-parser/examples/node/server.js b/packages/form-data-parser/examples/node/server.js index c8a3c86ba8d..1b6f25153e6 100644 --- a/packages/form-data-parser/examples/node/server.js +++ b/packages/form-data-parser/examples/node/server.js @@ -1,15 +1,18 @@ +import * as fsp from 'node:fs/promises'; import * as http from 'node:http'; import * as os from 'node:os'; +import * as path from 'node:path'; import { LocalFileStorage } from '@mjackson/file-storage/local'; import { parseFormData } from '@mjackson/form-data-parser'; import { MultipartParseError, MaxFileSizeExceededError } from '@mjackson/multipart-parser'; import { createRequestListener } from '@mjackson/node-fetch-server'; const PORT = 3000; - const oneMb = 1024 * 1024; -const fileStorage = new LocalFileStorage(os.tmpdir()); +const fileStorage = new LocalFileStorage( + await fsp.mkdtemp(path.join(os.tmpdir(), 'form-data-parser-')), +); const server = http.createServer( createRequestListener(async (request) => { From 661604d0a4a360d4a446528b00513e2028a4df7f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 25 Jan 2025 21:02:58 -0800 Subject: [PATCH 609/730] Simplify example even further --- .../form-data-parser/examples/node/server.js | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/form-data-parser/examples/node/server.js b/packages/form-data-parser/examples/node/server.js index 1b6f25153e6..66e62ec2110 100644 --- a/packages/form-data-parser/examples/node/server.js +++ b/packages/form-data-parser/examples/node/server.js @@ -14,6 +14,12 @@ const fileStorage = new LocalFileStorage( await fsp.mkdtemp(path.join(os.tmpdir(), 'form-data-parser-')), ); +/** @type (file: File) => Promise */ +async function getDataUrl(file) { + let buffer = Buffer.from(await file.arrayBuffer()); + return `data:${file.type};base64,${buffer.toString('base64')}`; +} + const server = http.createServer( createRequestListener(async (request) => { if (request.method === 'GET') { @@ -47,15 +53,8 @@ const server = http.createServer( return file.size === 0 ? null : file; }); - let text1 = formData.get('text1'); - let image1 = formData.get('image1'); - - let dataUrl = ''; - if (image1) { - let imageFile = /** @type File */ (image1); - let buffer = Buffer.from(await imageFile.arrayBuffer()); - dataUrl = `data:${imageFile.type};base64,${buffer.toString('base64')}`; - } + let text = /** @type string */ (formData.get('text1')); + let image = /** @type File | null */ (formData.get('image1')); return new Response( ` @@ -65,8 +64,8 @@ const server = http.createServer(

form-data-parser Submitted Data

- ${text1 ? `

You entered this text: ${text1}

` : '

You did not enter any text.

'} - ${image1 ? `

You uploaded this image:

` : '

You did not upload an image.

'} + ${text ? `

You entered this text: ${text}

` : '

You did not enter any text.

'} + ${image ? `

You uploaded this image:

` : '

You did not upload an image.

'} `, { From eefa6d877c5a9423444baeb642929bec1a735f34 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 26 Jan 2025 21:16:47 -0800 Subject: [PATCH 610/730] Add `storage.list(options)` Fixes #32 --- packages/file-storage/CHANGELOG.md | 33 ++++- packages/file-storage/src/file-storage.ts | 2 +- packages/file-storage/src/lib/file-storage.ts | 126 +++++++++++++++-- .../src/lib/local-file-storage.test.ts | 70 ++++++++- .../src/lib/local-file-storage.ts | 133 +++++++++++++----- .../src/lib/memory-file-storage.test.ts | 63 +++++++++ .../src/lib/memory-file-storage.ts | 58 +++++++- packages/file-storage/src/local.ts | 2 +- packages/file-storage/src/memory.ts | 2 +- 9 files changed, 421 insertions(+), 68 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index da3c46fe146..c74276fb8ba 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -2,17 +2,42 @@ This is the changelog for [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Add `storage.list(options)` for listing files in storage. + +The following `options` are available: + +- `cursor`: An opaque string that allows you to paginate over the keys in storage +- `includeMetadata`: If `true`, include file metadata in the result +- `limit`: The maximum number of files to return +- `prefix`: Only return keys that start with this string + +Pagination is done via an opaque `cursor` property in the list result object. If it is not `undefined`, there are more files to list. You can list them by passing the `cursor` back in the `options` object on the next call. + +```ts +let result = await storage.list(); + +console.log(result.files); + +if (result.cursor !== undefined) { + let result2 = await storage.list({ cursor: result.cursor }); +} +``` + +Objects in the `files` array have only a `key` property by default. If you pass `includeMetadata: true` in the options, they will also have `lastModified`, `name`, `size`, and `type` properties. + ## v0.5.0 (2025-01-25) -- Add `fileStorage.put(key, file)` method as a convenience around `fileStorage.set(key, file)` + `fileStorage.get(key)`, which is a very common pattern when you need immediate access to the file you just put in storage +- Add `storage.put(key, file)` method as a convenience around `storage.set(key, file)` + `storage.get(key)`, which is a very common pattern when you need immediate access to the file you just put in storage ```ts // before -await fileStorage.set(key, file); -let newFile = await fileStorage.get(key)!; +await storage.set(key, file); +let newFile = await storage.get(key)!; // after -let newFile = await fileStorage.put(key, file); +let newFile = await storage.put(key, file); ``` ## v0.4.1 (2025-01-10) diff --git a/packages/file-storage/src/file-storage.ts b/packages/file-storage/src/file-storage.ts index 7647353f727..9dbaaee15b1 100644 --- a/packages/file-storage/src/file-storage.ts +++ b/packages/file-storage/src/file-storage.ts @@ -1 +1 @@ -export { type FileStorage } from './lib/file-storage.js'; +export { type FileStorage } from './lib/file-storage.ts'; diff --git a/packages/file-storage/src/lib/file-storage.ts b/packages/file-storage/src/lib/file-storage.ts index 7a1b695931d..ea49d31c6c9 100644 --- a/packages/file-storage/src/lib/file-storage.ts +++ b/packages/file-storage/src/lib/file-storage.ts @@ -3,36 +3,134 @@ */ export interface FileStorage { /** - * Checks if a file with the given key exists. + * Get a [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) at the given key. * @param key The key to look up - * @returns `true` if a file with the given key exists, `false` otherwise + * @returns The file with the given key, or `null` if no such key exists */ - has(key: string): boolean | Promise; + get(key: string): File | null | Promise; + /** - * Puts a [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in storage at the given key. - * @param key The key to store the file under - * @param file The file to store - * @returns A promise that resolves when the file has been stored + * Check if a file with the given key exists. + * @param key The key to look up + * @returns `true` if a file with the given key exists, `false` otherwise */ - set(key: string, file: File): void | Promise; + has(key: string): boolean | Promise; + /** - * Gets the [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) with a given key. - * @param key The key to look up - * @returns The file with the given key, or `null` if no such key exists + * List the files in storage. + * + * The following `options` are available: + * + * - `cursor`: An opaque string that allows you to paginate over the keys in storage + * - `includeMetadata`: If `true`, include file metadata in the result + * - `limit`: The maximum number of files to return + * - `prefix`: Only return keys that start with this string + * + * Pagination is done via an opaque `cursor` property in the list result object. If it is not + * `undefined`, there are more files to list. You can list them by passing the `cursor` back + * in the `options` object on the next call. + * + * ```ts + * let result = await storage.list(); + * + * console.log(result.files); + * + * if (result.cursor !== undefined) { + * let result2 = await storage.list({ cursor: result.cursor }); + * } + * ``` + * + * Objects in the `files` array have only a `key` property by default. If you pass + * `includeMetadata: true` in the options, they will also have `lastModified`, `name`, `size`, and + * `type` properties. + * + * @param options Options for the list operation + * @returns An object with an array of `files` and an optional `cursor` property */ - get(key: string): File | null | Promise; + list(options?: T): ListResult | Promise>; + /** - * Puts a [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in storage and returns + * Put a [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in storage and return * a new file backed by this storage. * @param key The key to store the file under * @param file The file to store * @returns A new File object backed by this storage */ put(key: string, file: File): File | Promise; + /** - * Removes the file with the given key from storage. + * Remove the file with the given key from storage. * @param key The key to remove * @returns A promise that resolves when the file has been removed */ remove(key: string): void | Promise; + + /** + * Put a [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in storage at the given + * key. + * @param key The key to store the file under + * @param file The file to store + * @returns A promise that resolves when the file has been stored + */ + set(key: string, file: File): void | Promise; +} + +export interface FileKey { + /** + * The key of the file in storage. + */ + key: string; +} + +/** + * Metadata about a file in storage. + */ +export interface FileMetadata extends FileKey { + /** + * The last modified time of the file (in ms since the Unix epoch). + */ + lastModified: number; + /** + * The name of the file. + */ + name: string; + /** + * The size of the file in bytes. + */ + size: number; + /** + * The MIME type of the file. + */ + type: string; +} + +export interface ListOptions { + /** + * An opaque string that allows you to paginate over the keys in storage. + */ + cursor?: string; + /** + * If `true`, include file metadata in the result. + */ + includeMetadata?: boolean; + /** + * The maximum number of files to return. + */ + limit?: number; + /** + * Only return files with keys that start with this prefix. + */ + prefix?: string; +} + +export interface ListResult { + /** + * An opaque string that allows you to paginate over the keys in storage. Pass this back in the + * `options` object on the next `list()` call to get the next page of results. + */ + cursor?: string; + /** + * A list of the files in storage. + */ + files: (T extends { includeMetadata: true } ? FileMetadata : FileKey)[]; } diff --git a/packages/file-storage/src/lib/local-file-storage.test.ts b/packages/file-storage/src/lib/local-file-storage.test.ts index 335fa396e51..0befbd2978c 100644 --- a/packages/file-storage/src/lib/local-file-storage.test.ts +++ b/packages/file-storage/src/lib/local-file-storage.test.ts @@ -1,5 +1,5 @@ import * as assert from 'node:assert/strict'; -import { after, describe, it } from 'node:test'; +import { afterEach, describe, it } from 'node:test'; import * as fs from 'node:fs'; import * as path from 'node:path'; @@ -10,7 +10,7 @@ const __dirname = new URL('.', import.meta.url).pathname; describe('LocalFileStorage', () => { let directory = path.resolve(__dirname, '../../test-local-file-storage'); - after(() => { + afterEach(() => { fs.rmSync(directory, { recursive: true }); }); @@ -44,6 +44,72 @@ describe('LocalFileStorage', () => { assert.equal(await storage.get('hello'), null); }); + it('lists files with pagination', async () => { + let storage = new LocalFileStorage(directory); + let allKeys = ['a', 'b', 'c', 'd', 'e']; + + await Promise.all( + allKeys.map((key) => + storage.set(key, new File([`Hello ${key}!`], `hello.txt`, { type: 'text/plain' })), + ), + ); + + let { cursor, files } = await storage.list(); + assert.equal(cursor, undefined); + assert.equal(files.length, 5); + assert.deepEqual(files.map((f) => f.key).sort(), allKeys); + + let { cursor: cursor1, files: files1 } = await storage.list({ limit: 0 }); + assert.equal(cursor1, undefined); + assert.equal(files1.length, 0); + + let { cursor: cursor2, files: files2 } = await storage.list({ limit: 2 }); + assert.notEqual(cursor2, undefined); + assert.equal(files2.length, 2); + + let { cursor: cursor3, files: files3 } = await storage.list({ cursor: cursor2 }); + assert.equal(cursor3, undefined); + assert.equal(files3.length, 3); + + assert.deepEqual([...files2, ...files3].map((f) => f.key).sort(), allKeys); + }); + + it('lists files by key prefix', async () => { + let storage = new LocalFileStorage(directory); + let allKeys = ['a', 'b', 'b/c', 'c', 'd']; + + await Promise.all( + allKeys.map((key) => + storage.set(key, new File([`Hello ${key}!`], `hello.txt`, { type: 'text/plain' })), + ), + ); + + let { cursor, files } = await storage.list({ prefix: 'b' }); + assert.equal(cursor, undefined); + assert.equal(files.length, 2); + assert.deepEqual(files.map((f) => f.key).sort(), ['b', 'b/c']); + }); + + it('lists files with metadata', async () => { + let storage = new LocalFileStorage(directory); + let allKeys = ['a', 'b', 'c', 'd', 'e']; + + await Promise.all( + allKeys.map((key) => + storage.set(key, new File([`Hello ${key}!`], `hello.txt`, { type: 'text/plain' })), + ), + ); + + let { cursor, files } = await storage.list({ includeMetadata: true }); + assert.equal(cursor, undefined); + assert.equal(files.length, 5); + assert.deepEqual(files.map((f) => f.key).sort(), allKeys); + files.forEach((f) => assert.ok('lastModified' in f)); + files.forEach((f) => assert.ok('name' in f)); + files.forEach((f) => assert.ok('size' in f)); + files.forEach((f) => assert.ok('type' in f)); + }); + it('handles race conditions', async () => { let storage = new LocalFileStorage(directory); let lastModified = Date.now(); diff --git a/packages/file-storage/src/lib/local-file-storage.ts b/packages/file-storage/src/lib/local-file-storage.ts index 619f572e84a..e4a6fa80eab 100644 --- a/packages/file-storage/src/lib/local-file-storage.ts +++ b/packages/file-storage/src/lib/local-file-storage.ts @@ -3,16 +3,19 @@ import * as fsp from 'node:fs/promises'; import * as path from 'node:path'; import { openFile, writeFile } from '@mjackson/lazy-file/fs'; -import { type FileStorage } from './file-storage.ts'; - -interface FileMetadata { - name: string; - type: string; - mtime: number; -} +import { + type FileStorage, + type FileKey, + type FileMetadata, + type ListOptions, + type ListResult, +} from './file-storage.ts'; /** - * A `FileStorage` that is backed by the local filesystem. + * A `FileStorage` that is backed by a directory on the local filesystem. + * + * Important: No attempt is made to avoid overwriting existing files, so the directory used should + * be a new directory solely dedicated to this storage object. * * Note: Keys have no correlation to file names on disk, so they may be any string including * characters that are not valid in file names. Additionally, individual `File` names have no @@ -43,6 +46,26 @@ export class LocalFileStorage implements FileStorage { } } + async get(key: string): Promise { + let { filePath, metaPath } = await this.#getPaths(key); + + try { + let meta = await readMetadata(metaPath); + + return openFile(filePath, { + lastModified: meta.lastModified, + name: meta.name, + type: meta.type, + }); + } catch (error) { + if (!isNoEntityError(error)) { + throw error; + } + + return null; + } + } + async has(key: string): Promise { let { metaPath } = await this.#getPaths(key); @@ -54,44 +77,51 @@ export class LocalFileStorage implements FileStorage { } } - async set(key: string, file: File): Promise { - // Remove any existing file with the same key. - await this.remove(key); + async list(options?: T): Promise> { + let { cursor, includeMetadata = false, limit = 32, prefix } = options ?? {}; - let { directory, filePath, metaPath } = await this.#getPaths(key); + let files = []; + let foundCursor = cursor === undefined; + let nextCursor: string | undefined; + let lastHash: string | undefined; - // Ensure directory exists - await fsp.mkdir(directory, { recursive: true }); + outerLoop: for await (let subdir of await fsp.opendir(this.#dirname)) { + if (!subdir.isDirectory()) continue; - await writeFile(filePath, file); + for await (let file of await fsp.opendir(path.join(this.#dirname, subdir.name))) { + if (!file.isFile() || !file.name.endsWith('.meta.json')) continue; - let metadata: FileMetadata = { - name: file.name, - type: file.type, - mtime: file.lastModified, - }; - await fsp.writeFile(metaPath, JSON.stringify(metadata)); - } + let hash = file.name.slice(0, -10); // Remove ".meta.json" - async get(key: string): Promise { - let { filePath, metaPath } = await this.#getPaths(key); + if (foundCursor) { + let meta = await readMetadata(path.join(this.#dirname, subdir.name, file.name)); - try { - let metadataContent = await fsp.readFile(metaPath, 'utf-8'); - let metadata: FileMetadata = JSON.parse(metadataContent); + if (prefix != null && !meta.key.startsWith(prefix)) { + continue; + } - return openFile(filePath, { - name: metadata.name, - type: metadata.type, - lastModified: metadata.mtime, - }); - } catch (error) { - if (!isNoEntityError(error)) { - throw error; - } + if (files.length >= limit) { + nextCursor = lastHash; + break outerLoop; + } - return null; + if (includeMetadata) { + files.push(meta); + } else { + files.push({ key: meta.key }); + } + } else if (hash === cursor) { + foundCursor = true; + } + + lastHash = hash; + } } + + return { + cursor: nextCursor, + files: files as any, + }; } async put(key: string, file: File): Promise { @@ -111,11 +141,32 @@ export class LocalFileStorage implements FileStorage { } } + async set(key: string, file: File): Promise { + // Remove any existing file with the same key. + await this.remove(key); + + let { directory, filePath, metaPath } = await this.#getPaths(key); + + // Ensure directory exists + await fsp.mkdir(directory, { recursive: true }); + + await writeFile(filePath, file); + + let meta: FileMetadata = { + key, + lastModified: file.lastModified, + name: file.name, + size: file.size, + type: file.type, + }; + await fsp.writeFile(metaPath, JSON.stringify(meta)); + } + async #getPaths(key: string): Promise<{ directory: string; filePath: string; metaPath: string }> { let hash = await computeHash(key); - let shardDir = hash.slice(0, 8); + let shardDir = hash.slice(0, 2); let directory = path.join(this.#dirname, shardDir); - let filename = `${hash.slice(8)}.bin`; + let filename = `${hash}.dat`; let metaname = `${hash}.meta.json`; return { @@ -126,6 +177,10 @@ export class LocalFileStorage implements FileStorage { } } +async function readMetadata(metaPath: string): Promise { + return JSON.parse(await fsp.readFile(metaPath, 'utf-8')); +} + async function computeHash(key: string, algorithm = 'SHA-256'): Promise { let digest = await crypto.subtle.digest(algorithm, new TextEncoder().encode(key)); return Array.from(new Uint8Array(digest)) diff --git a/packages/file-storage/src/lib/memory-file-storage.test.ts b/packages/file-storage/src/lib/memory-file-storage.test.ts index da0e1f66af5..c4dc1f0a565 100644 --- a/packages/file-storage/src/lib/memory-file-storage.test.ts +++ b/packages/file-storage/src/lib/memory-file-storage.test.ts @@ -28,4 +28,67 @@ describe('MemoryFileStorage', () => { assert.ok(!storage.has('hello')); assert.equal(storage.get('hello'), null); }); + + it('lists files with pagination', async () => { + let storage = new MemoryFileStorage(); + let allKeys = ['a', 'b', 'c', 'd', 'e']; + + allKeys.forEach((key) => { + storage.set(key, new File([`Hello ${key}!`], `hello.txt`, { type: 'text/plain' })); + }); + + let { cursor, files } = storage.list(); + assert.equal(cursor, undefined); + assert.equal(files.length, 5); + assert.deepEqual(files.map((f) => f.key).sort(), allKeys); + + let { cursor: cursor1, files: files1 } = storage.list({ limit: 0 }); + assert.equal(cursor1, undefined); + assert.equal(files1.length, 0); + + let { cursor: cursor2, files: files2 } = storage.list({ limit: 2 }); + assert.notEqual(cursor2, undefined); + assert.equal(files2.length, 2); + + let { cursor: cursor3, files: files3 } = storage.list({ cursor: cursor2 }); + assert.equal(cursor3, undefined); + assert.equal(files3.length, 3); + + assert.deepEqual([...files2, ...files3].map((f) => f.key).sort(), allKeys); + }); + + it('lists files by key prefix', async () => { + let storage = new MemoryFileStorage(); + let allKeys = ['a', 'b', 'b/c', 'c', 'd']; + + allKeys.forEach((key) => { + storage.set(key, new File([`Hello ${key}!`], `hello.txt`, { type: 'text/plain' })); + }); + + let { cursor, files } = storage.list({ prefix: 'b' }); + + assert.equal(cursor, undefined); + assert.equal(files.length, 2); + assert.equal(files[0].key, 'b'); + assert.equal(files[1].key, 'b/c'); + }); + + it('lists files with metadata', async () => { + let storage = new MemoryFileStorage(); + let allKeys = ['a', 'b', 'c', 'd', 'e']; + + allKeys.forEach((key) => { + storage.set(key, new File([`Hello ${key}!`], `hello.txt`, { type: 'text/plain' })); + }); + + let { cursor, files } = storage.list({ includeMetadata: true }); + + assert.equal(cursor, undefined); + assert.equal(files.length, 5); + assert.deepEqual(files.map((f) => f.key).sort(), allKeys); + files.forEach((f) => assert.ok('lastModified' in f)); + files.forEach((f) => assert.ok('name' in f)); + files.forEach((f) => assert.ok('size' in f)); + files.forEach((f) => assert.ok('type' in f)); + }); }); diff --git a/packages/file-storage/src/lib/memory-file-storage.ts b/packages/file-storage/src/lib/memory-file-storage.ts index 5afae3a8064..aae9ef94e63 100644 --- a/packages/file-storage/src/lib/memory-file-storage.ts +++ b/packages/file-storage/src/lib/memory-file-storage.ts @@ -1,4 +1,10 @@ -import { type FileStorage } from './file-storage.ts'; +import { + type FileKey, + type FileMetadata, + type FileStorage, + type ListOptions, + type ListResult, +} from './file-storage.ts'; /** * A simple, in-memory implementation of the `FileStorage` interface. @@ -6,16 +12,52 @@ import { type FileStorage } from './file-storage.ts'; export class MemoryFileStorage implements FileStorage { #map = new Map(); + get(key: string): File | null { + return this.#map.get(key) ?? null; + } + has(key: string): boolean { return this.#map.has(key); } - set(key: string, file: File): void { - this.#map.set(key, file); - } + list(options?: T): ListResult { + let { cursor, includeMetadata = false, limit = Infinity, prefix } = options ?? {}; - get(key: string): File | null { - return this.#map.get(key) ?? null; + let files = []; + let foundCursor = cursor === undefined; + let nextCursor: string | undefined; + + for (let [key, file] of this.#map.entries()) { + if (foundCursor) { + if (prefix != null && !key.startsWith(prefix)) { + continue; + } + + if (files.length >= limit) { + nextCursor = files[files.length - 1]?.key; + break; + } + + if (includeMetadata) { + files.push({ + key, + lastModified: file.lastModified, + name: file.name, + size: file.size, + type: file.type, + }); + } else { + files.push({ key }); + } + } else if (key === cursor) { + foundCursor = true; + } + } + + return { + cursor: nextCursor, + files: files as any, + }; } put(key: string, file: File): File { @@ -26,4 +68,8 @@ export class MemoryFileStorage implements FileStorage { remove(key: string): void { this.#map.delete(key); } + + set(key: string, file: File): void { + this.#map.set(key, file); + } } diff --git a/packages/file-storage/src/local.ts b/packages/file-storage/src/local.ts index 3d4d690ab11..52984a46cf9 100644 --- a/packages/file-storage/src/local.ts +++ b/packages/file-storage/src/local.ts @@ -1 +1 @@ -export { LocalFileStorage } from './lib/local-file-storage.js'; +export { LocalFileStorage } from './lib/local-file-storage.ts'; diff --git a/packages/file-storage/src/memory.ts b/packages/file-storage/src/memory.ts index 364cbccbd9c..d55ca5c1d0d 100644 --- a/packages/file-storage/src/memory.ts +++ b/packages/file-storage/src/memory.ts @@ -1 +1 @@ -export { MemoryFileStorage } from './lib/memory-file-storage.js'; +export { MemoryFileStorage } from './lib/memory-file-storage.ts'; From 523fd67757d5e0d2ea2d7a461544a20d2e9d32f8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 26 Jan 2025 21:35:28 -0800 Subject: [PATCH 611/730] Updated doc comment and changelog --- packages/file-storage/CHANGELOG.md | 31 +++++++++++++++- packages/file-storage/src/lib/file-storage.ts | 37 ++++++++++++++++--- 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index c74276fb8ba..abf41505533 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -13,6 +13,35 @@ The following `options` are available: - `limit`: The maximum number of files to return - `prefix`: Only return keys that start with this string +For example, to list all files under keys that start with `user123/`: + +```ts +let result = await storage.list({ prefix: 'user123/' }); +console.log(result.files); +// [ +// { key: "user123/..." }, +// { key: "user123/..." }, +// ... +// ] +``` + +`result.files` will be an array of `{ key: string }` objects. To include metadata about each file, use `includeMetadata: true` in your `options`: + +```ts +let result = await storage.list({ prefix: 'user123/', includeMetadata: true }); +console.log(result.files); +// [ +// { +// key: "user123/..." +// lastModified: 1737955705270, +// name: "hello.txt" +// size: 16, +// type: "text/plain" +// }, +// ... +// ] +``` + Pagination is done via an opaque `cursor` property in the list result object. If it is not `undefined`, there are more files to list. You can list them by passing the `cursor` back in the `options` object on the next call. ```ts @@ -25,7 +54,7 @@ if (result.cursor !== undefined) { } ``` -Objects in the `files` array have only a `key` property by default. If you pass `includeMetadata: true` in the options, they will also have `lastModified`, `name`, `size`, and `type` properties. +Use the `limit` option to limit how many results you get back in the `files` array. ## v0.5.0 (2025-01-25) diff --git a/packages/file-storage/src/lib/file-storage.ts b/packages/file-storage/src/lib/file-storage.ts index ea49d31c6c9..1a215b9a578 100644 --- a/packages/file-storage/src/lib/file-storage.ts +++ b/packages/file-storage/src/lib/file-storage.ts @@ -26,9 +26,36 @@ export interface FileStorage { * - `limit`: The maximum number of files to return * - `prefix`: Only return keys that start with this string * - * Pagination is done via an opaque `cursor` property in the list result object. If it is not - * `undefined`, there are more files to list. You can list them by passing the `cursor` back - * in the `options` object on the next call. + * For example, to list all files under keys that start with `user123/`: + * + * ```ts + * let result = await storage.list({ prefix: 'user123/' }); + * console.log(result.files); + * // [ + * // { key: "user123/..." }, + * // { key: "user123/..." }, + * // ... + * // ] + * ``` + * + * `result.files` will be an array of `{ key: string }` objects. To include metadata about each file, use `includeMetadata: true` in your `options`: + * + * ```ts + * let result = await storage.list({ prefix: 'user123/', includeMetadata: true }); + * console.log(result.files); + * // [ + * // { + * // key: "user123/..." + * // lastModified: 1737955705270, + * // name: "hello.txt" + * // size: 16, + * // type: "text/plain" + * // }, + * // ... + * // ] + * ``` + * + * Pagination is done via an opaque `cursor` property in the list result object. If it is not `undefined`, there are more files to list. You can list them by passing the `cursor` back in the `options` object on the next call. * * ```ts * let result = await storage.list(); @@ -40,9 +67,7 @@ export interface FileStorage { * } * ``` * - * Objects in the `files` array have only a `key` property by default. If you pass - * `includeMetadata: true` in the options, they will also have `lastModified`, `name`, `size`, and - * `type` properties. + * Use the `limit` option to limit how many results you get back in the `files` array. * * @param options Options for the list operation * @returns An object with an array of `files` and an optional `cursor` property From 38bd31bbadf8037f30a69cca495ccffb8e0caf18 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 26 Jan 2025 21:40:40 -0800 Subject: [PATCH 612/730] Clean up some unused imports and unnecessary vars --- packages/file-storage/src/lib/local-file-storage.ts | 10 +++------- packages/file-storage/src/lib/memory-file-storage.ts | 8 +------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/packages/file-storage/src/lib/local-file-storage.ts b/packages/file-storage/src/lib/local-file-storage.ts index e4a6fa80eab..280d04591a2 100644 --- a/packages/file-storage/src/lib/local-file-storage.ts +++ b/packages/file-storage/src/lib/local-file-storage.ts @@ -5,7 +5,6 @@ import { openFile, writeFile } from '@mjackson/lazy-file/fs'; import { type FileStorage, - type FileKey, type FileMetadata, type ListOptions, type ListResult, @@ -164,15 +163,12 @@ export class LocalFileStorage implements FileStorage { async #getPaths(key: string): Promise<{ directory: string; filePath: string; metaPath: string }> { let hash = await computeHash(key); - let shardDir = hash.slice(0, 2); - let directory = path.join(this.#dirname, shardDir); - let filename = `${hash}.dat`; - let metaname = `${hash}.meta.json`; + let directory = path.join(this.#dirname, hash.slice(0, 2)); return { directory, - filePath: path.join(directory, filename), - metaPath: path.join(directory, metaname), + filePath: path.join(directory, `${hash}.dat`), + metaPath: path.join(directory, `${hash}.meta.json`), }; } } diff --git a/packages/file-storage/src/lib/memory-file-storage.ts b/packages/file-storage/src/lib/memory-file-storage.ts index aae9ef94e63..e42aa1245ac 100644 --- a/packages/file-storage/src/lib/memory-file-storage.ts +++ b/packages/file-storage/src/lib/memory-file-storage.ts @@ -1,10 +1,4 @@ -import { - type FileKey, - type FileMetadata, - type FileStorage, - type ListOptions, - type ListResult, -} from './file-storage.ts'; +import { type FileStorage, type ListOptions, type ListResult } from './file-storage.ts'; /** * A simple, in-memory implementation of the `FileStorage` interface. From d34cd85f7d33e4a1abd7463f308c8f6068bffc26 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 26 Jan 2025 21:48:19 -0800 Subject: [PATCH 613/730] Update CHANGELOG --- packages/multipart-parser/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index faca870504c..6d22a53979e 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -2,6 +2,10 @@ This is the changelog for [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Fix bad publish that left a `workspace:^` version identifier in package.json + ## v0.8.0 (2025-01-24) This release improves error handling and simplifies some of the internals of the parser. From 5a646c58732f012d1fc280ed35780096d25e2ea9 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 26 Jan 2025 21:48:27 -0800 Subject: [PATCH 614/730] Release multipart-parser@0.8.1 --- packages/multipart-parser/CHANGELOG.md | 2 +- packages/multipart-parser/jsr.json | 2 +- packages/multipart-parser/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index 6d22a53979e..ed7512403e5 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.8.1 (2025-01-27) - Fix bad publish that left a `workspace:^` version identifier in package.json diff --git a/packages/multipart-parser/jsr.json b/packages/multipart-parser/jsr.json index 2bdb27c327b..307546dee25 100644 --- a/packages/multipart-parser/jsr.json +++ b/packages/multipart-parser/jsr.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.8.0", + "version": "0.8.1", "exports": "./src/multipart-parser.ts", "publish": { "include": [ diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index b063fe7cb92..5e7c7296309 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.8.0", + "version": "0.8.1", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "repository": { From 43236efdd67a5255733d33455e535a034469cdf0 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 26 Jan 2025 22:53:04 -0800 Subject: [PATCH 615/730] Doc comment formatting --- packages/file-storage/CHANGELOG.md | 6 +++--- packages/file-storage/src/lib/file-storage.ts | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index abf41505533..8ffbe3e08f9 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -25,16 +25,16 @@ console.log(result.files); // ] ``` -`result.files` will be an array of `{ key: string }` objects. To include metadata about each file, use `includeMetadata: true` in your `options`: +`result.files` will be an array of `{ key: string }` objects. To include metadata about each file, use `includeMetadata: true`. ```ts let result = await storage.list({ prefix: 'user123/', includeMetadata: true }); console.log(result.files); // [ // { -// key: "user123/..." +// key: "user123/...", // lastModified: 1737955705270, -// name: "hello.txt" +// name: "hello.txt", // size: 16, // type: "text/plain" // }, diff --git a/packages/file-storage/src/lib/file-storage.ts b/packages/file-storage/src/lib/file-storage.ts index 1a215b9a578..7fb25121adf 100644 --- a/packages/file-storage/src/lib/file-storage.ts +++ b/packages/file-storage/src/lib/file-storage.ts @@ -38,16 +38,17 @@ export interface FileStorage { * // ] * ``` * - * `result.files` will be an array of `{ key: string }` objects. To include metadata about each file, use `includeMetadata: true` in your `options`: + * `result.files` will be an array of `{ key: string }` objects. To include metadata about each + * file, use `includeMetadata: true`. * * ```ts * let result = await storage.list({ prefix: 'user123/', includeMetadata: true }); * console.log(result.files); * // [ * // { - * // key: "user123/..." + * // key: "user123/...", * // lastModified: 1737955705270, - * // name: "hello.txt" + * // name: "hello.txt", * // size: 16, * // type: "text/plain" * // }, @@ -55,7 +56,9 @@ export interface FileStorage { * // ] * ``` * - * Pagination is done via an opaque `cursor` property in the list result object. If it is not `undefined`, there are more files to list. You can list them by passing the `cursor` back in the `options` object on the next call. + * Pagination is done via an opaque `cursor` property in the list result object. If it is not + * `undefined`, there are more files to list. You can list them by passing the `cursor` back in + * the `options` object on the next call. * * ```ts * let result = await storage.list(); From a26fe0c857100981ad577d478ae61be6430bab86 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 26 Jan 2025 23:24:23 -0800 Subject: [PATCH 616/730] Export all core types from root export --- packages/file-storage/src/file-storage.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/file-storage/src/file-storage.ts b/packages/file-storage/src/file-storage.ts index 9dbaaee15b1..1d34c55a5c8 100644 --- a/packages/file-storage/src/file-storage.ts +++ b/packages/file-storage/src/file-storage.ts @@ -1 +1,7 @@ -export { type FileStorage } from './lib/file-storage.ts'; +export type { + FileStorage, + FileKey, + FileMetadata, + ListOptions, + ListResult, +} from './lib/file-storage.ts'; From 62c7d9c657f2cc3f27634d24087ea9135662562c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 27 Jan 2025 09:39:22 -0800 Subject: [PATCH 617/730] Add more tests for headers.etag --- packages/headers/src/lib/super-headers.test.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/headers/src/lib/super-headers.test.ts b/packages/headers/src/lib/super-headers.test.ts index 19da6db78bc..6f6e74782b6 100644 --- a/packages/headers/src/lib/super-headers.test.ts +++ b/packages/headers/src/lib/super-headers.test.ts @@ -233,8 +233,14 @@ describe('SuperHeaders', () => { }); it('handles the etag property', () => { - let headers = new SuperHeaders({ etag: 'abc' }); + let headers = new SuperHeaders({ etag: '"abc"' }); assert.equal(headers.get('ETag'), '"abc"'); + + let headers2 = new SuperHeaders({ etag: 'abc' }); + assert.equal(headers2.get('ETag'), '"abc"'); + + let headers3 = new SuperHeaders({ etag: 'W/"abc"' }); + assert.equal(headers3.get('ETag'), 'W/"abc"'); }); it('handles the expires property', () => { @@ -536,14 +542,14 @@ describe('SuperHeaders', () => { assert.equal(headers.etag, null); - headers.etag = 'abc'; + headers.etag = '"abc"'; assert.equal(headers.etag, '"abc"'); - headers.etag = '"def"'; - assert.equal(headers.etag, '"def"'); + headers.etag = 'abc'; + assert.equal(headers.etag, '"abc"'); - headers.etag = 'W/"def"'; - assert.equal(headers.etag, 'W/"def"'); + headers.etag = 'W/"abc"'; + assert.equal(headers.etag, 'W/"abc"'); headers.etag = ''; assert.equal(headers.etag, '""'); From 581adb02c90a559bd2fe66918831ea6a37aced1c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 27 Jan 2025 11:59:29 -0800 Subject: [PATCH 618/730] Add If-None-Match header Fixes #21 --- packages/headers/CHANGELOG.md | 19 ++++ packages/headers/README.md | 23 +++++ packages/headers/src/headers.ts | 1 + .../headers/src/lib/if-none-match.test.ts | 94 +++++++++++++++++++ packages/headers/src/lib/if-none-match.ts | 58 ++++++++++++ .../headers/src/lib/super-headers.test.ts | 55 ++++++++--- packages/headers/src/lib/super-headers.ts | 30 ++++-- packages/headers/src/lib/utils.ts | 4 + 8 files changed, 265 insertions(+), 19 deletions(-) create mode 100644 packages/headers/src/lib/if-none-match.test.ts create mode 100644 packages/headers/src/lib/if-none-match.ts diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index ea51d5b19e5..dda3a69df73 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -18,6 +18,25 @@ let cookieNames = Array.from(headers.cookie.names()); let cookieNames = headers.cookie.names; ``` +Additionally, this release adds support for the `If-None-Match` header. This is useful for conditional GET requests where you want to return a response with content only if the ETag has changed. + +```ts +import { SuperHeaders } from '@mjackson/headers'; + +function requestHandler(request: Request): Promise { + let response = await callDownstreamService(request); + + if (request.method === 'GET' && response.headers.has('ETag')) { + let headers = new SuperHeaders(request.headers); + if (headers.ifNoneMatch.matches(response.headers.get('ETag'))) { + return new Response(null, { status: 304 }); + } + } + + return response; +} +``` + ## v0.9.0 (2024-12-20) This release tightens up the type safety and brings `SuperHeaders` more in line with the built-in `Headers` interface. diff --git a/packages/headers/README.md b/packages/headers/README.md index 823fa9a4a91..ccb5ec44d6f 100644 --- a/packages/headers/README.md +++ b/packages/headers/README.md @@ -100,6 +100,10 @@ headers.get('Cookie'); // 'session_id=abc123; user_id=12345; theme=dark' // Host headers.host = 'example.com'; +// If-None-Match +headers.ifNoneMatch = ['67ab43', '54ed21']; +headers.get('If-None-Match'); // '"67ab43", "54ed21"' + // Last-Modified headers.lastModified = new Date(); // or headers.lastModified = new Date().getTime(); @@ -366,6 +370,25 @@ let header = new Cookie([ ]); ``` +### If-None-Match + +```ts +import { IfNoneMatch } from '@mjackson/headers'; + +let header = new IfNoneMatch('"67ab43", "54ed21"'); + +header.has('67ab43'); // true +header.has('21ba69'); // false + +header.matches('"67ab43"'); // true + +// Alternative init style +let header = new IfNoneMatch(['67ab43', '54ed21']); +let header = new IfNoneMatch({ + tags: ['67ab43', '54ed21'], +}); +``` + ### Set-Cookie ```ts diff --git a/packages/headers/src/headers.ts b/packages/headers/src/headers.ts index fb98f848e11..9c655a4928b 100644 --- a/packages/headers/src/headers.ts +++ b/packages/headers/src/headers.ts @@ -5,6 +5,7 @@ export { type CacheControlInit, CacheControl } from './lib/cache-control.ts'; export { type ContentDispositionInit, ContentDisposition } from './lib/content-disposition.ts'; export { type ContentTypeInit, ContentType } from './lib/content-type.ts'; export { type CookieInit, Cookie } from './lib/cookie.ts'; +export { type IfNoneMatchInit, IfNoneMatch } from './lib/if-none-match.ts'; export { type SetCookieInit, SetCookie } from './lib/set-cookie.ts'; export { diff --git a/packages/headers/src/lib/if-none-match.test.ts b/packages/headers/src/lib/if-none-match.test.ts new file mode 100644 index 00000000000..13247082204 --- /dev/null +++ b/packages/headers/src/lib/if-none-match.test.ts @@ -0,0 +1,94 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { IfNoneMatch } from './if-none-match.ts'; + +describe('IfNoneMatch', () => { + it('initializes with an empty string', () => { + let header = new IfNoneMatch(''); + assert.deepEqual(header.tags, []); + }); + + it('initializes with a string with a single tag', () => { + let header = new IfNoneMatch('67ab43'); + assert.deepEqual(header.tags, ['"67ab43"']); + + let header2 = new IfNoneMatch('"67ab43"'); + assert.deepEqual(header2.tags, ['"67ab43"']); + + let header3 = new IfNoneMatch('W/"67ab43"'); + assert.deepEqual(header3.tags, ['W/"67ab43"']); + }); + + it('initializes with a string with multiple tags', () => { + let header = new IfNoneMatch('67ab43, 54ed21'); + assert.deepEqual(header.tags, ['"67ab43"', '"54ed21"']); + + let header2 = new IfNoneMatch('"67ab43", "54ed21"'); + assert.deepEqual(header2.tags, ['"67ab43"', '"54ed21"']); + + let header3 = new IfNoneMatch('W/"67ab43", "54ed21"'); + assert.deepEqual(header3.tags, ['W/"67ab43"', '"54ed21"']); + }); + + it('initializes with an array of tags', () => { + let header = new IfNoneMatch(['67ab43', '54ed21']); + assert.deepEqual(header.tags, ['"67ab43"', '"54ed21"']); + + let header2 = new IfNoneMatch(['"67ab43"', '"54ed21"']); + assert.deepEqual(header2.tags, ['"67ab43"', '"54ed21"']); + + let header3 = new IfNoneMatch(['W/"67ab43"', '"54ed21"']); + assert.deepEqual(header3.tags, ['W/"67ab43"', '"54ed21"']); + }); + + it('initializes with an object', () => { + let header = new IfNoneMatch({ tags: ['67ab43', '54ed21'] }); + assert.deepEqual(header.tags, ['"67ab43"', '"54ed21"']); + + let header2 = new IfNoneMatch({ tags: ['"67ab43"', '"54ed21"'] }); + assert.deepEqual(header2.tags, ['"67ab43"', '"54ed21"']); + + let header3 = new IfNoneMatch({ tags: ['W/"67ab43"', '"54ed21"'] }); + assert.deepEqual(header3.tags, ['W/"67ab43"', '"54ed21"']); + }); + + it('initializes with another IfNoneMatch', () => { + let header = new IfNoneMatch(new IfNoneMatch('67ab43, 54ed21')); + assert.deepEqual(header.tags, ['"67ab43"', '"54ed21"']); + }); + + it('checks if a tag is present', () => { + let header = new IfNoneMatch('67ab43, 54ed21'); + assert.ok(header.has('"67ab43"')); + assert.ok(header.has('"54ed21"')); + assert.ok(!header.has('"7892dd"')); + assert.ok(!header.has('*')); + + let header2 = new IfNoneMatch('W/"67ab43", "54ed21"'); + assert.ok(header2.has('W/"67ab43"')); + assert.ok(header2.has('"54ed21"')); + assert.ok(!header2.has('"7892dd"')); + }); + + it('checks if a tag matches', () => { + let header = new IfNoneMatch('67ab43, 54ed21'); + assert.ok(header.matches('"67ab43"')); + assert.ok(header.matches('"54ed21"')); + assert.ok(!header.matches('"7892dd"')); + + let header2 = new IfNoneMatch('W/"67ab43", "54ed21"'); + assert.ok(header2.matches('W/"67ab43"')); + assert.ok(header2.matches('"54ed21"')); + assert.ok(!header2.matches('"7892dd"')); + + let header3 = new IfNoneMatch('*'); + assert.ok(header3.matches('"67ab43"')); + assert.ok(header3.matches('"54ed21"')); + }); + + it('converts to a string', () => { + let header = new IfNoneMatch('W/"67ab43", "54ed21"'); + assert.equal(header.toString(), 'W/"67ab43", "54ed21"'); + }); +}); diff --git a/packages/headers/src/lib/if-none-match.ts b/packages/headers/src/lib/if-none-match.ts new file mode 100644 index 00000000000..f71179c18bd --- /dev/null +++ b/packages/headers/src/lib/if-none-match.ts @@ -0,0 +1,58 @@ +import { type HeaderValue } from './header-value.ts'; +import { quoteEtag } from './utils.ts'; + +export interface IfNoneMatchInit { + /** + * The entity tags to compare against the current entity. + */ + tags: string[]; +} + +/** + * The value of an `If-None-Match` HTTP header. + * + * [MDN `If-None-Match` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-3.2) + */ +export class IfNoneMatch implements HeaderValue, IfNoneMatchInit { + tags: string[] = []; + + constructor(init?: string | string[] | IfNoneMatchInit) { + if (init) { + if (typeof init === 'string') { + this.tags.push(...init.split(/\s*,\s*/).map(quoteEtag)); + } else if (Array.isArray(init)) { + this.tags.push(...init.map(quoteEtag)); + } else { + this.tags.push(...init.tags.map(quoteEtag)); + } + } + } + + /** + * Checks if the header contains the given entity tag. + * + * Note: This method checks only for exact matches and does not consider wildcards. + * + * @param tag The entity tag to check for. + * @returns `true` if the tag is present in the header, `false` otherwise. + */ + has(tag: string): boolean { + return this.tags.includes(quoteEtag(tag)); + } + + /** + * Checks if this header matches the given entity tag. + * + * @param tag The entity tag to check for. + * @returns `true` if the tag is present in the header (or the header contains a wildcard), `false` otherwise. + */ + matches(tag: string): boolean { + return this.has(tag) || this.tags.includes('*'); + } + + toString() { + return this.tags.join(', '); + } +} diff --git a/packages/headers/src/lib/super-headers.test.ts b/packages/headers/src/lib/super-headers.test.ts index 6f6e74782b6..606c329a960 100644 --- a/packages/headers/src/lib/super-headers.test.ts +++ b/packages/headers/src/lib/super-headers.test.ts @@ -9,6 +9,7 @@ import { ContentDisposition } from './content-disposition.ts'; import { ContentType } from './content-type.ts'; import { Cookie } from './cookie.ts'; import { SuperHeaders } from './super-headers.ts'; +import { IfNoneMatch } from './if-none-match.ts'; describe('SuperHeaders', () => { it('is an instance of Headers', () => { @@ -77,7 +78,11 @@ describe('SuperHeaders', () => { it('checks if a header exists', () => { let headers = new SuperHeaders({ 'X-Custom': 'value' }); assert.equal(headers.has('X-Custom'), true); - assert.equal(headers.has('Nonexistent'), false); + assert.equal(headers.has('Content-Type'), false); + + // Accessing this property should not change the result of has() + let _ = headers.contentType; + assert.equal(headers.has('Content-Type'), false); }); it('iterates over entries', () => { @@ -233,14 +238,14 @@ describe('SuperHeaders', () => { }); it('handles the etag property', () => { - let headers = new SuperHeaders({ etag: '"abc"' }); - assert.equal(headers.get('ETag'), '"abc"'); + let headers = new SuperHeaders({ etag: '"67ab43"' }); + assert.equal(headers.get('ETag'), '"67ab43"'); - let headers2 = new SuperHeaders({ etag: 'abc' }); - assert.equal(headers2.get('ETag'), '"abc"'); + let headers2 = new SuperHeaders({ etag: '67ab43' }); + assert.equal(headers2.get('ETag'), '"67ab43"'); - let headers3 = new SuperHeaders({ etag: 'W/"abc"' }); - assert.equal(headers3.get('ETag'), 'W/"abc"'); + let headers3 = new SuperHeaders({ etag: 'W/"67ab43"' }); + assert.equal(headers3.get('ETag'), 'W/"67ab43"'); }); it('handles the expires property', () => { @@ -258,6 +263,11 @@ describe('SuperHeaders', () => { assert.equal(headers.get('If-Modified-Since'), 'Fri, 01 Jan 2021 00:00:00 GMT'); }); + it('handles the ifNoneMatch property', () => { + let headers = new SuperHeaders({ ifNoneMatch: ['67ab43', '54ed21'] }); + assert.equal(headers.get('If-None-Match'), '"67ab43", "54ed21"'); + }); + it('handles the ifUnmodifiedSince property', () => { let headers = new SuperHeaders({ ifUnmodifiedSince: new Date('2021-01-01T00:00:00Z') }); assert.equal(headers.get('If-Unmodified-Since'), 'Fri, 01 Jan 2021 00:00:00 GMT'); @@ -542,14 +552,14 @@ describe('SuperHeaders', () => { assert.equal(headers.etag, null); - headers.etag = '"abc"'; - assert.equal(headers.etag, '"abc"'); + headers.etag = '"67ab43"'; + assert.equal(headers.etag, '"67ab43"'); - headers.etag = 'abc'; - assert.equal(headers.etag, '"abc"'); + headers.etag = '67ab43'; + assert.equal(headers.etag, '"67ab43"'); - headers.etag = 'W/"abc"'; - assert.equal(headers.etag, 'W/"abc"'); + headers.etag = 'W/"67ab43"'; + assert.equal(headers.etag, 'W/"67ab43"'); headers.etag = ''; assert.equal(headers.etag, '""'); @@ -599,6 +609,25 @@ describe('SuperHeaders', () => { assert.equal(headers.ifModifiedSince, null); }); + it('supports the ifNoneMatch property', () => { + let headers = new SuperHeaders(); + + assert.ok(headers.ifNoneMatch instanceof IfNoneMatch); + + headers.ifNoneMatch = '"67ab43", "54ed21"'; + assert.deepEqual(headers.ifNoneMatch.tags, ['"67ab43"', '"54ed21"']); + + headers.ifNoneMatch = ['67ab43', '54ed21']; + assert.deepEqual(headers.ifNoneMatch.tags, ['"67ab43"', '"54ed21"']); + + headers.ifNoneMatch = { tags: ['67ab43', '54ed21'] }; + assert.deepEqual(headers.ifNoneMatch.tags, ['"67ab43"', '"54ed21"']); + + headers.ifNoneMatch = null; + assert.ok(headers.ifNoneMatch instanceof IfNoneMatch); + assert.equal(headers.ifNoneMatch.toString(), ''); + }); + it('supports the ifUnmodifiedSince property', () => { let headers = new SuperHeaders(); diff --git a/packages/headers/src/lib/super-headers.ts b/packages/headers/src/lib/super-headers.ts index b41ea47e2bf..98c756966ed 100644 --- a/packages/headers/src/lib/super-headers.ts +++ b/packages/headers/src/lib/super-headers.ts @@ -7,8 +7,9 @@ import { type ContentTypeInit, ContentType } from './content-type.ts'; import { type CookieInit, Cookie } from './cookie.ts'; import { canonicalHeaderName } from './header-names.ts'; import { type HeaderValue } from './header-value.ts'; +import { type IfNoneMatchInit, IfNoneMatch } from './if-none-match.ts'; import { type SetCookieInit, SetCookie } from './set-cookie.ts'; -import { isIterable } from './utils.ts'; +import { isIterable, quoteEtag } from './utils.ts'; type DateInit = number | Date; @@ -85,6 +86,10 @@ interface SuperHeadersPropertyInit { * The [`If-Modified-Since`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since) header value. */ ifModifiedSince?: string | DateInit; + /** + * The [`If-None-Match`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match) header value. + */ + ifNoneMatch?: string | string[] | IfNoneMatchInit; /** * The [`If-Unmodified-Since`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Unmodified-Since) header value. */ @@ -131,6 +136,7 @@ const ETagKey = 'etag'; const ExpiresKey = 'expires'; const HostKey = 'host'; const IfModifiedSinceKey = 'if-modified-since'; +const IfNoneMatchKey = 'if-none-match'; const IfUnmodifiedSinceKey = 'if-unmodified-since'; const LastModifiedKey = 'last-modified'; const LocationKey = 'location'; @@ -251,7 +257,7 @@ export class SuperHeaders extends Headers { */ has(name: string): boolean { let key = name.toLowerCase(); - return key === SetCookieKey ? this.#setCookies.length > 0 : this.#map.has(key); + return key === SetCookieKey ? this.#setCookies.length > 0 : this.get(key) != null; } /** @@ -569,10 +575,7 @@ export class SuperHeaders extends Headers { } set etag(value: string | undefined | null) { - this.#setStringValue( - ETagKey, - typeof value === 'string' && !/^(W\/)?".*"$/.test(value) ? `"${value}"` : value, - ); + this.#setStringValue(ETagKey, typeof value === 'string' ? quoteEtag(value) : value); } /** @@ -621,6 +624,21 @@ export class SuperHeaders extends Headers { this.#setDateValue(IfModifiedSinceKey, value); } + /** + * The `If-None-Match` header makes a request conditional on the absence of a matching ETag. + * + * [MDN `If-None-Match` Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match) + * + * [HTTP/1.1 Specification](https://datatracker.ietf.org/doc/html/rfc7232#section-3.2) + */ + get ifNoneMatch(): IfNoneMatch { + return this.#getHeaderValue(IfNoneMatchKey, IfNoneMatch); + } + + set ifNoneMatch(value: string | string[] | IfNoneMatchInit | undefined | null) { + this.#setHeaderValue(IfNoneMatchKey, IfNoneMatch, value); + } + /** * The `If-Unmodified-Since` header makes a request conditional on the last modification date of the * requested resource. diff --git a/packages/headers/src/lib/utils.ts b/packages/headers/src/lib/utils.ts index efa5a2da1e1..6560a030a8a 100644 --- a/packages/headers/src/lib/utils.ts +++ b/packages/headers/src/lib/utils.ts @@ -9,3 +9,7 @@ export function isIterable(value: any): value is Iterable { export function isValidDate(date: unknown): boolean { return date instanceof Date && !isNaN(date.getTime()); } + +export function quoteEtag(tag: string): string { + return tag === '*' ? tag : /^(W\/)?".*"$/.test(tag) ? tag : `"${tag}"`; +} From b01e7ebf3c20de93d86a425388642e94bc9ce55d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 27 Jan 2025 12:01:06 -0800 Subject: [PATCH 619/730] Release headers@0.10.0 --- packages/headers/CHANGELOG.md | 2 +- packages/headers/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/headers/CHANGELOG.md b/packages/headers/CHANGELOG.md index dda3a69df73..9b20eef4f70 100644 --- a/packages/headers/CHANGELOG.md +++ b/packages/headers/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`headers`](https://github.com/mjackson/remix-the-web/tree/main/packages/headers). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.10.0 (2025-01-27) This release contains several improvements to `Cookie` that bring it more in line with other headers like `Accept`, `AcceptEncoding`, and `AcceptLanguage`. diff --git a/packages/headers/package.json b/packages/headers/package.json index c1c991d4f17..bd982cbcc30 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/headers", - "version": "0.9.0", + "version": "0.10.0", "description": "A toolkit for working with HTTP headers in JavaScript", "author": "Michael Jackson ", "license": "MIT", From 2ae7199a3087219cb7702cc41a0b3be280bd617b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 27 Jan 2025 13:02:49 -0800 Subject: [PATCH 620/730] Update CHANGELOG --- packages/file-storage/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 8ffbe3e08f9..714fb33ee37 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -4,6 +4,7 @@ This is the changelog for [`file-storage`](https://github.com/mjackson/remix-the ## HEAD +- BREAKING CHANGE: `LocalFileStorage` now uses 2 characters for shard directory names instead of 8. - Add `storage.list(options)` for listing files in storage. The following `options` are available: From 6c2c86f4d5ab5950474fc372922015854e50ca53 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 28 Jan 2025 16:30:24 -0800 Subject: [PATCH 621/730] Remove unneeded declaration file --- packages/file-storage/global.d.ts | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 packages/file-storage/global.d.ts diff --git a/packages/file-storage/global.d.ts b/packages/file-storage/global.d.ts deleted file mode 100644 index b8041179bc5..00000000000 --- a/packages/file-storage/global.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -// See https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62651 - -interface ReadableStream { - values(options?: { preventCancel?: boolean }): AsyncIterableIterator; - [Symbol.asyncIterator](): AsyncIterableIterator; -} From 4653db00436fb0430c13862aea356dae08ec5204 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 31 Jan 2025 09:19:25 -0800 Subject: [PATCH 622/730] Small type tweak --- packages/form-data-parser/examples/node/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/form-data-parser/examples/node/server.js b/packages/form-data-parser/examples/node/server.js index 66e62ec2110..7e5c8565398 100644 --- a/packages/form-data-parser/examples/node/server.js +++ b/packages/form-data-parser/examples/node/server.js @@ -53,7 +53,7 @@ const server = http.createServer( return file.size === 0 ? null : file; }); - let text = /** @type string */ (formData.get('text1')); + let text = /** @type string | null */ (formData.get('text1')); let image = /** @type File | null */ (formData.get('image1')); return new Response( From b600e6f5645cf04701e7b3bed78c15d914b20f12 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 31 Jan 2025 09:22:22 -0800 Subject: [PATCH 623/730] Add note about using with Remix v2 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index c063efda98f..81fd2c32f9c 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,10 @@ We currently publish the following packages: - [node-fetch-server](packages/node-fetch-server): Build HTTP servers for Node.js using the web `fetch()` API - [tar-parser](packages/tar-parser): Fast, streaming parser for tar archives +## Using with Remix v2 + +If you're trying to use these libraries with Remix v2, you'll need to [enable "Single Fetch"](https://remix.run/docs/en/main/guides/single-fetch#enabling-single-fetch) first. This tells Remix to use Node's built-in fetch primitives (`Request`, `Response`, `Headers`, etc.) instead of a broken polyfill we shipped in earlier versions of Remix. + ## License See [LICENSE](https://github.com/mjackson/remix-the-web/blob/main/LICENSE) From 8dd78878a7f2074fe2908c72c59861273175e46d Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 1 Feb 2025 07:19:06 -0800 Subject: [PATCH 624/730] Small style tweak --- packages/file-storage/src/lib/local-file-storage.ts | 4 ++-- packages/file-storage/src/lib/memory-file-storage.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/file-storage/src/lib/local-file-storage.ts b/packages/file-storage/src/lib/local-file-storage.ts index 280d04591a2..738348cd8f1 100644 --- a/packages/file-storage/src/lib/local-file-storage.ts +++ b/packages/file-storage/src/lib/local-file-storage.ts @@ -79,7 +79,7 @@ export class LocalFileStorage implements FileStorage { async list(options?: T): Promise> { let { cursor, includeMetadata = false, limit = 32, prefix } = options ?? {}; - let files = []; + let files: any[] = []; let foundCursor = cursor === undefined; let nextCursor: string | undefined; let lastHash: string | undefined; @@ -119,7 +119,7 @@ export class LocalFileStorage implements FileStorage { return { cursor: nextCursor, - files: files as any, + files, }; } diff --git a/packages/file-storage/src/lib/memory-file-storage.ts b/packages/file-storage/src/lib/memory-file-storage.ts index e42aa1245ac..a8704d7434c 100644 --- a/packages/file-storage/src/lib/memory-file-storage.ts +++ b/packages/file-storage/src/lib/memory-file-storage.ts @@ -17,7 +17,7 @@ export class MemoryFileStorage implements FileStorage { list(options?: T): ListResult { let { cursor, includeMetadata = false, limit = Infinity, prefix } = options ?? {}; - let files = []; + let files: any[] = []; let foundCursor = cursor === undefined; let nextCursor: string | undefined; @@ -50,7 +50,7 @@ export class MemoryFileStorage implements FileStorage { return { cursor: nextCursor, - files: files as any, + files, }; } From fbd792cfb4ec4797257f800af1e54d1b8b419758 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 3 Feb 2025 17:38:53 -0800 Subject: [PATCH 625/730] Buffer file contents in MemoryFileStorage --- packages/file-storage/CHANGELOG.md | 1 + .../file-storage/src/lib/memory-file-storage.ts | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 714fb33ee37..fc3e3f51298 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -5,6 +5,7 @@ This is the changelog for [`file-storage`](https://github.com/mjackson/remix-the ## HEAD - BREAKING CHANGE: `LocalFileStorage` now uses 2 characters for shard directory names instead of 8. +- Buffer contents of files stored in `MemoryFileStorage`. - Add `storage.list(options)` for listing files in storage. The following `options` are available: diff --git a/packages/file-storage/src/lib/memory-file-storage.ts b/packages/file-storage/src/lib/memory-file-storage.ts index a8704d7434c..6cd43c5509e 100644 --- a/packages/file-storage/src/lib/memory-file-storage.ts +++ b/packages/file-storage/src/lib/memory-file-storage.ts @@ -2,6 +2,9 @@ import { type FileStorage, type ListOptions, type ListResult } from './file-stor /** * A simple, in-memory implementation of the `FileStorage` interface. + * + * Note: Any files you put in storage will have their entire contents buffered in memory, so this is not suitable for large files + * in production scenarios. */ export class MemoryFileStorage implements FileStorage { #map = new Map(); @@ -54,8 +57,8 @@ export class MemoryFileStorage implements FileStorage { }; } - put(key: string, file: File): File { - this.set(key, file); + async put(key: string, file: File): Promise { + await this.set(key, file); return this.get(key)!; } @@ -63,7 +66,13 @@ export class MemoryFileStorage implements FileStorage { this.#map.delete(key); } - set(key: string, file: File): void { - this.#map.set(key, file); + async set(key: string, file: File): Promise { + let buffer = await file.arrayBuffer(); + let newFile = new File([buffer], file.name, { + lastModified: file.lastModified, + type: file.type, + }); + + this.#map.set(key, newFile); } } From 78806e14b7689b6a42ad3d1610df5052a16d1393 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 3 Feb 2025 17:39:22 -0800 Subject: [PATCH 626/730] Add `Promise` to return type Fixes #48 --- packages/multipart-parser/CHANGELOG.md | 4 ++++ packages/multipart-parser/src/lib/multipart.ts | 2 +- packages/tar-parser/CHANGELOG.md | 4 ++++ packages/tar-parser/src/lib/tar.ts | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index ed7512403e5..f39b7543bc2 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -2,6 +2,10 @@ This is the changelog for [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Add `Promise` to `MultipartPartHandler` return type + ## v0.8.1 (2025-01-27) - Fix bad publish that left a `workspace:^` version identifier in package.json diff --git a/packages/multipart-parser/src/lib/multipart.ts b/packages/multipart-parser/src/lib/multipart.ts index 37fbb8ec644..0838c5d3847 100644 --- a/packages/multipart-parser/src/lib/multipart.ts +++ b/packages/multipart-parser/src/lib/multipart.ts @@ -35,7 +35,7 @@ type MultipartMessageSource = | Iterable | AsyncIterable; -export type MultipartPartHandler = (part: MultipartPart) => void; +export type MultipartPartHandler = (part: MultipartPart) => void | Promise; export interface ParseMultipartOptions { boundary: string; diff --git a/packages/tar-parser/CHANGELOG.md b/packages/tar-parser/CHANGELOG.md index d9a77679a40..62ce9892c3f 100644 --- a/packages/tar-parser/CHANGELOG.md +++ b/packages/tar-parser/CHANGELOG.md @@ -2,6 +2,10 @@ This is the changelog for [`tar-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/tar-parser). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Add `Promise` to `TarEntryHandler` return type + ## v0.2.1 (2025-01-24) - Add support for environments that do not support `ReadableStream.prototype[Symbol.asyncIterator]` (i.e. Safari), see #46 diff --git a/packages/tar-parser/src/lib/tar.ts b/packages/tar-parser/src/lib/tar.ts index 8fcf6143fea..3eefce10f58 100644 --- a/packages/tar-parser/src/lib/tar.ts +++ b/packages/tar-parser/src/lib/tar.ts @@ -151,7 +151,7 @@ type TarArchiveSource = | Iterable | AsyncIterable; -type TarEntryHandler = (entry: TarEntry) => void; +type TarEntryHandler = (entry: TarEntry) => void | Promise; export type ParseTarOptions = ParseTarHeaderOptions; From c5f5ebebe72f9b275019230dc0a110e01c8b3e29 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 3 Feb 2025 17:40:43 -0800 Subject: [PATCH 627/730] Release multipart-parser@0.8.2 --- packages/multipart-parser/CHANGELOG.md | 2 +- packages/multipart-parser/jsr.json | 2 +- packages/multipart-parser/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/multipart-parser/CHANGELOG.md b/packages/multipart-parser/CHANGELOG.md index f39b7543bc2..99c14c48155 100644 --- a/packages/multipart-parser/CHANGELOG.md +++ b/packages/multipart-parser/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`multipart-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/multipart-parser). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.8.2 (2025-02-04) - Add `Promise` to `MultipartPartHandler` return type diff --git a/packages/multipart-parser/jsr.json b/packages/multipart-parser/jsr.json index 307546dee25..c6d7aaafa36 100644 --- a/packages/multipart-parser/jsr.json +++ b/packages/multipart-parser/jsr.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.8.1", + "version": "0.8.2", "exports": "./src/multipart-parser.ts", "publish": { "include": [ diff --git a/packages/multipart-parser/package.json b/packages/multipart-parser/package.json index 5e7c7296309..9f1a0a68213 100644 --- a/packages/multipart-parser/package.json +++ b/packages/multipart-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.8.1", + "version": "0.8.2", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "repository": { From 15fa0fe044eb693bad991652a8ee09ef1f7d74d3 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 3 Feb 2025 17:40:48 -0800 Subject: [PATCH 628/730] Release tar-parser@0.2.2 --- packages/tar-parser/CHANGELOG.md | 2 +- packages/tar-parser/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/tar-parser/CHANGELOG.md b/packages/tar-parser/CHANGELOG.md index 62ce9892c3f..0d169d56bfb 100644 --- a/packages/tar-parser/CHANGELOG.md +++ b/packages/tar-parser/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`tar-parser`](https://github.com/mjackson/remix-the-web/tree/main/packages/tar-parser). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.2.2 (2025-02-04) - Add `Promise` to `TarEntryHandler` return type diff --git a/packages/tar-parser/package.json b/packages/tar-parser/package.json index 001d16d5460..c4898406d5a 100644 --- a/packages/tar-parser/package.json +++ b/packages/tar-parser/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/tar-parser", - "version": "0.2.1", + "version": "0.2.2", "description": "A fast, efficient parser for tar streams in any JavaScript environment", "author": "Michael Jackson ", "license": "MIT", From 62284a722a54d7254a2c166e9c9b4023a48143b7 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 3 Feb 2025 17:40:57 -0800 Subject: [PATCH 629/730] Release file-storage@0.6.0 --- packages/file-storage/CHANGELOG.md | 2 +- packages/file-storage/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index fc3e3f51298..140685c3240 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.6.0 (2025-02-04) - BREAKING CHANGE: `LocalFileStorage` now uses 2 characters for shard directory names instead of 8. - Buffer contents of files stored in `MemoryFileStorage`. diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index a2fc426b5e1..104459ce275 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/file-storage", - "version": "0.5.0", + "version": "0.6.0", "description": "Key/value storage for JavaScript File objects", "author": "Michael Jackson ", "repository": { From d08d29463ed3bcec88bc279f275eec18971b5afa Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 3 Feb 2025 17:44:40 -0800 Subject: [PATCH 630/730] Fix failing test --- .../src/lib/memory-file-storage.test.ts | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/file-storage/src/lib/memory-file-storage.test.ts b/packages/file-storage/src/lib/memory-file-storage.test.ts index c4dc1f0a565..8a0ecd421f3 100644 --- a/packages/file-storage/src/lib/memory-file-storage.test.ts +++ b/packages/file-storage/src/lib/memory-file-storage.test.ts @@ -8,7 +8,7 @@ describe('MemoryFileStorage', () => { let storage = new MemoryFileStorage(); let file = new File(['Hello, world!'], 'hello.txt', { type: 'text/plain' }); - storage.set('hello', file); + await storage.set('hello', file); assert.ok(storage.has('hello')); @@ -33,9 +33,11 @@ describe('MemoryFileStorage', () => { let storage = new MemoryFileStorage(); let allKeys = ['a', 'b', 'c', 'd', 'e']; - allKeys.forEach((key) => { - storage.set(key, new File([`Hello ${key}!`], `hello.txt`, { type: 'text/plain' })); - }); + await Promise.all( + allKeys.map((key) => + storage.set(key, new File([`Hello ${key}!`], `hello.txt`, { type: 'text/plain' })), + ), + ); let { cursor, files } = storage.list(); assert.equal(cursor, undefined); @@ -61,9 +63,11 @@ describe('MemoryFileStorage', () => { let storage = new MemoryFileStorage(); let allKeys = ['a', 'b', 'b/c', 'c', 'd']; - allKeys.forEach((key) => { - storage.set(key, new File([`Hello ${key}!`], `hello.txt`, { type: 'text/plain' })); - }); + await Promise.all( + allKeys.map((key) => + storage.set(key, new File([`Hello ${key}!`], `hello.txt`, { type: 'text/plain' })), + ), + ); let { cursor, files } = storage.list({ prefix: 'b' }); @@ -77,9 +81,11 @@ describe('MemoryFileStorage', () => { let storage = new MemoryFileStorage(); let allKeys = ['a', 'b', 'c', 'd', 'e']; - allKeys.forEach((key) => { - storage.set(key, new File([`Hello ${key}!`], `hello.txt`, { type: 'text/plain' })); - }); + await Promise.all( + allKeys.map((key) => + storage.set(key, new File([`Hello ${key}!`], `hello.txt`, { type: 'text/plain' })), + ), + ); let { cursor, files } = storage.list({ includeMetadata: true }); From 80a399804573c9c7a294263bec463a223b680d45 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 3 Feb 2025 17:51:11 -0800 Subject: [PATCH 631/730] Update example --- packages/form-data-parser/examples/node/server.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/form-data-parser/examples/node/server.js b/packages/form-data-parser/examples/node/server.js index 7e5c8565398..9f13f2bea51 100644 --- a/packages/form-data-parser/examples/node/server.js +++ b/packages/form-data-parser/examples/node/server.js @@ -10,9 +10,7 @@ import { createRequestListener } from '@mjackson/node-fetch-server'; const PORT = 3000; const oneMb = 1024 * 1024; -const fileStorage = new LocalFileStorage( - await fsp.mkdtemp(path.join(os.tmpdir(), 'form-data-parser-')), -); +const fileStorage = new LocalFileStorage(await fsp.mkdtemp(path.join(os.tmpdir(), 'uploads-'))); /** @type (file: File) => Promise */ async function getDataUrl(file) { From 8a3d2b4002b2b3b32ce305f62c86ab2f7b037892 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 3 Feb 2025 18:20:37 -0800 Subject: [PATCH 632/730] Update release notes --- packages/file-storage/CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 140685c3240..0df762f8fe7 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -44,15 +44,15 @@ console.log(result.files); // ] ``` -Pagination is done via an opaque `cursor` property in the list result object. If it is not `undefined`, there are more files to list. You can list them by passing the `cursor` back in the `options` object on the next call. +Pagination is done via an opaque `cursor` property in the list result object. If it is not `undefined`, there are more files to list. You can list them by passing the `cursor` back in the `options` object on the next call. For example, to list all items in storage, you could do something like this: ```ts let result = await storage.list(); - console.log(result.files); -if (result.cursor !== undefined) { - let result2 = await storage.list({ cursor: result.cursor }); +while (result.cursor !== undefined) { + result = await storage.list({ cursor: result.cursor }); + console.log(result.files); } ``` From 548213a77cfe7fd3b6f0ed448fbaaf1fe9a7d022 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 3 Feb 2025 20:01:38 -0800 Subject: [PATCH 633/730] Update multipart-parser README --- packages/multipart-parser/README.md | 79 ++++++++++++++--------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/packages/multipart-parser/README.md b/packages/multipart-parser/README.md index b2f022a4efb..12dd11a8c84 100644 --- a/packages/multipart-parser/README.md +++ b/packages/multipart-parser/README.md @@ -30,7 +30,7 @@ deno add @mjackson/multipart-parser ## Usage -The most common use case for `multipart-parser` is handling file uploads when you're building a web server. For this case, the `parseMultipartRequest` function is your friend. It will automatically validate the request is `multipart/form-data`, extract the multipart boundary from the `Content-Type` header, parse all fields and files in the `request.body` stream, and `yield` each one to you as a `MultipartPart` object so you can save it to disk or upload it somewhere. +The most common use case for `multipart-parser` is handling file uploads when you're building a web server. For this case, the `parseMultipartRequest` function is your friend. It will automatically validate the request is `multipart/form-data`, extract the multipart boundary from the `Content-Type` header, parse all fields and files in the `request.body` stream, and give each one to you as a `MultipartPart` object so you can save it to disk or upload it somewhere. ```ts import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser'; @@ -38,13 +38,14 @@ import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart- async function handleRequest(request: Request): void { try { await parseMultipartRequest(request, (part) => { - console.log(part.name); - console.log(part.filename); - - if (/^text\//.test(part.mediaType)) { - console.log(await part.text()); + if (part.isFile) { + let buffer = await part.bytes(); // Uint8Array + console.log(`File received: ${part.filename} (${buffer.length} bytes)`); + console.log(`Content type: ${part.mediaType}`); + console.log(`Field name: ${part.name}`); } else { - // TODO: part.body is a ReadableStream, stream it to a file + let text = await part.text(); // string + console.log(`Field received: ${part.name} = ${JSON.stringify(text)}`); } }); } catch (error) { @@ -57,68 +58,62 @@ async function handleRequest(request: Request): void { } ``` -The main module (`import from "@mjackson/multipart-parser"`) assumes you're working with [the fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) (`Request`, `ReadableStream`, etc). Support for these interfaces was added to Node.js by the [undici](https://github.com/nodejs/undici) project in [version 16.5.0](https://nodejs.org/en/blog/release/v16.5.0). +## Limiting File Upload Size -If however you're building a server for Node.js that relies on node-specific APIs like `http.IncomingMessage`, `stream.Readable`, and `buffer.Buffer` (ala Express or `http.createServer`), `multipart-parser` ships with an additional module that works directly with these APIs. +A common use case when handling file uploads is limiting the size of uploaded files to prevent malicious users from sending very large files that may overload your server's memory and/or storage capacity. You can set a file upload size limit using the `maxFileSize` option, and return a 413 "Payload Too Large" response when you receive a request that exceeds the limit. ```ts -import * as http from 'node:http'; -import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser/node'; +import { + MultipartParseError, + MaxFileSizeExceededError, + parseMultipartRequest, +} from '@mjackson/multipart-parser/node'; -const server = http.createServer(async (req, res) => { - try { - await parseMultipartRequest(req, (part) => { - console.log(part.name); - console.log(part.filename); - console.log(part.mediaType); +const oneMb = Math.pow(2, 20); +async function handleRequest(request: Request): Promise { + try { + await parseMultipartRequest(request, { maxFileSize: 10 * oneMb }, (part) => { // ... }); } catch (error) { - if (error instanceof MultipartParseError) { - console.error('Failed to parse multipart request:', error.message); + if (error instanceof MaxFileSizeExceededError) { + return new Response('File size limit exceeded', { status: 413 }); + } else if (error instanceof MultipartParseError) { + return new Response('Failed to parse multipart request', { status: 400 }); } else { - console.error('An unexpected error occurred:', error); + console.error(error); + return new Response('Internal Server Error', { status: 500 }); } } -}); - -server.listen(8080); +} ``` -## Limiting File Upload Size +## Node.js Support -A common use case when handling file uploads is limiting the size of uploaded files to prevent malicious users from sending very large files that may overload your server's memory and/or storage capacity. You can set a file upload size limit using the `maxFileSize` option, and return a 413 "Payload Too Large" response when you receive a request that exceeds the limit. +The main module (`import from "@mjackson/multipart-parser"`) assumes you're working with [the fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) (`Request`, `ReadableStream`, etc). Support for these interfaces was added to Node.js by the [undici](https://github.com/nodejs/undici) project in [version 16.5.0](https://nodejs.org/en/blog/release/v16.5.0). + +If however you're building a server for Node.js that relies on node-specific APIs like `http.IncomingMessage`, `stream.Readable`, and `buffer.Buffer` (ala Express or `http.createServer`), `multipart-parser` ships with an additional module that works directly with these APIs. ```ts import * as http from 'node:http'; -import { - MultipartParseError, - MaxFileSizeExceededError, - parseMultipartRequest, -} from '@mjackson/multipart-parser/node'; - -const tenMb = 10 * Math.pow(2, 20); +import { MultipartParseError, parseMultipartRequest } from '@mjackson/multipart-parser/node'; const server = http.createServer(async (req, res) => { try { - await parseMultipartRequest(req, { maxFileSize: tenMb }, (part) => { + await parseMultipartRequest(req, (part) => { // ... }); } catch (error) { - if (error instanceof MaxFileSizeExceededError) { - res.writeHead(413); - res.end(error.message); - } else if (error instanceof MultipartParseError) { - res.writeHead(400); - res.end('Invalid multipart request'); + if (error instanceof MultipartParseError) { + console.error('Failed to parse multipart request:', error.message); } else { - console.error(error); - res.writeHead(500); - res.end('Internal Server Error'); + console.error('An unexpected error occurred:', error); } } }); + +server.listen(8080); ``` ## Low-level API From b34459c8228e4682fb47939cfe520e0b2ff8f1c7 Mon Sep 17 00:00:00 2001 From: Jacob Ebey Date: Tue, 4 Feb 2025 20:52:51 -0800 Subject: [PATCH 634/730] fix: make headers HTTPs compatible When using https headers such as `:method` exist, and these are "invalid" headers in the Fetch spec causing errors to be thrown during Request construction. --- packages/node-fetch-server/src/lib/request-listener.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index 14de6c15049..e2046b30bfb 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -172,6 +172,7 @@ export function createHeaders(req: http.IncomingMessage): Headers { let rawHeaders = req.rawHeaders; for (let i = 0; i < rawHeaders.length; i += 2) { + if (rawHeaders[i].startsWith(":")) continue; headers.append(rawHeaders[i], rawHeaders[i + 1]); } From a520244eb01e040fa5031a15ebe38910dd12de6c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 6 Feb 2025 09:07:59 -0800 Subject: [PATCH 635/730] Use Request directly in tests --- .../src/lib/multipart-request.test.ts | 161 ++++++++++++------ .../src/lib/multipart.node.test.ts | 10 +- packages/multipart-parser/test/utils.node.ts | 30 ++-- packages/multipart-parser/test/utils.ts | 108 ++++-------- 4 files changed, 162 insertions(+), 147 deletions(-) diff --git a/packages/multipart-parser/src/lib/multipart-request.test.ts b/packages/multipart-parser/src/lib/multipart-request.test.ts index 90550f9146c..e7cbe3d7a7d 100644 --- a/packages/multipart-parser/src/lib/multipart-request.test.ts +++ b/packages/multipart-parser/src/lib/multipart-request.test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { createMockRequest, createMultipartMockRequest, getRandomBytes } from '../../test/utils.ts'; +import { createMultipartMessage, getRandomBytes } from '../../test/utils.ts'; import { MultipartParseError, @@ -33,7 +33,7 @@ describe('getMultipartBoundary', async () => { describe('isMultipartRequest', async () => { it('returns true for multipart/form-data requests', async () => { - let request = createMockRequest({ + let request = new Request('https://example.com', { headers: { 'Content-Type': 'multipart/form-data' }, }); @@ -41,7 +41,7 @@ describe('isMultipartRequest', async () => { }); it('returns true for multipart/mixed requests', async () => { - let request = createMockRequest({ + let request = new Request('https://example.com', { headers: { 'Content-Type': 'multipart/mixed' }, }); @@ -49,7 +49,7 @@ describe('isMultipartRequest', async () => { }); it('returns false for other content types', async () => { - let request = createMockRequest({ + let request = new Request('https://example.com', { headers: { 'Content-Type': 'text/plain' }, }); @@ -58,10 +58,16 @@ describe('isMultipartRequest', async () => { }); describe('parseMultipartRequest', async () => { - let boundary = 'boundary123'; + let boundary = '----WebKitFormBoundaryz8Zv2UxQ7f4a0Z3H'; it('parses an empty multipart message', async () => { - let request = createMultipartMockRequest(boundary); + let request = new Request('https://example.com', { + method: 'POST', + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + body: `--${boundary}--`, + }); let parts = []; await parseMultipartRequest(request, (part) => { @@ -72,8 +78,14 @@ describe('parseMultipartRequest', async () => { }); it('parses a simple multipart form', async () => { - let request = createMultipartMockRequest(boundary, { - field1: 'value1', + let request = new Request('https://example.com', { + method: 'POST', + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + body: createMultipartMessage(boundary, { + field1: 'value1', + }), }); let parts: MultipartPart[] = []; @@ -87,9 +99,15 @@ describe('parseMultipartRequest', async () => { }); it('parses multiple parts correctly', async () => { - let request = createMultipartMockRequest(boundary, { - field1: 'value1', - field2: 'value2', + let request = new Request('https://example.com', { + method: 'POST', + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + body: createMultipartMessage(boundary, { + field1: 'value1', + field2: 'value2', + }), }); let parts: MultipartPart[] = []; @@ -105,8 +123,14 @@ describe('parseMultipartRequest', async () => { }); it('parses empty parts correctly', async () => { - let request = createMultipartMockRequest(boundary, { - empty: '', + let request = new Request('https://example.com', { + method: 'POST', + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + body: createMultipartMessage(boundary, { + empty: '', + }), }); let parts: MultipartPart[] = []; @@ -120,12 +144,18 @@ describe('parseMultipartRequest', async () => { }); it('parses file uploads correctly', async () => { - let request = createMultipartMockRequest(boundary, { - file1: { - filename: 'test.txt', - mediaType: 'text/plain', - content: 'File content', + let request = new Request('https://example.com', { + method: 'POST', + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, + body: createMultipartMessage(boundary, { + file1: { + filename: 'test.txt', + mediaType: 'text/plain', + content: 'File content', + }, + }), }); let parts: MultipartPart[] = []; @@ -141,14 +171,20 @@ describe('parseMultipartRequest', async () => { }); it('parses multiple fields and a file upload', async () => { - let request = createMultipartMockRequest(boundary, { - field1: 'value1', - field2: 'value2', - file1: { - filename: 'test.txt', - mediaType: 'text/plain', - content: 'File content', + let request = new Request('https://example.com', { + method: 'POST', + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, + body: createMultipartMessage(boundary, { + field1: 'value1', + field2: 'value2', + file1: { + filename: 'test.txt', + mediaType: 'text/plain', + content: 'File content', + }, + }), }); let parts: MultipartPart[] = []; @@ -169,12 +205,18 @@ describe('parseMultipartRequest', async () => { it('parses large file uploads correctly', async () => { let content = getRandomBytes(10 * 1024 * 1024); // 10 MB file - let request = createMultipartMockRequest(boundary, { - file1: { - filename: 'random.dat', - mediaType: 'application/octet-stream', - content, + let request = new Request('https://example.com', { + method: 'POST', + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, + body: createMultipartMessage(boundary, { + file1: { + filename: 'random.dat', + mediaType: 'application/octet-stream', + content, + }, + }), }); let parts: { name?: string; filename?: string; mediaType?: string; content: Uint8Array }[] = []; @@ -195,8 +237,11 @@ describe('parseMultipartRequest', async () => { }); it('throws when Content-Type is not multipart/form-data', async () => { - let request = createMockRequest({ - headers: { 'Content-Type': 'text/plain' }, + let request = new Request('https://example.com', { + method: 'POST', + headers: { + 'Content-Type': 'text/plain', + }, }); await assert.rejects(async () => { @@ -204,9 +249,13 @@ describe('parseMultipartRequest', async () => { }, MultipartParseError); }); - it('throws when boundary is missing', async () => { - let request = createMockRequest({ - headers: { 'Content-Type': 'multipart/form-data' }, + it('throws when initial boundary is missing', async () => { + let request = new Request('https://example.com', { + method: 'POST', + headers: { + 'Content-Type': 'multipart/form-data', + }, + body: 'Content-Disposition: form-data; name="field1"\r\n\r\nvalue1', }); await assert.rejects(async () => { @@ -215,7 +264,8 @@ describe('parseMultipartRequest', async () => { }); it('throws when header exceeds maximum size', async () => { - let request = createMockRequest({ + let request = new Request('https://example.com', { + method: 'POST', headers: { 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, @@ -235,12 +285,19 @@ describe('parseMultipartRequest', async () => { }); it('throws when a file exceeds maximum size', async () => { - let request = createMultipartMockRequest(boundary, { - file1: { - filename: 'random.dat', - mediaType: 'application/octet-stream', - content: getRandomBytes(11 * 1024 * 1024), // 11 MB file + let request = new Request('https://example.com', { + method: 'POST', + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, + body: [ + `--${boundary}`, + 'Content-Disposition: form-data; name="file1"; filename="random.dat"', + 'Content-Type: application/octet-stream', + '', + getRandomBytes(11 * 1024 * 1024), // 11 MB file + `--${boundary}--`, + ].join(CRLF), }); await assert.rejects(async () => { @@ -249,12 +306,18 @@ describe('parseMultipartRequest', async () => { }); it('errors the stream when a file exceeds maximum size', async () => { - let request = createMultipartMockRequest(boundary, { - file1: { - filename: 'random.dat', - mediaType: 'application/octet-stream', - content: getRandomBytes(11 * 1024 * 1024), // 11 MB file + let request = new Request('https://example.com', { + method: 'POST', + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, + body: createMultipartMessage(boundary, { + file1: { + filename: 'random.dat', + mediaType: 'application/octet-stream', + content: getRandomBytes(11 * 1024 * 1024), // 11 MB file + }, + }), }); let parts: MultipartPart[] = []; @@ -277,7 +340,8 @@ describe('parseMultipartRequest', async () => { }); it('parses malformed parts', async () => { - let request = createMockRequest({ + let request = new Request('https://example.com', { + method: 'POST', headers: { 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, @@ -295,7 +359,8 @@ describe('parseMultipartRequest', async () => { }); it('throws error when final boundary is missing', async () => { - let request = createMockRequest({ + let request = new Request('https://example.com', { + method: 'POST', headers: { 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, diff --git a/packages/multipart-parser/src/lib/multipart.node.test.ts b/packages/multipart-parser/src/lib/multipart.node.test.ts index d4733f7c290..4e050993ce7 100644 --- a/packages/multipart-parser/src/lib/multipart.node.test.ts +++ b/packages/multipart-parser/src/lib/multipart.node.test.ts @@ -2,16 +2,16 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; import { getRandomBytes } from '../../test/utils.ts'; -import { createMultipartMockRequest } from '../../test/utils.node.ts'; +import { createMultipartRequest } from '../../test/utils.node.ts'; import { type MultipartPart } from './multipart.ts'; import { parseMultipartRequest } from './multipart.node.ts'; describe('parseMultipartRequest (node)', () => { - let boundary = 'boundary123'; + let boundary = '----WebKitFormBoundaryzv5f5B2cY6tjQ0Rn'; it('parses an empty multipart message', async () => { - let request = createMultipartMockRequest(boundary); + let request = createMultipartRequest(boundary); let parts = []; await parseMultipartRequest(request, (part) => { @@ -22,7 +22,7 @@ describe('parseMultipartRequest (node)', () => { }); it('parses a simple multipart form', async () => { - let request = createMultipartMockRequest(boundary, { + let request = createMultipartRequest(boundary, { field1: 'value1', }); @@ -38,7 +38,7 @@ describe('parseMultipartRequest (node)', () => { it('parses large file uploads correctly', async () => { let content = getRandomBytes(1024 * 1024 * 10); // 10 MB file - let request = createMultipartMockRequest(boundary, { + let request = createMultipartRequest(boundary, { file1: { filename: 'tesla.jpg', mediaType: 'image/jpeg', diff --git a/packages/multipart-parser/test/utils.node.ts b/packages/multipart-parser/test/utils.node.ts index 6e358fe7dbf..54b477f0d33 100644 --- a/packages/multipart-parser/test/utils.node.ts +++ b/packages/multipart-parser/test/utils.node.ts @@ -1,7 +1,21 @@ import type * as http from 'node:http'; import { Readable } from 'node:stream'; -import { type PartValue, createMultipartBody } from './utils.ts'; +import { type PartValue, createMultipartMessage } from './utils.ts'; + +export function createMultipartRequest( + boundary: string, + parts?: { [name: string]: PartValue }, +): http.IncomingMessage { + let body = createMultipartMessage(boundary, parts); + + let request = createReadable(body) as http.IncomingMessage; + request.headers = { + 'content-type': `multipart/form-data; boundary=${boundary}`, + }; + + return request; +} export function createReadable(content: Uint8Array, chunkSize = 16 * 1024): Readable { let i = 0; @@ -17,17 +31,3 @@ export function createReadable(content: Uint8Array, chunkSize = 16 * 1024): Read }, }); } - -export function createMultipartMockRequest( - boundary: string, - parts?: { [name: string]: PartValue }, -): http.IncomingMessage { - let body = createMultipartBody(boundary, parts); - - let request = createReadable(body) as http.IncomingMessage; - request.headers = { - 'content-type': `multipart/form-data; boundary=${boundary}`, - }; - - return request; -} diff --git a/packages/multipart-parser/test/utils.ts b/packages/multipart-parser/test/utils.ts index ffcfd39ad89..6d813cc7ef0 100644 --- a/packages/multipart-parser/test/utils.ts +++ b/packages/multipart-parser/test/utils.ts @@ -1,67 +1,4 @@ -import Headers from '@mjackson/headers'; - -export function concat(chunks: Uint8Array[]): Uint8Array { - if (chunks.length === 1) return chunks[0]; - - let length = 0; - for (let chunk of chunks) { - length += chunk.length; - } - - let result = new Uint8Array(length); - let offset = 0; - - for (let chunk of chunks) { - result.set(chunk, offset); - offset += chunk.length; - } - - return result; -} - -export function getRandomBytes(size: number): Uint8Array { - let chunks: Uint8Array[] = []; - - for (let i = 0; i < size; i += 65536) { - chunks.push(crypto.getRandomValues(new Uint8Array(Math.min(size - i, 65536)))); - } - - return concat(chunks); -} - -export function createReadableStream( - content: string | Uint8Array, - chunkSize = 64 * 1024, -): ReadableStream { - let encoder = new TextEncoder(); - - return new ReadableStream({ - start(controller) { - for (let i = 0; i < content.length; i += chunkSize) { - controller.enqueue( - typeof content === 'string' - ? encoder.encode(content.slice(i, i + chunkSize)) - : content.subarray(i, i + chunkSize), - ); - } - controller.close(); - }, - }); -} - -export function createMockRequest({ - headers, - body = '', -}: { - headers?: Headers | HeadersInit; - body?: string | Uint8Array | ReadableStream; -}): Request { - return { - headers: headers instanceof Headers ? headers : new Headers(headers), - body: - typeof body === 'string' || body instanceof Uint8Array ? createReadableStream(body) : body, - } as unknown as Request; -} +import SuperHeaders from '@mjackson/headers'; export type PartValue = | string @@ -72,7 +9,7 @@ export type PartValue = content: string | Uint8Array; }; -export function createMultipartBody( +export function createMultipartMessage( boundary: string, parts?: { [name: string]: PartValue }, ): Uint8Array { @@ -91,7 +28,7 @@ export function createMultipartBody( pushLine(`--${boundary}`); if (typeof part === 'string') { - let headers = new Headers({ + let headers = new SuperHeaders({ contentDisposition: { type: 'form-data', name, @@ -102,7 +39,7 @@ export function createMultipartBody( pushLine(); pushLine(part); } else { - let headers = new Headers({ + let headers = new SuperHeaders({ contentDisposition: { type: 'form-data', name, @@ -132,18 +69,31 @@ export function createMultipartBody( return concat(chunks); } -export function createMultipartMockRequest( - boundary: string, - parts?: { [name: string]: PartValue }, -): Request { - let headers = new Headers({ - contentType: { - mediaType: 'multipart/form-data', - boundary, - }, - }); +export function getRandomBytes(size: number): Uint8Array { + let chunks: Uint8Array[] = []; + + for (let i = 0; i < size; i += 65536) { + chunks.push(crypto.getRandomValues(new Uint8Array(Math.min(size - i, 65536)))); + } + + return concat(chunks); +} + +export function concat(chunks: Uint8Array[]): Uint8Array { + if (chunks.length === 1) return chunks[0]; - let body = createMultipartBody(boundary, parts); + let length = 0; + for (let chunk of chunks) { + length += chunk.length; + } - return createMockRequest({ headers, body }); + let result = new Uint8Array(length); + let offset = 0; + + for (let chunk of chunks) { + result.set(chunk, offset); + offset += chunk.length; + } + + return result; } From 2bcbecf229df624bc2838a0f4f87dd67abf76b87 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 6 Feb 2025 10:13:45 -0800 Subject: [PATCH 636/730] More test simplification --- .../src/lib/multipart-request.test.ts | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/multipart-parser/src/lib/multipart-request.test.ts b/packages/multipart-parser/src/lib/multipart-request.test.ts index e7cbe3d7a7d..c64e39e3d50 100644 --- a/packages/multipart-parser/src/lib/multipart-request.test.ts +++ b/packages/multipart-parser/src/lib/multipart-request.test.ts @@ -34,7 +34,10 @@ describe('getMultipartBoundary', async () => { describe('isMultipartRequest', async () => { it('returns true for multipart/form-data requests', async () => { let request = new Request('https://example.com', { - headers: { 'Content-Type': 'multipart/form-data' }, + method: 'POST', + headers: { + 'Content-Type': 'multipart/form-data', + }, }); assert.ok(isMultipartRequest(request)); @@ -42,7 +45,10 @@ describe('isMultipartRequest', async () => { it('returns true for multipart/mixed requests', async () => { let request = new Request('https://example.com', { - headers: { 'Content-Type': 'multipart/mixed' }, + method: 'POST', + headers: { + 'Content-Type': 'multipart/mixed', + }, }); assert.ok(isMultipartRequest(request)); @@ -50,7 +56,10 @@ describe('isMultipartRequest', async () => { it('returns false for other content types', async () => { let request = new Request('https://example.com', { - headers: { 'Content-Type': 'text/plain' }, + method: 'POST', + headers: { + 'Content-Type': 'text/plain', + }, }); assert.ok(!isMultipartRequest(request)); @@ -290,14 +299,13 @@ describe('parseMultipartRequest', async () => { headers: { 'Content-Type': `multipart/form-data; boundary=${boundary}`, }, - body: [ - `--${boundary}`, - 'Content-Disposition: form-data; name="file1"; filename="random.dat"', - 'Content-Type: application/octet-stream', - '', - getRandomBytes(11 * 1024 * 1024), // 11 MB file - `--${boundary}--`, - ].join(CRLF), + body: createMultipartMessage(boundary, { + file1: { + filename: 'random.dat', + mediaType: 'application/octet-stream', + content: getRandomBytes(11 * 1024 * 1024), // 11 MB file + }, + }), }); await assert.rejects(async () => { From cf5fcbcdd888fda197506ee37810133b348e6ebf Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 6 Feb 2025 11:13:38 -0800 Subject: [PATCH 637/730] Change var name --- packages/multipart-parser/test/utils.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/multipart-parser/test/utils.ts b/packages/multipart-parser/test/utils.ts index 6d813cc7ef0..c462cef6534 100644 --- a/packages/multipart-parser/test/utils.ts +++ b/packages/multipart-parser/test/utils.ts @@ -24,10 +24,10 @@ export function createMultipartMessage( } if (parts) { - for (let [name, part] of Object.entries(parts)) { + for (let [name, value] of Object.entries(parts)) { pushLine(`--${boundary}`); - if (typeof part === 'string') { + if (typeof value === 'string') { let headers = new SuperHeaders({ contentDisposition: { type: 'form-data', @@ -37,27 +37,27 @@ export function createMultipartMessage( pushLine(`${headers}`); pushLine(); - pushLine(part); + pushLine(value); } else { let headers = new SuperHeaders({ contentDisposition: { type: 'form-data', name, - filename: part.filename, - filenameSplat: part.filenameSplat, + filename: value.filename, + filenameSplat: value.filenameSplat, }, }); - if (part.mediaType) { - headers.contentType = part.mediaType; + if (value.mediaType) { + headers.contentType = value.mediaType; } pushLine(`${headers}`); pushLine(); - if (typeof part.content === 'string') { - pushLine(part.content); + if (typeof value.content === 'string') { + pushLine(value.content); } else { - chunks.push(part.content); + chunks.push(value.content); pushLine(); } } From 9d95dde9ffd99cc133f2e1cf64f713fafec8cb5a Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 6 Feb 2025 12:10:40 -0800 Subject: [PATCH 638/730] Add http/2 support Closes #42 --- packages/node-fetch-server/CHANGELOG.md | 26 +++++++++++++ .../examples/http2/README.md | 3 ++ .../examples/http2/package.json | 8 ++++ .../examples/http2/server.crt | 17 +++++++++ .../examples/http2/server.csr | 15 ++++++++ .../examples/http2/server.js | 37 +++++++++++++++++++ .../examples/http2/server.key | 27 ++++++++++++++ pnpm-lock.yaml | 6 +++ pnpm-workspace.yaml | 1 + 9 files changed, 140 insertions(+) create mode 100644 packages/node-fetch-server/examples/http2/README.md create mode 100644 packages/node-fetch-server/examples/http2/package.json create mode 100644 packages/node-fetch-server/examples/http2/server.crt create mode 100644 packages/node-fetch-server/examples/http2/server.csr create mode 100644 packages/node-fetch-server/examples/http2/server.js create mode 100644 packages/node-fetch-server/examples/http2/server.key diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index bfdc9908e5a..2cef2d293b6 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -2,6 +2,32 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Add http/2 support with an example + +```ts +import * as http2 from 'node:http2'; +import { createRequestListener } from '@mjackson/node-fetch-server'; + +let server = http2.createSecureServer(options); + +server.on( + 'request', + createRequestListener((request) => { + let url = new URL(request.url); + + if (url.pathname === '/') { + return new Response('Hello HTTP/2!', { + headers: { 'content-type': 'text/plain' }, + }); + } + + return new Response('Not Found', { status: 404 }); + }), +); +``` + ## v0.5.1 (2025-01-25) - Iterate manually over response bodies in `sendResponse` instead of using `for await...of`. This seems to avoid an issue where the iterator tries to read from a stream after the lock has been released. diff --git a/packages/node-fetch-server/examples/http2/README.md b/packages/node-fetch-server/examples/http2/README.md new file mode 100644 index 00000000000..653ec3f1035 --- /dev/null +++ b/packages/node-fetch-server/examples/http2/README.md @@ -0,0 +1,3 @@ +# node-fetch-server HTTP/2 Example + +This is an example of building a http/2 server for Node.js using [the built-in `http2` module](https://nodejs.org/api/http2.html). diff --git a/packages/node-fetch-server/examples/http2/package.json b/packages/node-fetch-server/examples/http2/package.json new file mode 100644 index 00000000000..ca23447b5d9 --- /dev/null +++ b/packages/node-fetch-server/examples/http2/package.json @@ -0,0 +1,8 @@ +{ + "name": "node-fetch-server-http2-example", + "private": true, + "type": "module", + "dependencies": { + "@mjackson/node-fetch-server": "workspace:^" + } +} diff --git a/packages/node-fetch-server/examples/http2/server.crt b/packages/node-fetch-server/examples/http2/server.crt new file mode 100644 index 00000000000..707cb7f4c7d --- /dev/null +++ b/packages/node-fetch-server/examples/http2/server.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICpDCCAYwCCQDont9/q43GLTANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls +b2NhbGhvc3QwHhcNMjUwMjA2MTkyMjU5WhcNMjYwMjA2MTkyMjU5WjAUMRIwEAYD +VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDX +z69g6TBkbdv0TMeTL3jRLgdiSoTyqjcjLEakgEfPDtS0vLadkrqiTipx5do6CpyB +0vMqrYVgFnnUKykJuTPh5pFIdTFbAKkv3YcyVMRfzt5eMLRFQ5iFbmbzme7BksaZ +D6b0ahwnNPvRGX/Kz362wQ10nK4YP7JCXbc0Ybxvdfq5o8L0uoOjW5K+8JULVLmc +imeXA8NLe8ui/flvBgc/P4qt5SVh0S+/FjTEa12DCzxkvaOmWKqpHjzUMg0aKkrV +Q22hjaEdkgcKomqC/4I3de6bGr828yJltXxTp80/8TaM4U7xPi8hvUfOW+wLPUK9 +ODJ+XtQu1LhtQwwe1a0RAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADsHhsAveJ7N +LOS/J8+y5/KGphlW0/bZzsJGCkm9YMFfPW6U3Ac85X67oahzd7kPI5n2z867dVXO +Ix60enYF3xf2IzcL/FVSL+dDW6JKIp6lB+qdlA7EeN3Segx+NV/fErHUZmL5WmBN +hNlOdEx06uo6Pp21+RyktDMFKBbpDbPrWHziNWJz0mT6SA1RMT8ElWxKXalO6XFT +yJCM/iwpm4SrTZ11j8Nszcv730DrMr/hF+uO4d2N4FzV1NAKv66JpXnzPC1jcCFs +Js7880NtdEdBVadp8gB5Cmu7I6ZcNKe24x1nRNtyddQkgUllKOoIGobrHk02l0PV +0gnz6agIzfQ= +-----END CERTIFICATE----- diff --git a/packages/node-fetch-server/examples/http2/server.csr b/packages/node-fetch-server/examples/http2/server.csr new file mode 100644 index 00000000000..e3ffa3e32a9 --- /dev/null +++ b/packages/node-fetch-server/examples/http2/server.csr @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICWTCCAUECAQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA18+vYOkwZG3b9EzHky940S4HYkqE8qo3IyxGpIBH +zw7UtLy2nZK6ok4qceXaOgqcgdLzKq2FYBZ51CspCbkz4eaRSHUxWwCpL92HMlTE +X87eXjC0RUOYhW5m85nuwZLGmQ+m9GocJzT70Rl/ys9+tsENdJyuGD+yQl23NGG8 +b3X6uaPC9LqDo1uSvvCVC1S5nIpnlwPDS3vLov35bwYHPz+KreUlYdEvvxY0xGtd +gws8ZL2jpliqqR481DINGipK1UNtoY2hHZIHCqJqgv+CN3Xumxq/NvMiZbV8U6fN +P/E2jOFO8T4vIb1HzlvsCz1CvTgyfl7ULtS4bUMMHtWtEQIDAQABoAAwDQYJKoZI +hvcNAQELBQADggEBAMyfFv3WSqg/X6RmrIZjuFdZ6fnV8Gd5twFuzGWcxcTaxQZx +OwY7hKXXFsTRjx15T84wV7KcRK26RY9CJB+28zWp5r67/zLO1DkeZ+DuDjyazLPD +iPMmpOhzK9dsu3ymhRjlQcKtUHfK5x/hlSvKaL8LYhEMY8G16ST8GQxoNAR+ax6t +zq+wS7WccS7kKXr4uJf0H0KL3CqkmzLDlyiV/4f2UGQPk2riYihPuaikb5tLftUv +cDsLwa4YOU6shdKa6Z0yq2oMjRYzAS79/gF22oxs5pK0Fzf5geQGjbzqd/CPrvWM +M0IMtej9xpq+CfQv/pxAxmLEMW4WCnnqFwCN/xI= +-----END CERTIFICATE REQUEST----- diff --git a/packages/node-fetch-server/examples/http2/server.js b/packages/node-fetch-server/examples/http2/server.js new file mode 100644 index 00000000000..45d54f46c47 --- /dev/null +++ b/packages/node-fetch-server/examples/http2/server.js @@ -0,0 +1,37 @@ +import * as http2 from 'node:http2'; +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { createRequestListener } from '@mjackson/node-fetch-server'; + +const __dirname = path.dirname(new URL(import.meta.url).pathname); +const PORT = 3000; + +let options = { + key: fs.readFileSync(path.join(__dirname, 'server.key')), + cert: fs.readFileSync(path.join(__dirname, 'server.crt')), +}; + +let server = http2.createSecureServer(options); + +server.on( + 'request', + createRequestListener((request) => { + let url = new URL(request.url); + + if (url.pathname === '/') { + return new Response('Hello HTTP/2!', { + headers: { 'content-type': 'text/plain' }, + }); + } + + return new Response('Not Found', { status: 404 }); + }), +); + +server.on('error', (err) => { + console.error('Server error:', err); +}); + +server.listen(PORT, () => { + console.log(`Server running at https://localhost:${PORT}`); +}); diff --git a/packages/node-fetch-server/examples/http2/server.key b/packages/node-fetch-server/examples/http2/server.key new file mode 100644 index 00000000000..530cf832bd2 --- /dev/null +++ b/packages/node-fetch-server/examples/http2/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA18+vYOkwZG3b9EzHky940S4HYkqE8qo3IyxGpIBHzw7UtLy2 +nZK6ok4qceXaOgqcgdLzKq2FYBZ51CspCbkz4eaRSHUxWwCpL92HMlTEX87eXjC0 +RUOYhW5m85nuwZLGmQ+m9GocJzT70Rl/ys9+tsENdJyuGD+yQl23NGG8b3X6uaPC +9LqDo1uSvvCVC1S5nIpnlwPDS3vLov35bwYHPz+KreUlYdEvvxY0xGtdgws8ZL2j +pliqqR481DINGipK1UNtoY2hHZIHCqJqgv+CN3Xumxq/NvMiZbV8U6fNP/E2jOFO +8T4vIb1HzlvsCz1CvTgyfl7ULtS4bUMMHtWtEQIDAQABAoIBAGlbyDgcv/ZXt+lF +zq0poOcmfI5c6Rj7Rp3SUM6gne4VRHzUIKc+6gSw+oHOgEKTyaKL1RFB03p8no+Z +XpiTpSOlB8qDBEx0PyTSFt3YimJnwSHkzy19eamyo2pL/UbdnD0/aferEgGGGWYU +99GQiUE5cJM8prXJ6wIBdJ6LFI6o+fNWjWAQeg6wEuA3MbfvQ4uZo8WvknVaJLqa +AYMPK/V1bT9/hmaLFfDiLMrD92ZC+mJqgEvsLrU64mQmASa7Zfh9v6sqqS6h4vjZ +fmJfQjG1+g1rCkE2kHEYKmziz3A0A5FUjWwny3RSt9lbIJh2E0vcgYtbF3abUCIe +aQOQkP0CgYEA7MLq430P+Arn2xFPX8Y7XeQftv++qBsLZeq4lSV6ru1/mG68xFrm +fqXI/xi3lyfbezpG0BFQGqVFB1f70IMGKcM7Ph1l5mI4OWcpqzcKi8UqGRzeFJ9Z +NB7HWrU8h2dl/d5yRF4EmYj2RrBxoZdjN0H+3yL/TotcTuPPPbDKeRMCgYEA6Vj3 +Kjnn3avIMK/UWkREXoGCvRQH2wD4h6vQs1ro2PNMyWB+JS1XxucJbPfDmZhqxkyt +rWehadRrmlMfTX27llRjeoVH3h54QE58lgLme+Ak3qjNiiUlFVFiCpEaYrba3iDk +A3jqQ1naqXyP6sbiItRZ96v05hiWIYe8WkaiCcsCgYAUziAT84Z2toafUosWEHZh +Ds3Wp+yaGx5KS3EC8jMwsgAXZgvCeXZtxKW//O0NJFx+HKXiXNMcNE+3kHy5Wvos +q1JGaBDvSMxGBxG7UO/lTmMfp9DAISyWjunXx7tU7rogr+58oYJn94gkuBaUK5h1 +X6BE/W9P+KEY8Z3hfuqb7wKBgHGDhtEy1BmgvET68/lpZjz3Eat7OAsQoNYW/fKS +Ed2gFcWMvDDHqwCmWY55xNxOKfsHSCGn3PzHigTL1Nl0hbGuoanzdi+WcPcPd0ne +ZVLzidwLD9nZEf4Z1fC//67vtu8B3wnVY1iaOGXko3oZf95joNR8ASmB4l6zUiw0 +WhUbAoGBAJIAzNQMMIF3fSUL4CnhTaWuo6UNUvQjXiSfx9opzWLfMWgGqoJ1RqEF +HTL3jLQQfypqy6E0LtVRMhXJL/J1dY46ZJmkYxosDyfi1Om1wmKV4mbUGoIKiMFd +1uOjZjUX3/XGA5rt1pdQxdwbauDgrPorQkKJFFWbCYZ9YCAxGxP9 +-----END RSA PRIVATE KEY----- diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1e21998bbfe..edcd03edecc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -225,6 +225,12 @@ importers: specifier: ^4.17.21 version: 4.17.21 + packages/node-fetch-server/examples/http2: + dependencies: + '@mjackson/node-fetch-server': + specifier: workspace:^ + version: link:../.. + packages/tar-parser: devDependencies: '@mjackson/lazy-file': diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index dc4b22e4ab0..77a1d23d7b4 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,5 +4,6 @@ packages: - packages/multipart-parser/bench - packages/multipart-parser/examples/* - packages/node-fetch-server/bench + - packages/node-fetch-server/examples/* - packages/tar-parser/bench - scripts From 7fcb204696f9cfedf66d233f83291d2a6d3fbe2e Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 6 Feb 2025 12:11:33 -0800 Subject: [PATCH 639/730] Release node-fetch-server@0.6.0 --- packages/node-fetch-server/CHANGELOG.md | 2 +- packages/node-fetch-server/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 2cef2d293b6..111b7f80cbc 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.6.0 (2025-02-06) - Add http/2 support with an example diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index e8519c2dff4..3480d349573 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/node-fetch-server", - "version": "0.5.1", + "version": "0.6.0", "description": "Build servers for Node.js using the web fetch API", "author": "Michael Jackson ", "repository": { From 79aeec75ddc20e0cee9938007ea17277b7fbe220 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 6 Feb 2025 12:14:14 -0800 Subject: [PATCH 640/730] Update CHANGELOG --- packages/node-fetch-server/CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 111b7f80cbc..832eca4a62d 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -4,7 +4,7 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remi ## v0.6.0 (2025-02-06) -- Add http/2 support with an example +- Add http/2 support ```ts import * as http2 from 'node:http2'; @@ -19,7 +19,9 @@ server.on( if (url.pathname === '/') { return new Response('Hello HTTP/2!', { - headers: { 'content-type': 'text/plain' }, + headers: { + 'Content-Type': 'text/plain', + }, }); } From 0171e4c6694ede4d7eb16b63a378ad8d72da22aa Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 6 Feb 2025 12:14:41 -0800 Subject: [PATCH 641/730] Update example --- packages/node-fetch-server/examples/http2/server.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/node-fetch-server/examples/http2/server.js b/packages/node-fetch-server/examples/http2/server.js index 45d54f46c47..5eda12fc9d8 100644 --- a/packages/node-fetch-server/examples/http2/server.js +++ b/packages/node-fetch-server/examples/http2/server.js @@ -20,7 +20,9 @@ server.on( if (url.pathname === '/') { return new Response('Hello HTTP/2!', { - headers: { 'content-type': 'text/plain' }, + headers: { + 'Content-Type': 'text/plain', + }, }); } From 305dbe425f94969877b8e017459ac8a7dfa25cd8 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 6 Feb 2025 15:44:19 -0800 Subject: [PATCH 642/730] Fix regression in file storage Fixes #53 --- packages/file-storage/CHANGELOG.md | 4 ++ packages/file-storage/package.json | 1 + .../src/lib/local-file-storage.test.ts | 38 +++++++++++++++++++ .../src/lib/local-file-storage.ts | 13 ++----- .../src/lib/memory-file-storage.test.ts | 38 +++++++++++++++++++ .../src/lib/memory-file-storage.ts | 2 +- pnpm-lock.yaml | 3 ++ 7 files changed, 89 insertions(+), 10 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index 0df762f8fe7..bdb6ae39f51 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -2,6 +2,10 @@ This is the changelog for [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Fix regression when using `LocalFileStorage` together with `form-data-parser` (see #53) + ## v0.6.0 (2025-02-04) - BREAKING CHANGE: `LocalFileStorage` now uses 2 characters for shard directory names instead of 8. diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index 104459ce275..312180a3af9 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -79,6 +79,7 @@ "@mjackson/lazy-file": "workspace:^" }, "devDependencies": { + "@mjackson/form-data-parser": "workspace:^", "@types/node": "^20.14.10", "tsup": "^8.3.5" }, diff --git a/packages/file-storage/src/lib/local-file-storage.test.ts b/packages/file-storage/src/lib/local-file-storage.test.ts index 0befbd2978c..baca37e4618 100644 --- a/packages/file-storage/src/lib/local-file-storage.test.ts +++ b/packages/file-storage/src/lib/local-file-storage.test.ts @@ -2,6 +2,7 @@ import * as assert from 'node:assert/strict'; import { afterEach, describe, it } from 'node:test'; import * as fs from 'node:fs'; import * as path from 'node:path'; +import { parseFormData } from '@mjackson/form-data-parser'; import { LocalFileStorage } from './local-file-storage.ts'; @@ -136,4 +137,41 @@ describe('LocalFileStorage', () => { assert.ok(retrieved2); assert.equal(await retrieved2.text(), 'Hello, universe!'); }); + + describe('integration with form-data-parser', () => { + it('stores and lists file uploads', async () => { + let storage = new LocalFileStorage(directory); + + let boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW'; + let request = new Request('http://example.com', { + method: 'POST', + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + body: [ + `--${boundary}`, + 'Content-Disposition: form-data; name="hello"; filename="hello.txt"', + 'Content-Type: text/plain', + '', + 'Hello, world!', + `--${boundary}--`, + ].join('\r\n'), + }); + + await parseFormData(request, async (file) => { + await storage.set('hello', file); + }); + + assert.ok(await storage.has('hello')); + + let { files } = await storage.list({ includeMetadata: true }); + + assert.equal(files.length, 1); + assert.equal(files[0].key, 'hello'); + assert.equal(files[0].name, 'hello.txt'); + assert.equal(files[0].size, 13); + assert.equal(files[0].type, 'text/plain'); + assert.ok(files[0].lastModified); + }); + }); }); diff --git a/packages/file-storage/src/lib/local-file-storage.ts b/packages/file-storage/src/lib/local-file-storage.ts index 738348cd8f1..e0aeeb59f19 100644 --- a/packages/file-storage/src/lib/local-file-storage.ts +++ b/packages/file-storage/src/lib/local-file-storage.ts @@ -3,12 +3,7 @@ import * as fsp from 'node:fs/promises'; import * as path from 'node:path'; import { openFile, writeFile } from '@mjackson/lazy-file/fs'; -import { - type FileStorage, - type FileMetadata, - type ListOptions, - type ListResult, -} from './file-storage.ts'; +import type { FileStorage, FileMetadata, ListOptions, ListResult } from './file-storage.ts'; /** * A `FileStorage` that is backed by a directory on the local filesystem. @@ -105,7 +100,8 @@ export class LocalFileStorage implements FileStorage { } if (includeMetadata) { - files.push(meta); + let size = (await fsp.stat(path.join(this.#dirname, subdir.name, `${hash}.dat`))).size; + files.push({ ...meta, size }); } else { files.push({ key: meta.key }); } @@ -151,11 +147,10 @@ export class LocalFileStorage implements FileStorage { await writeFile(filePath, file); - let meta: FileMetadata = { + let meta: Omit = { key, lastModified: file.lastModified, name: file.name, - size: file.size, type: file.type, }; await fsp.writeFile(metaPath, JSON.stringify(meta)); diff --git a/packages/file-storage/src/lib/memory-file-storage.test.ts b/packages/file-storage/src/lib/memory-file-storage.test.ts index 8a0ecd421f3..0f31266110a 100644 --- a/packages/file-storage/src/lib/memory-file-storage.test.ts +++ b/packages/file-storage/src/lib/memory-file-storage.test.ts @@ -1,5 +1,6 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; +import { parseFormData } from '@mjackson/form-data-parser'; import { MemoryFileStorage } from './memory-file-storage.ts'; @@ -97,4 +98,41 @@ describe('MemoryFileStorage', () => { files.forEach((f) => assert.ok('size' in f)); files.forEach((f) => assert.ok('type' in f)); }); + + describe('integration with form-data-parser', () => { + it('stores and lists file uploads', async () => { + let storage = new MemoryFileStorage(); + + let boundary = '----WebKitFormBoundaryzv5f5B8XUeVl7e0A'; + let request = new Request('http://example.com', { + method: 'POST', + headers: { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, + }, + body: [ + `--${boundary}`, + 'Content-Disposition: form-data; name="a"; filename="hello.txt"', + 'Content-Type: text/plain', + '', + 'Hello, world!', + `--${boundary}--`, + ].join('\r\n'), + }); + + await parseFormData(request, async (file) => { + await storage.put('hello', file); + }); + + assert.ok(storage.has('hello')); + + let { files } = storage.list({ includeMetadata: true }); + + assert.equal(files.length, 1); + assert.equal(files[0].key, 'hello'); + assert.equal(files[0].name, 'hello.txt'); + assert.equal(files[0].size, 13); + assert.equal(files[0].type, 'text/plain'); + assert.ok(files[0].lastModified); + }); + }); }); diff --git a/packages/file-storage/src/lib/memory-file-storage.ts b/packages/file-storage/src/lib/memory-file-storage.ts index 6cd43c5509e..864dbbd5b63 100644 --- a/packages/file-storage/src/lib/memory-file-storage.ts +++ b/packages/file-storage/src/lib/memory-file-storage.ts @@ -1,4 +1,4 @@ -import { type FileStorage, type ListOptions, type ListResult } from './file-storage.ts'; +import type { FileStorage, ListOptions, ListResult } from './file-storage.ts'; /** * A simple, in-memory implementation of the `FileStorage` interface. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index edcd03edecc..c1a5e2e9011 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,6 +34,9 @@ importers: specifier: workspace:^ version: link:../lazy-file devDependencies: + '@mjackson/form-data-parser': + specifier: workspace:^ + version: link:../form-data-parser '@types/node': specifier: ^20.14.10 version: 20.16.1 From 36b2ee49d2eab4a420695f3c7e289e6df7910862 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 6 Feb 2025 15:47:05 -0800 Subject: [PATCH 643/730] Release file-storage@0.6.1 --- packages/file-storage/CHANGELOG.md | 2 +- packages/file-storage/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/file-storage/CHANGELOG.md b/packages/file-storage/CHANGELOG.md index bdb6ae39f51..43a739d3031 100644 --- a/packages/file-storage/CHANGELOG.md +++ b/packages/file-storage/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`file-storage`](https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.6.1 (2025-02-06) - Fix regression when using `LocalFileStorage` together with `form-data-parser` (see #53) diff --git a/packages/file-storage/package.json b/packages/file-storage/package.json index 312180a3af9..521b65798a6 100644 --- a/packages/file-storage/package.json +++ b/packages/file-storage/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/file-storage", - "version": "0.6.0", + "version": "0.6.1", "description": "Key/value storage for JavaScript File objects", "author": "Michael Jackson ", "repository": { From 066cb889f8b1753680ed660d166e5f24af106cb4 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 6 Feb 2025 16:55:06 -0800 Subject: [PATCH 644/730] More accurate type --- packages/file-storage/src/lib/local-file-storage.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/file-storage/src/lib/local-file-storage.ts b/packages/file-storage/src/lib/local-file-storage.ts index e0aeeb59f19..dd62d3cc01b 100644 --- a/packages/file-storage/src/lib/local-file-storage.ts +++ b/packages/file-storage/src/lib/local-file-storage.ts @@ -5,6 +5,8 @@ import { openFile, writeFile } from '@mjackson/lazy-file/fs'; import type { FileStorage, FileMetadata, ListOptions, ListResult } from './file-storage.ts'; +type MetadataJson = Omit; + /** * A `FileStorage` that is backed by a directory on the local filesystem. * @@ -147,7 +149,7 @@ export class LocalFileStorage implements FileStorage { await writeFile(filePath, file); - let meta: Omit = { + let meta: MetadataJson = { key, lastModified: file.lastModified, name: file.name, @@ -168,7 +170,7 @@ export class LocalFileStorage implements FileStorage { } } -async function readMetadata(metaPath: string): Promise { +async function readMetadata(metaPath: string): Promise { return JSON.parse(await fsp.readFile(metaPath, 'utf-8')); } From ae0b215a483b9ebcf3029e54595f1c705429bfb2 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 6 Feb 2025 17:00:26 -0800 Subject: [PATCH 645/730] No need to remove old files before setting new ones in LocalFileStorage --- packages/file-storage/src/lib/local-file-storage.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/file-storage/src/lib/local-file-storage.ts b/packages/file-storage/src/lib/local-file-storage.ts index dd62d3cc01b..88684972a13 100644 --- a/packages/file-storage/src/lib/local-file-storage.ts +++ b/packages/file-storage/src/lib/local-file-storage.ts @@ -139,9 +139,6 @@ export class LocalFileStorage implements FileStorage { } async set(key: string, file: File): Promise { - // Remove any existing file with the same key. - await this.remove(key); - let { directory, filePath, metaPath } = await this.#getPaths(key); // Ensure directory exists From e1a4f98647bf96be5fc6e15c7eb7721b80f581b2 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 6 Feb 2025 17:17:53 -0800 Subject: [PATCH 646/730] Update typings and docs for http2 --- packages/node-fetch-server/CHANGELOG.md | 4 ++ .../src/lib/request-listener.ts | 42 ++++++++++++------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 832eca4a62d..69c750b8b47 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -2,6 +2,10 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server). It follows [semantic versioning](https://semver.org/). +## HEAD + +- Update typings and docs for http2 support + ## v0.6.0 (2025-02-06) - Add http/2 support diff --git a/packages/node-fetch-server/src/lib/request-listener.ts b/packages/node-fetch-server/src/lib/request-listener.ts index e2046b30bfb..8f371287209 100644 --- a/packages/node-fetch-server/src/lib/request-listener.ts +++ b/packages/node-fetch-server/src/lib/request-listener.ts @@ -1,6 +1,7 @@ import type * as http from 'node:http'; +import type * as http2 from 'node:http2'; -import { type ClientAddress, type ErrorHandler, type FetchHandler } from './fetch-handler.ts'; +import type { ClientAddress, ErrorHandler, FetchHandler } from './fetch-handler.ts'; import { readStream } from './read-stream.ts'; export interface RequestListenerOptions { @@ -30,9 +31,12 @@ export interface RequestListenerOptions { } /** - * Wraps a fetch handler in a Node.js `http.RequestListener` that can be used with - * [`http.createServer()`](https://nodejs.org/api/http.html#httpcreateserveroptions-requestlistener) or - * [`https.createServer()`](https://nodejs.org/api/https.html#httpscreateserveroptions-requestlistener). + * Wraps a fetch handler in a Node.js request listener that can be used with: + * + * - [`http.createServer()`](https://nodejs.org/api/http.html#httpcreateserveroptions-requestlistener) + * - [`https.createServer()`](https://nodejs.org/api/https.html#httpscreateserveroptions-requestlistener) + * - [`http2.createServer()`](https://nodejs.org/api/http2.html#http2createserveroptions-onrequesthandler) + * - [`http2.createSecureServer()`](https://nodejs.org/api/http2.html#http2createsecureserveroptions-onrequesthandler) * * Example: * @@ -109,9 +113,10 @@ function internalServerError(): Response { export type RequestOptions = Omit; /** - * Creates a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) object from a Node.js - * [`http.IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage) and - * [`http.ServerResponse`](https://nodejs.org/api/http.html#class-httpserverresponse) pair. + * Creates a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) object from + * + * - a [`http.IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage)/[`http.ServerResponse`](https://nodejs.org/api/http.html#class-httpserverresponse) pair + * - a [`http2.Http2ServerRequest`](https://nodejs.org/api/http2.html#class-http2http2serverrequest)/[`http2.Http2ServerResponse`](https://nodejs.org/api/http2.html#class-http2http2serverresponse) pair * * @param req The incoming request object. * @param res The server response object. @@ -119,8 +124,8 @@ export type RequestOptions = Omit; * @returns A request object. */ export function createRequest( - req: http.IncomingMessage, - res: http.ServerResponse, + req: http.IncomingMessage | http2.Http2ServerRequest, + res: http.ServerResponse | http2.Http2ServerResponse, options?: RequestOptions, ): Request { let controller = new AbortController(); @@ -161,18 +166,18 @@ export function createRequest( } /** - * Creates a [`Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers) object from the headers - * in a Node.js [`http.IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage). + * Creates a [`Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers) object from the headers in a Node.js + * [`http.IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage)/[`http2.Http2ServerRequest`](https://nodejs.org/api/http2.html#class-http2http2serverrequest). * * @param req The incoming request object. * @returns A headers object. */ -export function createHeaders(req: http.IncomingMessage): Headers { +export function createHeaders(req: http.IncomingMessage | http2.Http2ServerRequest): Headers { let headers = new Headers(); let rawHeaders = req.rawHeaders; for (let i = 0; i < rawHeaders.length; i += 2) { - if (rawHeaders[i].startsWith(":")) continue; + if (rawHeaders[i].startsWith(':')) continue; headers.append(rawHeaders[i], rawHeaders[i + 1]); } @@ -180,13 +185,17 @@ export function createHeaders(req: http.IncomingMessage): Headers { } /** - * Sends a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) to the client using the - * Node.js [`http.ServerResponse`](https://nodejs.org/api/http.html#class-httpserverresponse) object. + * Sends a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) to the client using a Node.js + * [`http.ServerResponse`](https://nodejs.org/api/http.html#class-httpserverresponse)/[`http2.Http2ServerResponse`](https://nodejs.org/api/http2.html#class-http2http2serverresponse) + * object. * * @param res The server response object. * @param response The response to send. */ -export async function sendResponse(res: http.ServerResponse, response: Response): Promise { +export async function sendResponse( + res: http.ServerResponse | http2.Http2ServerResponse, + response: Response, +): Promise { // Iterate over response.headers so we are sure to send multiple Set-Cookie headers correctly. // These would incorrectly be merged into a single header if we tried to use // `Object.fromEntries(response.headers.entries())`. @@ -207,6 +216,7 @@ export async function sendResponse(res: http.ServerResponse, response: Response) if (response.body != null && res.req.method !== 'HEAD') { for await (let chunk of readStream(response.body)) { + // @ts-expect-error - Node typings for http2 require a 2nd parameter to write but it's optional res.write(chunk); } } From fbd6f01bf0bde2b5343f5ca0c7bdc18bab906dff Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 6 Feb 2025 17:19:26 -0800 Subject: [PATCH 647/730] Release node-fetch-server@0.6.1 --- packages/node-fetch-server/CHANGELOG.md | 2 +- packages/node-fetch-server/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/node-fetch-server/CHANGELOG.md b/packages/node-fetch-server/CHANGELOG.md index 69c750b8b47..92d8763cb48 100644 --- a/packages/node-fetch-server/CHANGELOG.md +++ b/packages/node-fetch-server/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog for [`node-fetch-server`](https://github.com/mjackson/remix-the-web/tree/main/packages/node-fetch-server). It follows [semantic versioning](https://semver.org/). -## HEAD +## v0.6.1 (2025-02-07) - Update typings and docs for http2 support diff --git a/packages/node-fetch-server/package.json b/packages/node-fetch-server/package.json index 3480d349573..4bbc1e44f13 100644 --- a/packages/node-fetch-server/package.json +++ b/packages/node-fetch-server/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/node-fetch-server", - "version": "0.6.0", + "version": "0.6.1", "description": "Build servers for Node.js using the web fetch API", "author": "Michael Jackson ", "repository": { From dce39daa977efa38043e4874fba0dd916f071c79 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 26 Feb 2025 11:21:25 -0800 Subject: [PATCH 648/730] Use pnpm 10.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 710ac98b49c..2323da39e74 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "remix-the-web", "private": true, - "packageManager": "pnpm@9.9.0", + "packageManager": "pnpm@10.3.0", "devDependencies": { "prettier": "^3.3.3", "typescript": "^5.7.2" From 1cc0f5f9d6fd0ea190cea29c076e586d36f21e0b Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 15 Mar 2025 20:40:29 -0700 Subject: [PATCH 649/730] Approve builds --- package.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 2323da39e74..a204e0f30e6 100644 --- a/package.json +++ b/package.json @@ -18,5 +18,12 @@ }, "workspaces": [ "packages/*" - ] + ], + "pnpm": { + "onlyBuiltDependencies": [ + "@swc/core", + "esbuild", + "workerd" + ] + } } From fd57ac19c9d744a8d02d9c4bbfcbdc7ee23fd577 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 20 May 2025 17:05:06 -0700 Subject: [PATCH 650/730] Build headers with esbuild --- packages/headers/.npmignore | 2 + packages/headers/README.md | 39 ++++- packages/headers/package.json | 53 +++--- packages/headers/tsconfig.build.json | 10 ++ packages/headers/tsup.config.ts | 9 - pnpm-lock.yaml | 244 ++++++++++++++++++++++++++- 6 files changed, 316 insertions(+), 41 deletions(-) create mode 100644 packages/headers/.npmignore create mode 100644 packages/headers/tsconfig.build.json delete mode 100644 packages/headers/tsup.config.ts diff --git a/packages/headers/.npmignore b/packages/headers/.npmignore new file mode 100644 index 00000000000..59c74efe800 --- /dev/null +++ b/packages/headers/.npmignore @@ -0,0 +1,2 @@ +# Ignore test files within the src directory +src/**/*.test.ts diff --git a/packages/headers/README.md b/packages/headers/README.md index ccb5ec44d6f..2bc25a97582 100644 --- a/packages/headers/README.md +++ b/packages/headers/README.md @@ -1,15 +1,18 @@ # headers -`headers` is a toolkit for working with HTTP headers in JavaScript. +Tired of manually parsing and stringifying HTTP header values in JavaScript? `headers` supercharges the standard `Headers` interface, providing a robust toolkit for effortless and type-safe header manipulation. -HTTP headers contain a wealth of information: +HTTP headers are packed with critical information—from content negotiation and caching directives to authentication tokens and file metadata. While the native `Headers` API provides a basic string-based interface, it leaves the complexities of parsing specific header formats (like `Accept`, `Content-Type`, or `Set-Cookie`) entirely up to you. -- Who is sending this request? -- What's in the payload and how is it encoded? -- What is the filename of this file upload? -- and much more! +`headers` solves this by offering: -The [built-in JavaScript `Headers` interface](https://developer.mozilla.org/en-US/docs/Web/API/Headers) accepts and gives you strings for everything, which you're probably used to parsing and stringifying manually as needed. This library aims to give you a more fluent interface for all of this information. Similar to how the DOM gives you programmatic access to HTML documents, `headers` gives you access to HTTP headers. +- **Type-Safe Accessors:** Interact with complex header values (e.g., media types, quality factors, cookie attributes) through strongly-typed properties and methods, eliminating guesswork and manual parsing. +- **Automatic Parsing & Stringification:** The library intelligently handles the parsing of raw header strings into structured objects and stringifies your structured data back into spec-compliant header values. +- **Fluent Interface:** Enjoy a more expressive and developer-friendly API for reading and writing header information. +- **Drop-in Enhancement:** As a subclass of the standard `Headers` object, it can be used anywhere a `Headers` object is expected, providing progressive enhancement to your existing code. +- **Individual Header Utilities:** For fine-grained control, use standalone utility classes for specific headers, perfect for scenarios outside of a full `Headers` object. + +Unlock a more powerful and elegant way to work with HTTP headers in your JavaScript and TypeScript projects! ## Installation @@ -46,6 +49,9 @@ headers.get('Accept'); // 'text/html,text/plain;q=0.9,text/*;q=0.8' // Accept-Encoding headers.acceptEncoding = 'gzip, deflate;q=0.8'; +headers.acceptEncoding.encodings; // [ 'gzip', 'deflate' ] +Object.fromEntries(headers.acceptEncoding.entries()); // { 'gzip': 1, 'deflate': 0.8 } + headers.acceptEncoding.accepts('gzip'); // true headers.acceptEncoding.accepts('br'); // false @@ -206,7 +212,7 @@ let headers = new Headers({ }); console.log(`${headers}`); -// Content-Type: text/html +// Content-Type: application/json // Accept-Language: en-US,en;q=0.9 ``` @@ -307,6 +313,23 @@ header.sMaxage; // 3600 // Alternative init style let header = new CacheControl({ public: true, maxAge: 3600 }); + +// Full set of supported properties +header.public; // true/false +header.private; // true/false +header.noCache; // true/false +header.noStore; // true/false +header.noTransform; // true/false +header.mustRevalidate; // true/false +header.proxyRevalidate; // true/false +header.maxAge; // number +header.sMaxage; // number +header.minFresh; // number +header.maxStale; // number +header.onlyIfCached; // true/false +header.immutable; // true/false +header.staleWhileRevalidate; // number +header.staleIfError; // number ``` ### Content-Disposition diff --git a/packages/headers/package.json b/packages/headers/package.json index bd982cbcc30..859ec285346 100644 --- a/packages/headers/package.json +++ b/packages/headers/package.json @@ -12,46 +12,57 @@ "homepage": "https://github.com/mjackson/remix-the-web/tree/main/packages/headers#readme", "files": [ "dist", + "src", "LICENSE", "README.md" ], "type": "module", + "main": "./dist/headers.cjs", + "module": "./dist/headers.js", "types": "./dist/headers.d.ts", - "main": "./dist/headers.js", "exports": { ".": { - "module-sync": { - "types": "./dist/headers.d.ts", - "default": "./dist/headers.js" - }, - "import": { - "types": "./dist/headers.d.ts", - "default": "./dist/headers.js" - }, - "require": { - "types": "./dist/headers.d.cts", - "default": "./dist/headers.cjs" - }, - "default": { - "types": "./dist/headers.d.ts", - "default": "./dist/headers.js" - } + "types": "./dist/headers.d.ts", + "import": "./dist/headers.js", + "require": "./dist/headers.cjs", + "default": "./dist/headers.js" }, "./package.json": "./package.json" }, "devDependencies": { "@types/node": "^20.14.10", - "tsup": "^8.3.5" + "esbuild": "^0.20.0" }, "scripts": { - "build": "tsup", + "clean": "rm -rf dist", + "build:types": "tsc --project tsconfig.build.json", + "build:esm": "esbuild src/headers.ts --bundle --outfile=dist/headers.js --format=esm --platform=neutral --minify --sourcemap", + "build:cjs": "esbuild src/headers.ts --bundle --outfile=dist/headers.cjs --format=cjs --platform=node --minify --sourcemap", + "build": "pnpm run clean && pnpm run build:types && pnpm run build:esm && pnpm run build:cjs", "test": "node --experimental-strip-types --disable-warning=ExperimentalWarning --test ./src/**/*.test.ts", - "prepare": "pnpm run build" + "prepublishOnly": "pnpm run build" }, "keywords": [ "fetch", "http", "header", - "headers" + "headers", + "http-headers", + "request-headers", + "response-headers", + "content-negotiation", + "cookies", + "set-cookie", + "cache-control", + "content-type", + "accept", + "accept-encoding", + "accept-language", + "content-disposition", + "if-none-match", + "etag", + "user-agent", + "host", + "last-modified" ] } diff --git a/packages/headers/tsconfig.build.json b/packages/headers/tsconfig.build.json new file mode 100644 index 00000000000..ad34533987f --- /dev/null +++ b/packages/headers/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "declarationMap": true, + "outDir": "./dist" + }, + "include": ["src"] +} \ No newline at end of file diff --git a/packages/headers/tsup.config.ts b/packages/headers/tsup.config.ts deleted file mode 100644 index d2992de6d9e..00000000000 --- a/packages/headers/tsup.config.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { defineConfig } from 'tsup'; - -export default defineConfig({ - clean: true, - dts: true, - entry: ['src/headers.ts'], - format: ['cjs', 'esm'], - platform: 'neutral', -}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c1a5e2e9011..d7c50722e07 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -84,9 +84,9 @@ importers: '@types/node': specifier: ^20.14.10 version: 20.16.1 - tsup: - specifier: ^8.3.5 - version: 8.3.5(@swc/core@1.5.29(@swc/helpers@0.5.12))(typescript@5.7.2) + esbuild: + specifier: ^0.20.0 + version: 0.20.2 packages/lazy-file: dependencies: @@ -346,6 +346,12 @@ packages: peerDependencies: esbuild: '*' + '@esbuild/aix-ppc64@0.20.2': + resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.24.0': resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} engines: {node: '>=18'} @@ -358,6 +364,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.20.2': + resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.24.0': resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} engines: {node: '>=18'} @@ -370,6 +382,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.20.2': + resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.24.0': resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} engines: {node: '>=18'} @@ -382,6 +400,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.20.2': + resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.24.0': resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} engines: {node: '>=18'} @@ -394,6 +418,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.20.2': + resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.24.0': resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} engines: {node: '>=18'} @@ -406,6 +436,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.20.2': + resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.24.0': resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} engines: {node: '>=18'} @@ -418,6 +454,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.20.2': + resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.24.0': resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} engines: {node: '>=18'} @@ -430,6 +472,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.20.2': + resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.24.0': resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} engines: {node: '>=18'} @@ -442,6 +490,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.20.2': + resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.24.0': resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} engines: {node: '>=18'} @@ -454,6 +508,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.20.2': + resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.24.0': resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} engines: {node: '>=18'} @@ -466,6 +526,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.20.2': + resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.24.0': resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} engines: {node: '>=18'} @@ -478,6 +544,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.20.2': + resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.24.0': resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} engines: {node: '>=18'} @@ -490,6 +562,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.20.2': + resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.24.0': resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} engines: {node: '>=18'} @@ -502,6 +580,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.20.2': + resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.24.0': resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} engines: {node: '>=18'} @@ -514,6 +598,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.20.2': + resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.24.0': resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} engines: {node: '>=18'} @@ -526,6 +616,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.20.2': + resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.24.0': resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} engines: {node: '>=18'} @@ -538,6 +634,12 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.20.2': + resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.24.0': resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} engines: {node: '>=18'} @@ -550,6 +652,12 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.20.2': + resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.24.0': resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} engines: {node: '>=18'} @@ -568,6 +676,12 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.20.2': + resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.24.0': resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} engines: {node: '>=18'} @@ -580,6 +694,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.20.2': + resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.24.0': resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} engines: {node: '>=18'} @@ -592,6 +712,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.20.2': + resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.24.0': resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} engines: {node: '>=18'} @@ -604,6 +730,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.20.2': + resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.24.0': resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} engines: {node: '>=18'} @@ -616,6 +748,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.20.2': + resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.24.0': resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} engines: {node: '>=18'} @@ -1162,6 +1300,11 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.20.2: + resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.24.0: resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} engines: {node: '>=18'} @@ -1940,108 +2083,162 @@ snapshots: escape-string-regexp: 4.0.0 rollup-plugin-node-polyfills: 0.2.1 + '@esbuild/aix-ppc64@0.20.2': + optional: true + '@esbuild/aix-ppc64@0.24.0': optional: true '@esbuild/android-arm64@0.17.19': optional: true + '@esbuild/android-arm64@0.20.2': + optional: true + '@esbuild/android-arm64@0.24.0': optional: true '@esbuild/android-arm@0.17.19': optional: true + '@esbuild/android-arm@0.20.2': + optional: true + '@esbuild/android-arm@0.24.0': optional: true '@esbuild/android-x64@0.17.19': optional: true + '@esbuild/android-x64@0.20.2': + optional: true + '@esbuild/android-x64@0.24.0': optional: true '@esbuild/darwin-arm64@0.17.19': optional: true + '@esbuild/darwin-arm64@0.20.2': + optional: true + '@esbuild/darwin-arm64@0.24.0': optional: true '@esbuild/darwin-x64@0.17.19': optional: true + '@esbuild/darwin-x64@0.20.2': + optional: true + '@esbuild/darwin-x64@0.24.0': optional: true '@esbuild/freebsd-arm64@0.17.19': optional: true + '@esbuild/freebsd-arm64@0.20.2': + optional: true + '@esbuild/freebsd-arm64@0.24.0': optional: true '@esbuild/freebsd-x64@0.17.19': optional: true + '@esbuild/freebsd-x64@0.20.2': + optional: true + '@esbuild/freebsd-x64@0.24.0': optional: true '@esbuild/linux-arm64@0.17.19': optional: true + '@esbuild/linux-arm64@0.20.2': + optional: true + '@esbuild/linux-arm64@0.24.0': optional: true '@esbuild/linux-arm@0.17.19': optional: true + '@esbuild/linux-arm@0.20.2': + optional: true + '@esbuild/linux-arm@0.24.0': optional: true '@esbuild/linux-ia32@0.17.19': optional: true + '@esbuild/linux-ia32@0.20.2': + optional: true + '@esbuild/linux-ia32@0.24.0': optional: true '@esbuild/linux-loong64@0.17.19': optional: true + '@esbuild/linux-loong64@0.20.2': + optional: true + '@esbuild/linux-loong64@0.24.0': optional: true '@esbuild/linux-mips64el@0.17.19': optional: true + '@esbuild/linux-mips64el@0.20.2': + optional: true + '@esbuild/linux-mips64el@0.24.0': optional: true '@esbuild/linux-ppc64@0.17.19': optional: true + '@esbuild/linux-ppc64@0.20.2': + optional: true + '@esbuild/linux-ppc64@0.24.0': optional: true '@esbuild/linux-riscv64@0.17.19': optional: true + '@esbuild/linux-riscv64@0.20.2': + optional: true + '@esbuild/linux-riscv64@0.24.0': optional: true '@esbuild/linux-s390x@0.17.19': optional: true + '@esbuild/linux-s390x@0.20.2': + optional: true + '@esbuild/linux-s390x@0.24.0': optional: true '@esbuild/linux-x64@0.17.19': optional: true + '@esbuild/linux-x64@0.20.2': + optional: true + '@esbuild/linux-x64@0.24.0': optional: true '@esbuild/netbsd-x64@0.17.19': optional: true + '@esbuild/netbsd-x64@0.20.2': + optional: true + '@esbuild/netbsd-x64@0.24.0': optional: true @@ -2051,30 +2248,45 @@ snapshots: '@esbuild/openbsd-x64@0.17.19': optional: true + '@esbuild/openbsd-x64@0.20.2': + optional: true + '@esbuild/openbsd-x64@0.24.0': optional: true '@esbuild/sunos-x64@0.17.19': optional: true + '@esbuild/sunos-x64@0.20.2': + optional: true + '@esbuild/sunos-x64@0.24.0': optional: true '@esbuild/win32-arm64@0.17.19': optional: true + '@esbuild/win32-arm64@0.20.2': + optional: true + '@esbuild/win32-arm64@0.24.0': optional: true '@esbuild/win32-ia32@0.17.19': optional: true + '@esbuild/win32-ia32@0.20.2': + optional: true + '@esbuild/win32-ia32@0.24.0': optional: true '@esbuild/win32-x64@0.17.19': optional: true + '@esbuild/win32-x64@0.20.2': + optional: true + '@esbuild/win32-x64@0.24.0': optional: true @@ -2589,6 +2801,32 @@ snapshots: '@esbuild/win32-ia32': 0.17.19 '@esbuild/win32-x64': 0.17.19 + esbuild@0.20.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.20.2 + '@esbuild/android-arm': 0.20.2 + '@esbuild/android-arm64': 0.20.2 + '@esbuild/android-x64': 0.20.2 + '@esbuild/darwin-arm64': 0.20.2 + '@esbuild/darwin-x64': 0.20.2 + '@esbuild/freebsd-arm64': 0.20.2 + '@esbuild/freebsd-x64': 0.20.2 + '@esbuild/linux-arm': 0.20.2 + '@esbuild/linux-arm64': 0.20.2 + '@esbuild/linux-ia32': 0.20.2 + '@esbuild/linux-loong64': 0.20.2 + '@esbuild/linux-mips64el': 0.20.2 + '@esbuild/linux-ppc64': 0.20.2 + '@esbuild/linux-riscv64': 0.20.2 + '@esbuild/linux-s390x': 0.20.2 + '@esbuild/linux-x64': 0.20.2 + '@esbuild/netbsd-x64': 0.20.2 + '@esbuild/openbsd-x64': 0.20.2 + '@esbuild/sunos-x64': 0.20.2 + '@esbuild/win32-arm64': 0.20.2 + '@esbuild/win32-ia32': 0.20.2 + '@esbuild/win32-x64': 0.20.2 + esbuild@0.24.0: optionalDependencies: '@esbuild/aix-ppc64': 0.24.0 From f8da620bb1fecd4a99df69c4444e4b96c237d298 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Tue, 20 May 2025 17:13:53 -0700 Subject: [PATCH 651/730] Update README and contributing guidelines --- CONTRIBUTING.md | 18 ++++++++------- README.md | 59 ++++++++++++++++++++++++++++++++++++------------- 2 files changed, 54 insertions(+), 23 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 41e56ea12f7..e57d3cb4706 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,20 +1,22 @@ -Welcome to `remix-the-web`! +Welcome to `remix-the-web`! We're excited to have you contribute. + +This guide will help you get started. ## Setting Up Your Environment -First off, [install `pnpm`](https://pnpm.io/installation) somewhere globally on your machine. It's the tool we use to manage dependencies and run tasks in this workspace. +To get started, you'll need `pnpm`. If you don't have it yet, you can [install `pnpm` here](https://pnpm.io/installation). -If you're using [VS Code](https://code.visualstudio.com/) you should also install [the `node:test runner` extension](https://marketplace.visualstudio.com/items?itemName=connor4312.nodejs-testing) which provides an integrated experience when running the tests. +If you're using [VS Code](https://code.visualstudio.com/), we recommend installing the [`node:test runner` extension](https://marketplace.visualstudio.com/items?itemName=connor4312.nodejs-testing) for a smooth testing experience. -When you've done that, run `pnpm install` to install all dependencies and run a build. You can also run `pnpm test` to run all tests in the repo. +Once that's set up, run `pnpm install` to get all the project dependencies. You can then run `pnpm build` to build the project and `pnpm test` to run all tests. ## Making Changes -You can find all packages in [the `packages` directory](https://github.com/mjackson/remix-the-web/tree/main/packages). Inside each package you'll find a few common files including: +All our packages live in the [`packages` directory](https://github.com/mjackson/remix-the-web/tree/main/packages). At a minimum, each package typically includes: -- `CHANGELOG.md` -- `package.json` -- `README.md` +- `CHANGELOG.md`: A log of what's changed. +- `package.json`: Package metadata and dependencies. +- `README.md`: Information about the package. When you make changes to a package, please make sure you add a few relevant tests and run the whole test suite to make sure everything still works. Then, add a human-friendly description of your change in the changelog and [make a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). We will take a look at it as soon as we can. diff --git a/README.md b/README.md index 81fd2c32f9c..189cb678cf6 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,70 @@ -This is a collection of packages for use with [Remix](https://remix.run), or any web framework you choose. +This collection of packages empowers you to build modern web applications with maximum interoperability and portability, leveraging the power of web standards. Whether you're using [Remix](https://remix.run) or another framework, these tools are designed to seamlessly integrate into your workflow. -It is laying the foundation for the next major release of Remix. +This repository is laying the groundwork for the next major evolution of Remix. ## Philosophy -Each package in this repository has a [single responsibility](https://en.wikipedia.org/wiki/Single-responsibility_principle). +Our core philosophy is simple: **build on web standards, embrace single responsibility.** -To maximize interoperability between packages, we build on web standards. Where standards are missing or incomplete, we augment them in unobtrusive ways to minimize the chance of incompatibility. +Each package in this repository: +- Adheres to the [single-responsibility principle](https://en.wikipedia.org/wiki/Single-responsibility_principle). +- Prioritizes web standards to ensure maximum interoperability and portability across JavaScript runtimes. +- Augments standards unobtrusively where they are missing or incomplete, minimizing incompatibility risks. -A few examples of web APIs that we use on the server include: +This approach means the JavaScript you write is **portable by default**. These packages work seamlessly across [Node.js](https://nodejs.org/), [Bun](https://bun.sh/), [Deno](https://deno.com/), [Cloudflare Workers](https://workers.cloudflare.com/), and other environments. + +We leverage server-side web APIs like: - [The Web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) instead of Node.js streams - [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) instead of Node.js `Buffer`s - [The Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) instead of the Node.js crypto library - [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) and [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) instead of some bespoke runtime-specific API -You get the idea. The benefit of writing JavaScript like this is that it's portable between various runtimes. Unless explicitly noted, all packages in this repository work on any JavaScript runtime you might be using: [Node.js](https://nodejs.org/), [Bun](https://bun.sh/), [Deno](https://deno.com/), [Cloudflare Workers](https://workers.cloudflare.com/), etc. +The benefit? Code that's not just reusable, but **future-proof**. The goal is that these packages should be useful for anyone who is building for the web. If you're using [Remix](https://remix.run), we've designed it from the start to work with web standards. If you're using some other framework, you should easily be able to integrate these tools into your workflow as well without going full-blown Remix. If you're building your own framework, we hope you'll be able to build on this foundation as well. ## Packages -We currently publish the following packages: +Discover our growing suite of tools: + +- [fetch-proxy](packages/fetch-proxy): Seamlessly construct HTTP proxies with the familiar `fetch()` API – ideal for API gateways or abstracting microservices. +- [file-storage](packages/file-storage): Robust key/value storage tailored for JavaScript `File` objects, simplifying file management. +- [form-data-parser](packages/form-data-parser): An enhanced `request.formData()` wrapper enabling efficient, streaming file uploads. +- [headers](packages/headers): A comprehensive toolkit for effortlessly managing HTTP headers in your JavaScript applications. +- [lazy-file](packages/lazy-file): Optimize performance with lazy-loaded, streaming `Blob`s and `File`s for JavaScript. +- [multipart-parser](packages/multipart-parser): High-performance, streaming parser for multipart messages, perfect for handling complex form data. +- [node-fetch-server](packages/node-fetch-server): Build Node.js HTTP servers using the web-standard `fetch()` API, promoting code consistency. +- [tar-parser](packages/tar-parser): A fast, streaming parser for tar archives, designed for efficient data extraction. + +## Why Choose These Packages? -- [fetch-proxy](packages/fetch-proxy): Easily build HTTP proxies using the `fetch()` API -- [file-storage](packages/file-storage): Key/value storage for JavaScript `File` objects -- [form-data-parser](packages/form-data-parser): A `request.formData()` wrapper with streaming file upload handling -- [headers](packages/headers): A toolkit for working with HTTP headers in JavaScript -- [lazy-file](packages/lazy-file): Lazy, streaming `Blob`s and `File`s for JavaScript -- [multipart-parser](packages/multipart-parser): Fast, streaming parser for multipart messages -- [node-fetch-server](packages/node-fetch-server): Build HTTP servers for Node.js using the web `fetch()` API -- [tar-parser](packages/tar-parser): Fast, streaming parser for tar archives +- **Web Standard-Focused:** Write code that's portable across Node.js, Deno, Bun, Cloudflare Workers, and more. +- **Single Responsibility:** Each package is focused and does one thing well, making them easy to understand and integrate. +- **Interoperable:** Designed to work together, and with your existing tools, thanks to their adherence to web standards. +- **Future-Proof:** By building on web standards, your codebase remains adaptable and resilient to ecosystem changes. +- **Remix Ready (and Beyond!):** While born from the needs of Remix, these packages are valuable for any web developer or framework author seeking robust, standard-compliant tools. ## Using with Remix v2 If you're trying to use these libraries with Remix v2, you'll need to [enable "Single Fetch"](https://remix.run/docs/en/main/guides/single-fetch#enabling-single-fetch) first. This tells Remix to use Node's built-in fetch primitives (`Request`, `Response`, `Headers`, etc.) instead of a broken polyfill we shipped in earlier versions of Remix. +## Quick Start + +Each package is available on npm and can be installed using: + +```bash +npm install +``` + +Then, import and use as needed in your project. Refer to individual package `README` files for specific usage instructions. + +All packages are published in both modern ESM and legacy CJS formats for maximum compatibility with both existing and new projects. + +## Contributing + +We welcome contributions! If you'd like to contribute, please feel free to open an issue or submit a pull request. See [CONTRIBUTING](https://github.com/mjackson/remix-the-web/blob/main/CONTRIBUTING.md) for more information. + ## License See [LICENSE](https://github.com/mjackson/remix-the-web/blob/main/LICENSE) From f6d0011c3db4e0b3e0c163a8c7d2c07e594446b0 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Wed, 21 May 2025 15:12:32 -0400 Subject: [PATCH 652/730] Add v2 maintenance mode warning (#10630) --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 49057fff0dd..f9cb9c88258 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,12 @@ # Welcome to Remix! +> [!IMPORTANT] +> With the release of [React Router v7](https://remix.run/blog/react-router-v7) we are sun-setting continued development/maintenance on Remix v2. If you have not already [upgraded to React Router v7](https://reactrouter.com/upgrading/remix), we recommend you do so. We've tried to make the upgrade process as smooth as possible with our [Future Flags](https://remix.run/docs/en/main/start/future-flags). +> +> We plan to continue to address bugs that pose security concerns or prevent upgrading to React Router v7. If you have a bug in one of those categories, please open an issue in this repository and prefix the title with `(v2):`. +> +> For all other issues, ongoing maintenance will be happening in React Router v7, so please o[pen issues (bugs) and/or discussions (feature requests) [in that repo](https://github.com/remix-run/react-router/issues/new?template=bug_report.yml). + We are happy you're here! [Remix](https://remix.run) is a full stack web framework that lets you focus on the user interface and work back through web fundamentals to deliver a fast, slick, and resilient user experience that deploys to any Node.js server and even non-Node.js environments at the edge like Cloudflare Workers. From 949dd8dbd8ac3ee00441063cdd7870ec7dc1ffce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20B=C5=82aszczyk?= Date: Fri, 23 May 2025 00:07:35 +0200 Subject: [PATCH 653/730] docs(README): fix typo (#10631) --- README.md | 2 +- contributors.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f9cb9c88258..cf414220bf7 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ > > We plan to continue to address bugs that pose security concerns or prevent upgrading to React Router v7. If you have a bug in one of those categories, please open an issue in this repository and prefix the title with `(v2):`. > -> For all other issues, ongoing maintenance will be happening in React Router v7, so please o[pen issues (bugs) and/or discussions (feature requests) [in that repo](https://github.com/remix-run/react-router/issues/new?template=bug_report.yml). +> For all other issues, ongoing maintenance will be happening in React Router v7, so please open issues (bugs) and/or discussions (feature requests) [in that repo](https://github.com/remix-run/react-router/issues/new?template=bug_report.yml). We are happy you're here! diff --git a/contributors.yml b/contributors.yml index b06d3bbbb05..4a62d393672 100644 --- a/contributors.yml +++ b/contributors.yml @@ -546,6 +546,7 @@ - pacexy - pandaiolo - panteliselef +- pawelblaszczyk5 - pcattori - penspinner - penx From 2f1e040eb80cc9b096ab44478f9752b190ddca9c Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Mon, 26 May 2025 10:47:40 -0400 Subject: [PATCH 654/730] Update script to be able to close v2 prs as well --- .github/workflows/close-v2-issues.yml | 13 ++++++-- scripts/close-v2-issues.mjs | 46 +++++++++++++++++++++------ scripts/close-v2-prs-comment.md | 17 ++++++++++ 3 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 scripts/close-v2-prs-comment.md diff --git a/.github/workflows/close-v2-issues.yml b/.github/workflows/close-v2-issues.yml index 4f92f3a635f..6dd1c2a3360 100644 --- a/.github/workflows/close-v2-issues.yml +++ b/.github/workflows/close-v2-issues.yml @@ -1,8 +1,15 @@ -name: 🚪 Close v2 Issues +name: 🚪 Close v2 Issues/PRs on: workflow_dispatch: inputs: + type: + type: choice + description: Type + options: + - issues + - prs + required: true prior_to_date: required: true @@ -10,7 +17,7 @@ concurrency: ${{ github.workflow }}-${{ github.ref }} jobs: experimental: - name: 🚪 Close v2 Issues + name: 🚪 Close v2 Issues/PRs if: github.repository == 'remix-run/remix' runs-on: ubuntu-latest env: @@ -33,4 +40,4 @@ jobs: run: pnpm install --frozen-lockfile - name: 🚪 Close Issues - run: node ./scripts/close-v2-issues.mjs --date ${{ github.event.inputs.prior_to_date }} + run: node ./scripts/close-v2-issues.mjs --type ${{ github.event.inputs.type }} --date ${{ github.event.inputs.prior_to_date }} diff --git a/scripts/close-v2-issues.mjs b/scripts/close-v2-issues.mjs index b87d19cb1c9..651c16af575 100644 --- a/scripts/close-v2-issues.mjs +++ b/scripts/close-v2-issues.mjs @@ -12,11 +12,21 @@ const { values: args } = parseArgs({ short: "d", default: new Date(oneYearAgo).toISOString().substring(0, 10), }, + type: { + type: "string", + short: "t", + default: "issues", // issues | prs + }, }, strict: true, }); -if (!args.date || !/^\d{4}-\d{2}-\d{2}$/.test(args.date)) { +console.log(args); + +if (!args.type || !["issues", "prs"].includes(args.type)) { + console.error("Missing or invalid date - expected YYYY-MM-DD."); + process.exit(1); +} else if (!args.date || !/^\d{4}-\d{2}-\d{2}$/.test(args.date)) { console.error("Missing or invalid date - expected YYYY-MM-DD."); process.exit(1); } else { @@ -27,33 +37,51 @@ async function run() { /** @type {(ms: number) => Promise} */ let sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + let isPullRequests = args.type === "prs"; + /** @type {(q: string) => string} */ - let getIssuesCmd = (q) => `gh issue list --search "${q}" --json number`; + let getQueryCmd = (q) => + isPullRequests + ? `gh pr list --search "${q}" --json number` + : `gh issue list --search "${q}" --json number`; /** @type {(n: number) => string} */ let getCommentCmd = (n) => - `gh issue comment ${n} -F ./scripts/close-v2-issues-comment.md`; + isPullRequests + ? `gh pr comment ${n} -F ./scripts/close-v2-prs-comment.md` + : `gh issue comment ${n} -F ./scripts/close-v2-issues-comment.md`; /** @type {(n: number) => string} */ - let getCloseCmd = (n) => `gh issue close ${n} -r "not planned"`; + let getCloseCmd = (n) => + isPullRequests + ? `gh pr close ${n}` + : `gh issue close ${n} -r "not planned"`; - let issueCmd = getIssuesCmd(`is:issue state:open updated:<${args.date}`); + let query = isPullRequests + ? `is:pr is:open updated:<${args.date}` + : `is:issue state:open updated:<${args.date}`; + let issueCmd = getQueryCmd(query); console.log(`Executing command: ${issueCmd}`); + let result = execSync(issueCmd).toString(); console.log(`Result: ${result}`); let issues = JSON.parse(result).map((i) => i.number); if (issues.length > 50) { - console.log("❌ Refusing to close more than 50 issues at once, exiting."); + console.log( + "❌ Refusing to close more than 50 issues/PRs at once, exiting." + ); process.exit(1); } - console.log(`Parsed ${issues.length} issues`); + let label = isPullRequests ? "PR" : "issue"; + + console.log(`Parsed ${issues.length} ${label}s`); for (let issue of issues) { - console.log(`--- Processing issue #${issue} ---`); + console.log(`--- Processing ${label} #${issue} ---`); let commentResult = runCmdIfTokenExists(getCommentCmd(issue)); - console.log(`Commented on issue #${issue}: ${commentResult}`); + console.log(`Commented on ${label} #${issue}: ${commentResult}`); await sleep(250); runCmdIfTokenExists(getCloseCmd(issue)); diff --git a/scripts/close-v2-prs-comment.md b/scripts/close-v2-prs-comment.md new file mode 100644 index 00000000000..6d2c4458996 --- /dev/null +++ b/scripts/close-v2-prs-comment.md @@ -0,0 +1,17 @@ +Thank you for opening this pull request, and our apologies we haven't gotten around to it yet! + +With the release of [React Router v7](https://remix.run/blog/react-router-v7) we are sun-setting continued development/maintenance on Remix v2. If you have not already [upgraded to React Router v7](https://reactrouter.com/upgrading/remix), we recommend you do so. We've tried to make the upgrade process as smooth as possible with our [Future Flags](https://remix.run/docs/en/main/start/future-flags). We are now in the process of cleaning up outdated issues and pull requests to improve the overall hygiene of our repositories. + +We plan to continue to address 2 types of issues in Remix v2: + +- Bugs that pose security concerns +- Bugs that prevent upgrading to React Router v7 + +If you believe this pull request meets one of those criteria, please respond or create a new pull request so it pops up on our radar (since github notifications may get lost in the noise 😕). + +For all other issues/changes, ongoing maintenance will be happening in React Router v7, so: + +- If this is a bug fix, please reopen against [React Router v7](https://github.com/remix-run/react-router) +- If this is a new feature, please open a new [Proposal Discussion](https://github.com/remix-run/react-router/discussions/new?category=proposals) in React Router, and if it gets enough community support it can be considered for implementation + +If you have any questions you can always reach out on [Discord](https://rmx.as/discord). Thanks again for providing feedback and helping us make our framework even better! From 2ac7a09000240a993f1993ab1b2d07e63831adcd Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Fri, 30 May 2025 10:45:36 -0400 Subject: [PATCH 655/730] Remove v2 code --- .changeset/README.md | 8 - .changeset/config.json | 36 - .eslintignore | 18 - .eslintrc.js | 64 - .github/ISSUE_TEMPLATE/bug_report.yml | 66 - .github/ISSUE_TEMPLATE/config.yml | 21 - .github/PULL_REQUEST_TEMPLATE.md | 42 - .github/dependabot.yml | 6 - .github/workflows/close-v2-issues.yml | 43 - .github/workflows/deduplicate-lock-file.yml | 49 - .github/workflows/deployments.yml | 222 - .github/workflows/format.yml | 65 - .github/workflows/lint.yml | 49 - .github/workflows/merged-pr.yml | 29 - .github/workflows/nightly.yml | 122 - .github/workflows/no-response.yml | 34 - .github/workflows/release-comments.yml | 22 - .github/workflows/release-experimental.yml | 59 - .github/workflows/release.yml | 123 - .github/workflows/shared-build.yml | 36 - .github/workflows/shared-test-integration.yml | 62 - .github/workflows/shared-test-unit.yml | 55 - .github/workflows/stacks.yml | 253 - .github/workflows/test-full.yml | 67 - .github/workflows/test-pr-ubuntu.yml | 39 - .github/workflows/test-pr-windows-macos.yml | 50 - .github/workflows/website.yml | 24 - .gitignore | 37 - .nvmrc | 2 +- .prettierignore | 2 - .vscode/README.md | 5 - .vscode/deno_resolve_npm_imports.json | 6 - .vscode/extensions.json | 7 - .vscode/settings.json | 4 +- CHANGELOG.md | 2440 --- CLA.md | 23 - CODE_OF_CONDUCT.md | 125 - CONTRIBUTING.md | 3 - DEVELOPMENT.md | 149 - LICENSE.md | 22 - README.md | 32 - babel.config.js | 27 - contributors.yml | 744 - ...nage-npm-dependencies-for-deno-projects.md | 113 - decisions/0002-do-not-clone-request.md | 19 - ...ata-from-loader-and-action-via-generics.md | 230 - decisions/0004-streaming-apis.md | 193 - decisions/0005-remixing-react-router.md | 309 - decisions/0006-linear-workflow.md | 86 - decisions/0007-remix-on-react-router-6-4-0.md | 166 - ...only-support-js-conversion-for-app-code.md | 101 - ...not-rely-on-treeshaking-for-correctness.md | 98 - ...tting-up-client-and-server-code-in-vite.md | 102 - decisions/template.md | 11 - docs/components/await.md | 94 - docs/components/form.md | 161 - docs/components/index.md | 4 - docs/components/link.md | 234 - docs/components/links.md | 27 - docs/components/live-reload.md | 37 - docs/components/meta.md | 27 - docs/components/nav-link.md | 202 - docs/components/outlet.md | 35 - docs/components/prefetch-page-links.md | 16 - docs/components/scripts.md | 39 - docs/components/scroll-restoration.md | 118 - docs/discussion/component-data.md | 6 - docs/discussion/concurrency.md | 130 - docs/discussion/cookies-and-sessions.md | 4 - docs/discussion/data-flow.md | 181 - docs/discussion/error-handling.md | 16 - docs/discussion/form-validation.md | 6 - docs/discussion/form-vs-fetcher.md | 276 - docs/discussion/formdata.md | 6 - docs/discussion/hot-module-replacement.md | 186 - docs/discussion/html-forms.md | 6 - docs/discussion/index.md | 4 - docs/discussion/introduction.md | 234 - docs/discussion/multiple-forms.md | 6 - docs/discussion/nested-routes.md | 6 - docs/discussion/pending-ui.md | 258 - docs/discussion/progressive-enhancement.md | 143 - docs/discussion/react-router.md | 52 - docs/discussion/resubmissions.md | 72 - docs/discussion/routes.md | 160 - docs/discussion/runtimes.md | 118 - docs/discussion/server-vs-client.md | 189 - docs/discussion/state-management.md | 522 - docs/discussion/testing.md | 6 - docs/file-conventions/-client.md | 32 - docs/file-conventions/-server.md | 31 - docs/file-conventions/asset-imports.md | 36 - docs/file-conventions/entry.client.md | 31 - docs/file-conventions/entry.server.md | 69 - docs/file-conventions/index.md | 4 - docs/file-conventions/remix-config.md | 281 - docs/file-conventions/root.md | 228 - docs/file-conventions/routes.md | 419 - docs/file-conventions/vite-config.md | 145 - docs/guides/accessibility.md | 34 - docs/guides/api-development-strategy.md | 68 - docs/guides/api-routes.md | 123 - docs/guides/authentication.md | 4 - docs/guides/bff.md | 50 - docs/guides/breadcrumbs.md | 90 - docs/guides/browser-support.md | 27 - docs/guides/cache-control.md | 74 - docs/guides/client-data.md | 239 - docs/guides/concurrent-submissions.md | 4 - docs/guides/constraints.md | 403 - docs/guides/contributing.md | 258 - docs/guides/css-files.md | 172 - docs/guides/data-loading.md | 769 - docs/guides/data-writes.md | 532 - docs/guides/debugging.md | 6 - docs/guides/dependency-optimization.md | 67 - docs/guides/deployment.md | 24 - docs/guides/disabling-javascript.md | 86 - docs/guides/envvars.md | 169 - docs/guides/errors.md | 119 - docs/guides/faq.md | 242 - docs/guides/file-uploads.md | 127 - docs/guides/form-validation.md | 121 - docs/guides/gotchas.md | 209 - docs/guides/images.md | 4 - docs/guides/index-query-param.md | 58 - docs/guides/index.md | 4 - docs/guides/lazy-route-discovery.md | 63 - docs/guides/local-tls.md | 121 - docs/guides/manual-mode.md | 313 - docs/guides/mdx.md | 215 - docs/guides/meta.md | 4 - docs/guides/migrating-react-router-app.md | 731 - docs/guides/not-found.md | 77 - docs/guides/performance.md | 72 - docs/guides/presets.md | 117 - docs/guides/progressive-enhancement.md | 6 - docs/guides/resource-routes.md | 164 - docs/guides/server-bundles.md | 72 - docs/guides/single-fetch.md | 518 - docs/guides/spa-mode.md | 304 - docs/guides/streaming.md | 212 - docs/guides/templates.md | 176 - docs/guides/typescript.md | 87 - docs/guides/vite.md | 1156 -- docs/hooks/index.md | 4 - docs/hooks/use-action-data.md | 52 - docs/hooks/use-async-error.md | 39 - docs/hooks/use-async-value.md | 36 - docs/hooks/use-before-unload.md | 40 - docs/hooks/use-blocker.md | 82 - docs/hooks/use-fetcher.md | 185 - docs/hooks/use-fetchers.md | 43 - docs/hooks/use-form-action.md | 40 - docs/hooks/use-href.md | 40 - docs/hooks/use-loader-data.md | 38 - docs/hooks/use-location.md | 41 - docs/hooks/use-matches.md | 33 - docs/hooks/use-navigate.md | 98 - docs/hooks/use-navigation-type.md | 32 - docs/hooks/use-navigation.md | 83 - docs/hooks/use-outlet-context.md | 23 - docs/hooks/use-outlet.md | 13 - docs/hooks/use-params.md | 20 - docs/hooks/use-prompt.md | 49 - docs/hooks/use-resolved-path.md | 51 - docs/hooks/use-revalidator.md | 65 - docs/hooks/use-route-error.md | 30 - docs/hooks/use-route-loader-data.md | 24 - docs/hooks/use-search-params.md | 63 - docs/hooks/use-submit.md | 116 - docs/hooks/use-view-transition-state.md | 33 - docs/index.md | 58 - docs/other-api/adapter.md | 158 - docs/other-api/create-remix.md | 92 - docs/other-api/dev.md | 373 - docs/other-api/index.md | 4 - docs/other-api/node.md | 30 - docs/other-api/serve.md | 98 - docs/other-api/testing.md | 80 - docs/prettier.config.js | 5 - docs/route/action.md | 71 - docs/route/client-action.md | 53 - docs/route/client-loader.md | 96 - docs/route/component.md | 18 - docs/route/error-boundary.md | 54 - docs/route/handle.md | 23 - docs/route/headers.md | 136 - docs/route/hydrate-fallback.md | 79 - docs/route/index.md | 4 - docs/route/links.md | 102 - docs/route/loader.md | 323 - docs/route/meta.md | 265 - docs/route/should-revalidate.md | 253 - docs/start/changelog.md | 9 - docs/start/community.md | 45 - docs/start/future-flags.md | 749 - docs/start/index.md | 4 - docs/start/quickstart.md | 290 - docs/start/tutorial.md | 1645 -- docs/start/v2.md | 1136 -- docs/styling/bundling.md | 54 - docs/styling/css-imports.md | 37 - docs/styling/css-in-js.md | 15 - docs/styling/css-modules.md | 42 - docs/styling/css.md | 336 - docs/styling/index.md | 4 - docs/styling/postcss.md | 110 - docs/styling/tailwind.md | 90 - docs/styling/vanilla-extract.md | 53 - docs/tutorials/blog.md | 1058 -- docs/tutorials/index.md | 4 - docs/tutorials/jokes.md | 7894 -------- docs/utils/cookies.md | 263 - docs/utils/create-remix-stub.md | 86 - docs/utils/data.md | 40 - docs/utils/defer.md | 48 - docs/utils/index.md | 4 - docs/utils/is-route-error-response.md | 10 - docs/utils/json.md | 40 - docs/utils/parse-multipart-form-data.md | 66 - docs/utils/redirect.md | 69 - docs/utils/redirectDocument.md | 42 - docs/utils/replace.md | 27 - docs/utils/sessions.md | 508 - .../unstable-create-file-upload-handler.md | 48 - .../unstable-create-memory-upload-handler.md | 29 - examples/README.md | 1 - integration/CHANGELOG.md | 15 - integration/abort-signal-test.ts | 66 - integration/action-test.ts | 432 - integration/assets/toupload.txt | 1 - integration/assets/touploadtoobig.txt | 1 - integration/blocking-test.ts | 120 - integration/browser-entry-test.ts | 88 - integration/bug-report-test.ts | 121 - integration/catch-boundary-data-test.ts | 472 - integration/catch-boundary-test.ts | 734 - integration/cf-compiler-test.ts | 189 - integration/client-data-test.ts | 2872 --- integration/compiler-mjs-cjs-output-test.ts | 35 - integration/compiler-test.ts | 348 - integration/css-modules-test.ts | 798 - integration/css-side-effect-imports-test.ts | 351 - integration/custom-entry-server-test.ts | 60 - integration/defer-loader-test.ts | 199 - integration/defer-test.ts | 2652 --- integration/deno-compiler-test.ts | 234 - .../deterministic-build-output-test.ts | 118 - integration/error-boundary-test.ts | 2718 --- integration/error-boundary-v2-test.ts | 497 - integration/error-data-request-test.ts | 349 - integration/error-sanitization-test.ts | 1290 -- integration/fetch-globals-test.ts | 43 - integration/fetcher-layout-test.ts | 563 - integration/fetcher-test.ts | 1065 -- integration/file-uploads-test.ts | 295 - integration/flat-routes-test.ts | 416 - integration/fog-of-war-test.ts | 1592 -- integration/form-data-test.ts | 125 - integration/form-test.ts | 2289 --- integration/headers-test.ts | 471 - integration/helpers/cf-template/.gitignore | 8 - integration/helpers/cf-template/app/root.tsx | 33 - .../helpers/cf-template/app/routes/_index.tsx | 41 - integration/helpers/cf-template/package.json | 32 - .../helpers/cf-template/public/favicon.ico | Bin 16958 -> 0 bytes .../helpers/cf-template/remix.config.js | 21 - .../helpers/cf-template/remix.env.d.ts | 8 - integration/helpers/cf-template/server.ts | 53 - integration/helpers/cf-template/tsconfig.json | 22 - integration/helpers/cf-template/wrangler.toml | 9 - integration/helpers/cleanup.mjs | 27 - integration/helpers/create-fixture.ts | 436 - integration/helpers/deno-template/.gitignore | 6 - .../helpers/deno-template/app/root.tsx | 33 - .../deno-template/app/routes/_index.tsx | 41 - .../helpers/deno-template/package.json | 28 - .../helpers/deno-template/public/favicon.ico | Bin 16958 -> 0 bytes .../helpers/deno-template/remix.config.js | 17 - integration/helpers/deno-template/server.ts | 13 - integration/helpers/killtree.ts | 57 - integration/helpers/node-template/.gitignore | 6 - .../helpers/node-template/app/root.tsx | 33 - .../node-template/app/routes/_index.tsx | 41 - .../helpers/node-template/package.json | 41 - .../helpers/node-template/public/favicon.ico | Bin 16958 -> 0 bytes .../helpers/node-template/remix.config.js | 11 - .../helpers/node-template/remix.env.d.ts | 2 - .../helpers/node-template/tsconfig.json | 22 - integration/helpers/playwright-fixture.ts | 355 - .../helpers/vite-5-template/.gitignore | 5 - .../helpers/vite-5-template/app/root.tsx | 25 - .../vite-5-template/app/routes/_index.tsx | 41 - integration/helpers/vite-5-template/env.d.ts | 2 - .../helpers/vite-5-template/package.json | 42 - .../vite-5-template/public/favicon.ico | Bin 16958 -> 0 bytes .../helpers/vite-5-template/tsconfig.json | 21 - .../helpers/vite-5-template/vite.config.ts | 7 - .../helpers/vite-6-template/.gitignore | 5 - .../helpers/vite-6-template/app/root.tsx | 25 - .../vite-6-template/app/routes/_index.tsx | 41 - integration/helpers/vite-6-template/env.d.ts | 2 - .../helpers/vite-6-template/package.json | 42 - .../vite-6-template/public/favicon.ico | Bin 16958 -> 0 bytes .../helpers/vite-6-template/tsconfig.json | 21 - .../helpers/vite-6-template/vite.config.ts | 7 - .../vite-cloudflare-template/.gitignore | 5 - .../vite-cloudflare-template/app/root.tsx | 25 - .../app/routes/_index.tsx | 41 - .../helpers/vite-cloudflare-template/env.d.ts | 2 - .../vite-cloudflare-template/package.json | 36 - .../public/favicon.ico | Bin 16958 -> 0 bytes .../vite-cloudflare-template/tsconfig.json | 21 - .../vite-cloudflare-template/vite.config.ts | 7 - integration/helpers/vite.ts | 406 - integration/hmr-test.ts | 669 - integration/hook-useSubmit-test.ts | 136 - integration/js-routes-test.ts | 46 - integration/layout-route-test.ts | 66 - integration/link-test.ts | 624 - integration/loader-test.ts | 277 - integration/matches-test.ts | 200 - integration/mdx-test.ts | 130 - integration/multiple-cookies-test.ts | 79 - integration/navigation-state-test.ts | 920 - integration/package.json | 50 - integration/path-mapping-test.ts | 117 - integration/playwright.config.ts | 49 - integration/postcss-test.ts | 457 - integration/prefetch-test.ts | 1249 -- integration/redirects-test.ts | 374 - integration/remix-serve-test.ts | 70 - integration/rendering-test.ts | 72 - integration/request-test.ts | 178 - integration/resource-routes-test.ts | 337 - integration/revalidate-test.ts | 590 - integration/root-route-test.ts | 421 - integration/route-collisions-test.ts | 144 - integration/scroll-test.ts | 125 - .../server-code-in-browser-message-test.ts | 64 - integration/server-entry-test.ts | 64 - integration/server-source-maps-test.ts | 50 - integration/set-cookie-revalidation-test.ts | 267 - integration/shared-route-imports-test.ts | 189 - integration/single-fetch-test.ts | 4050 ---- integration/splat-routes-test.ts | 129 - integration/svg-in-node-modules-test.ts | 52 - integration/tailwind-test.ts | 428 - integration/transition-test.ts | 319 - integration/tsconfig.json | 19 - integration/upload-test.ts | 339 - integration/vanilla-extract-test.ts | 675 - integration/vite-absolute-base-test.ts | 42 - integration/vite-basename-test.ts | 593 - integration/vite-build-test.ts | 388 - integration/vite-cloudflare-test.ts | 156 - integration/vite-css-test.ts | 382 - integration/vite-dev-custom-entry-test.ts | 176 - integration/vite-dev-test.ts | 493 - integration/vite-dot-client-test.ts | 47 - integration/vite-dot-server-test.ts | 269 - integration/vite-dotenv-test.ts | 81 - integration/vite-fs-routes-test.ts | 517 - integration/vite-hmr-hdr-test.ts | 389 - integration/vite-loader-context-test.ts | 53 - integration/vite-manifests-test.ts | 129 - integration/vite-node-env-test.ts | 79 - .../vite-plugin-order-validation-test.ts | 33 - integration/vite-presets-test.ts | 264 - integration/vite-route-added-test.ts | 76 - integration/vite-route-config-test.ts | 406 - ...e-route-exports-modified-offscreen-test.ts | 102 - integration/vite-server-bundles-test.ts | 434 - integration/vite-server-fs-allow-test.ts | 51 - integration/vite-spa-mode-test.ts | 997 - integration/vite-unused-route-exports-test.ts | 37 - jest.config.js | 36 - jest/buildRemix.js | 18 - jest/jest.config.shared.js | 28 - jest/transform.js | 24 - package.json | 145 - packages/ADDING_A_PACKAGE.md | 9 - packages/create-remix/.eslintrc.js | 15 - packages/create-remix/CHANGELOG.md | 464 - packages/create-remix/README.md | 13 - .../__tests__/create-remix-test.ts | 1480 -- .../__tests__/fixtures/arc.tar.gz | Bin 38912 -> 0 bytes .../create-remix/__tests__/fixtures/arc.tgz | Bin 38912 -> 0 bytes .../__tests__/fixtures/blank/package.json | 1 - .../__tests__/fixtures/examples-main.tar.gz | Bin 81920 -> 0 bytes .../fixtures/failing-remix-init/package.json | 1 - .../failing-remix-init/remix.init/index.js | 3 - .../__tests__/fixtures/nested-dir-repo.tar.gz | Bin 7078 -> 0 bytes .../__tests__/fixtures/remix-repo.tar.gz | Bin 179712 -> 0 bytes .../__tests__/fixtures/stack.tar.gz | Bin 34304 -> 0 bytes .../__tests__/fixtures/stack/.gitignore | 6 - .../__tests__/fixtures/stack/README.md | 38 - .../fixtures/stack/app/entry.client.tsx | 4 - .../fixtures/stack/app/entry.server.tsx | 22 - .../__tests__/fixtures/stack/app/root.tsx | 25 - .../__tests__/fixtures/stack/app/utils.ts | 1 - .../__tests__/fixtures/stack/package.json | 19 - .../fixtures/stack/public/favicon.ico | Bin 16958 -> 0 bytes .../__tests__/fixtures/stack/remix.config.js | 8 - .../__tests__/fixtures/stack/remix.env.d.ts | 2 - .../fixtures/stack/remix.init/index.js | 1 - .../__tests__/fixtures/stack/tsconfig.json | 22 - .../successful-remix-init/package.json | 1 - .../successful-remix-init/remix.init/index.js | 9 - .../create-remix/__tests__/fixtures/tar.js | 21 - .../fixtures/with-ignored-dir/package.json | 1 - .../create-remix/__tests__/github-mocks.ts | 364 - .../create-remix/__tests__/msw-register.ts | 9 - packages/create-remix/__tests__/msw.ts | 42 - .../create-remix/__tests__/setupAfterEnv.ts | 3 - packages/create-remix/cli.ts | 13 - packages/create-remix/copy-template.ts | 563 - packages/create-remix/index.ts | 858 - packages/create-remix/jest.config.js | 7 - packages/create-remix/loading-indicator.ts | 175 - packages/create-remix/package.json | 57 - packages/create-remix/prompt.ts | 193 - packages/create-remix/prompts-confirm.ts | 177 - packages/create-remix/prompts-multi-select.ts | 194 - packages/create-remix/prompts-prompt-base.ts | 115 - packages/create-remix/prompts-select.ts | 221 - packages/create-remix/prompts-text.ts | 284 - packages/create-remix/rollup.config.js | 64 - packages/create-remix/tsconfig.json | 19 - packages/create-remix/utils.ts | 305 - packages/remix-architect/CHANGELOG.md | 599 - packages/remix-architect/README.md | 13 - .../remix-architect/__tests__/554828.jpeg | Bin 26669 -> 0 bytes .../__tests__/binaryTypes-test.ts | 11 - .../remix-architect/__tests__/server-test.ts | 295 - packages/remix-architect/__tests__/setup.ts | 2 - packages/remix-architect/binaryTypes.ts | 69 - packages/remix-architect/index.ts | 4 - packages/remix-architect/jest.config.js | 5 - packages/remix-architect/package.json | 48 - packages/remix-architect/rollup.config.js | 6 - packages/remix-architect/server.ts | 138 - .../sessions/arcTableSessionStorage.ts | 121 - packages/remix-architect/tsconfig.json | 17 - packages/remix-cloudflare-pages/CHANGELOG.md | 627 - packages/remix-cloudflare-pages/README.md | 13 - packages/remix-cloudflare-pages/index.ts | 6 - packages/remix-cloudflare-pages/package.json | 47 - .../remix-cloudflare-pages/rollup.config.js | 44 - packages/remix-cloudflare-pages/tsconfig.json | 21 - packages/remix-cloudflare-pages/worker.ts | 148 - .../remix-cloudflare-workers/CHANGELOG.md | 567 - packages/remix-cloudflare-workers/README.md | 13 - packages/remix-cloudflare-workers/index.ts | 6 - .../remix-cloudflare-workers/package.json | 47 - .../remix-cloudflare-workers/rollup.config.js | 44 - .../remix-cloudflare-workers/tsconfig.json | 21 - packages/remix-cloudflare-workers/worker.ts | 142 - packages/remix-cloudflare/CHANGELOG.md | 750 - packages/remix-cloudflare/crypto.ts | 53 - packages/remix-cloudflare/globals.ts | 12 - packages/remix-cloudflare/implementations.ts | 15 - packages/remix-cloudflare/index.ts | 75 - packages/remix-cloudflare/package.json | 45 - packages/remix-cloudflare/rollup.config.js | 51 - .../sessions/workersKVStorage.ts | 80 - packages/remix-cloudflare/tsconfig.json | 21 - packages/remix-css-bundle/CHANGELOG.md | 299 - packages/remix-css-bundle/README.md | 9 - packages/remix-css-bundle/index.ts | 4 - packages/remix-css-bundle/package.json | 24 - packages/remix-css-bundle/rollup.config.js | 71 - packages/remix-css-bundle/tsconfig.json | 18 - packages/remix-deno/.empty.js | 6 - packages/remix-deno/CHANGELOG.md | 752 - packages/remix-deno/README.md | 16 - packages/remix-deno/crypto.ts | 52 - packages/remix-deno/globals.ts | 13 - packages/remix-deno/implementations.ts | 17 - packages/remix-deno/index.ts | 78 - packages/remix-deno/package.json | 32 - packages/remix-deno/rollup.config.js | 32 - packages/remix-deno/server.ts | 119 - packages/remix-deno/sessions/fileStorage.ts | 112 - packages/remix-dev/.gitignore | 2 - packages/remix-dev/CHANGELOG.md | 2081 -- packages/remix-dev/README.md | 13 - packages/remix-dev/__tests__/cli-test.ts | 201 - .../__tests__/cssSideEffectImports-test.ts | 476 - .../remix-dev/__tests__/defineRoutes-test.ts | 166 - .../__tests__/fixtures/cloudflare/.gitignore | 7 - .../fixtures/cloudflare/.node-version | 1 - .../__tests__/fixtures/cloudflare/README.md | 22 - .../fixtures/cloudflare/app/root.tsx | 33 - .../fixtures/cloudflare/app/routes/_index.tsx | 41 - .../fixtures/cloudflare/package.json | 32 - .../fixtures/cloudflare/public/_headers | 4 - .../fixtures/cloudflare/public/_routes.json | 5 - .../fixtures/cloudflare/public/favicon.ico | Bin 16958 -> 0 bytes .../fixtures/cloudflare/remix.config.js | 14 - .../fixtures/cloudflare/remix.env.d.ts | 3 - .../__tests__/fixtures/cloudflare/server.ts | 9 - .../fixtures/cloudflare/tsconfig.json | 22 - .../__tests__/fixtures/deno/.gitignore | 6 - .../fixtures/deno/.vscode/extensions.json | 3 - .../deno/.vscode/resolve_npm_imports.json | 22 - .../fixtures/deno/.vscode/settings.json | 4 - .../__tests__/fixtures/deno/README.md | 128 - .../__tests__/fixtures/deno/app/root.tsx | 34 - .../fixtures/deno/app/routes/_index.tsx | 42 - .../__tests__/fixtures/deno/deno.json | 6 - .../__tests__/fixtures/deno/package.json | 30 - .../fixtures/deno/public/favicon.ico | Bin 16958 -> 0 bytes .../__tests__/fixtures/deno/remix.config.js | 13 - .../__tests__/fixtures/deno/server.ts | 13 - .../__tests__/fixtures/examples-main.tar.gz | Bin 81920 -> 0 bytes .../fixtures/failing-remix-init/package.json | 1 - .../failing-remix-init/remix.init/index.js | 3 - .../__tests__/fixtures/nested-dir-repo.tar.gz | Bin 34304 -> 0 bytes .../__tests__/fixtures/node/.gitignore | 6 - .../__tests__/fixtures/node/README.md | 38 - .../__tests__/fixtures/node/app/root.tsx | 33 - .../fixtures/node/app/routes/_index.tsx | 41 - .../__tests__/fixtures/node/package.json | 30 - .../fixtures/node/public/favicon.ico | Bin 16958 -> 0 bytes .../__tests__/fixtures/node/remix.config.js | 7 - .../__tests__/fixtures/node/remix.env.d.ts | 2 - .../__tests__/fixtures/node/tsconfig.json | 22 - .../__tests__/fixtures/remix-repo.tar.gz | Bin 179712 -> 0 bytes .../remix-dev/__tests__/fixtures/stack.tar.gz | Bin 34304 -> 0 bytes .../__tests__/fixtures/stack/.gitignore | 6 - .../__tests__/fixtures/stack/README.md | 38 - .../fixtures/stack/app/entry.client.tsx | 4 - .../fixtures/stack/app/entry.server.tsx | 23 - .../__tests__/fixtures/stack/app/root.tsx | 25 - .../__tests__/fixtures/stack/app/utils.ts | 1 - .../__tests__/fixtures/stack/package.json | 15 - .../fixtures/stack/public/favicon.ico | Bin 16958 -> 0 bytes .../__tests__/fixtures/stack/remix.config.js | 7 - .../__tests__/fixtures/stack/remix.env.d.ts | 2 - .../fixtures/stack/remix.init/index.js | 1 - .../__tests__/fixtures/stack/tsconfig.json | 22 - .../successful-remix-init/package.json | 1 - .../successful-remix-init/remix.init/index.js | 9 - packages/remix-dev/__tests__/fixtures/tar.js | 21 - .../remix-dev/__tests__/flat-routes-test.ts | 891 - packages/remix-dev/__tests__/github-mocks.ts | 358 - packages/remix-dev/__tests__/init-test.ts | 152 - packages/remix-dev/__tests__/msw.ts | 33 - .../remix-dev/__tests__/readConfig-test.ts | 80 - packages/remix-dev/__tests__/reveal-test.ts | 106 - .../routeManifestToRouteConfig-test.ts | 111 - packages/remix-dev/__tests__/setupAfterEnv.ts | 3 - packages/remix-dev/__tests__/styles-test.ts | 60 - .../remix-dev/__tests__/utils/captureError.ts | 14 - packages/remix-dev/__tests__/utils/cli.ts | 101 - packages/remix-dev/__tests__/utils/eol.ts | 2 - packages/remix-dev/__tests__/utils/git.ts | 18 - packages/remix-dev/__tests__/utils/withApp.ts | 41 - .../__tests__/validateRouteConfig-test.ts | 141 - packages/remix-dev/assets-manifest.d.ts | 6 - packages/remix-dev/cache.ts | 7 - packages/remix-dev/channel.ts | 28 - packages/remix-dev/cli.ts | 11 - packages/remix-dev/cli/commands.ts | 435 - .../remix-dev/cli/detectPackageManager.ts | 23 - packages/remix-dev/cli/index.ts | 1 - packages/remix-dev/cli/run.ts | 289 - packages/remix-dev/cli/useJavascript.ts | 30 - packages/remix-dev/colors.ts | 29 - packages/remix-dev/compiler/analysis.ts | 14 - packages/remix-dev/compiler/build.ts | 7 - packages/remix-dev/compiler/cancel.ts | 7 - packages/remix-dev/compiler/compiler.ts | 144 - packages/remix-dev/compiler/context.ts | 11 - packages/remix-dev/compiler/css/bundle.ts | 60 - packages/remix-dev/compiler/css/compiler.ts | 95 - packages/remix-dev/compiler/css/index.ts | 2 - .../compiler/css/plugins/bundleEntry.ts | 44 - packages/remix-dev/compiler/fileWatchCache.ts | 199 - packages/remix-dev/compiler/index.ts | 5 - packages/remix-dev/compiler/js/compiler.ts | 186 - packages/remix-dev/compiler/js/index.ts | 2 - .../js/plugins/browserNodeBuiltinsPolyfill.ts | 37 - packages/remix-dev/compiler/js/plugins/hmr.ts | 240 - .../remix-dev/compiler/js/plugins/routes.ts | 107 - packages/remix-dev/compiler/js/write.ts | 14 - packages/remix-dev/compiler/lazyValue.ts | 45 - packages/remix-dev/compiler/manifest.ts | 195 - packages/remix-dev/compiler/options.ts | 8 - .../compiler/plugins/absoluteCssUrlsPlugin.ts | 23 - .../compiler/plugins/cssBundlePlugin.ts | 38 - .../remix-dev/compiler/plugins/cssImports.ts | 203 - .../compiler/plugins/cssModuleImports.ts | 173 - .../compiler/plugins/cssSideEffectImports.ts | 209 - .../compiler/plugins/emptyModules.ts | 43 - .../remix-dev/compiler/plugins/external.ts | 17 - packages/remix-dev/compiler/plugins/mdx.ts | 149 - .../compiler/plugins/vanillaExtract.ts | 161 - .../remix-dev/compiler/server/compiler.ts | 138 - packages/remix-dev/compiler/server/index.ts | 2 - .../compiler/server/plugins/bareImports.ts | 111 - .../compiler/server/plugins/entry.ts | 73 - .../compiler/server/plugins/manifest.ts | 41 - .../compiler/server/plugins/routes.ts | 48 - .../plugins/serverNodeBuiltinsPolyfill.ts | 17 - .../compiler/server/virtualModules.ts | 14 - packages/remix-dev/compiler/server/write.ts | 48 - packages/remix-dev/compiler/utils/crypto.ts | 19 - packages/remix-dev/compiler/utils/loaders.ts | 55 - packages/remix-dev/compiler/utils/log.ts | 44 - packages/remix-dev/compiler/utils/postcss.ts | 260 - .../remix-dev/compiler/utils/routeExports.ts | 70 - packages/remix-dev/compiler/utils/tsconfig.ts | 29 - packages/remix-dev/compiler/watch.ts | 158 - packages/remix-dev/config.ts | 922 - .../config/defaults/entry.client.tsx | 12 - .../remix-dev/config/defaults/entry.dev.ts | 13 - .../defaults/entry.server.cloudflare.tsx | 57 - .../config/defaults/entry.server.deno.tsx | 57 - .../config/defaults/entry.server.node.tsx | 155 - .../config/defaults/entry.server.spa.tsx | 20 - packages/remix-dev/config/flat-routes.ts | 550 - packages/remix-dev/config/format.ts | 91 - packages/remix-dev/config/routes.ts | 397 - packages/remix-dev/config/serverModes.ts | 16 - packages/remix-dev/dependencies.ts | 93 - packages/remix-dev/devServer/index.ts | 1 - packages/remix-dev/devServer/liveReload.ts | 90 - packages/remix-dev/devServer_unstable/env.ts | 11 - packages/remix-dev/devServer_unstable/hdr.ts | 142 - packages/remix-dev/devServer_unstable/hmr.ts | 75 - .../remix-dev/devServer_unstable/index.ts | 287 - packages/remix-dev/devServer_unstable/proc.ts | 57 - .../remix-dev/devServer_unstable/socket.ts | 48 - packages/remix-dev/index.ts | 28 - packages/remix-dev/invariant.ts | 18 - packages/remix-dev/jest.config.js | 7 - packages/remix-dev/manifest.ts | 28 - packages/remix-dev/modules.ts | 152 - packages/remix-dev/package.json | 144 - packages/remix-dev/result.ts | 7 - packages/remix-dev/rollup.config.js | 103 - packages/remix-dev/server-build.ts | 18 - packages/remix-dev/tsconfig.json | 18 - packages/remix-dev/tux/format.ts | 25 - packages/remix-dev/tux/index.ts | 1 - packages/remix-dev/tux/logger.ts | 60 - packages/remix-dev/vite/babel.ts | 15 - packages/remix-dev/vite/build.ts | 332 - .../remix-dev/vite/cloudflare-proxy-plugin.ts | 87 - packages/remix-dev/vite/combine-urls-test.ts | 57 - packages/remix-dev/vite/combine-urls.ts | 6 - packages/remix-dev/vite/dev.ts | 76 - packages/remix-dev/vite/index.ts | 18 - .../remix-dev/vite/is-in-remix-monorepo.ts | 11 - packages/remix-dev/vite/node-adapter.ts | 98 - packages/remix-dev/vite/plugin.ts | 2023 -- packages/remix-dev/vite/profiler.ts | 44 - .../remix-dev/vite/remove-exports-test.ts | 399 - packages/remix-dev/vite/remove-exports.ts | 368 - packages/remix-dev/vite/resolve-file-url.ts | 22 - packages/remix-dev/vite/ssr-externals.ts | 22 - .../remix-dev/vite/static/refresh-utils.cjs | 189 - packages/remix-dev/vite/styles.ts | 261 - packages/remix-dev/vite/vite-node.ts | 63 - packages/remix-dev/vite/vite.ts | 31 - packages/remix-dev/vite/vmod.ts | 3 - packages/remix-eslint-config/CHANGELOG.md | 349 - packages/remix-eslint-config/README.md | 49 - packages/remix-eslint-config/index.js | 103 - packages/remix-eslint-config/internal.js | 93 - .../jest-testing-library.js | 29 - packages/remix-eslint-config/node.js | 12 - packages/remix-eslint-config/package.json | 63 - packages/remix-eslint-config/rules/core.js | 97 - packages/remix-eslint-config/rules/import.js | 10 - .../remix-eslint-config/rules/jest-dom.js | 17 - packages/remix-eslint-config/rules/jest.js | 19 - .../remix-eslint-config/rules/jsx-a11y.js | 21 - packages/remix-eslint-config/rules/react.js | 30 - .../rules/testing-library.js | 25 - .../remix-eslint-config/rules/typescript.js | 53 - .../remix-eslint-config/settings/import.js | 14 - .../remix-eslint-config/settings/react.js | 16 - packages/remix-express/CHANGELOG.md | 607 - packages/remix-express/README.md | 13 - .../remix-express/__tests__/server-test.ts | 246 - packages/remix-express/__tests__/setup.ts | 2 - packages/remix-express/index.ts | 2 - packages/remix-express/jest.config.js | 5 - packages/remix-express/package.json | 49 - packages/remix-express/rollup.config.js | 6 - packages/remix-express/server.ts | 148 - packages/remix-express/tsconfig.json | 17 - packages/remix-fs-routes/CHANGELOG.md | 53 - packages/remix-fs-routes/README.md | 13 - packages/remix-fs-routes/index.ts | 48 - packages/remix-fs-routes/package.json | 43 - packages/remix-fs-routes/rollup.config.js | 49 - packages/remix-fs-routes/tsconfig.json | 19 - packages/remix-node/.gitignore | 2 - packages/remix-node/CHANGELOG.md | 804 - packages/remix-node/README.md | 13 - packages/remix-node/__tests__/assets/test.txt | 1 - .../__tests__/fileUploadHandler-test.ts | 116 - .../remix-node/__tests__/sessions-test.ts | 128 - packages/remix-node/__tests__/setup.ts | 2 - packages/remix-node/__tests__/utils.ts | 5 - packages/remix-node/crypto.ts | 13 - packages/remix-node/globals.ts | 60 - packages/remix-node/implementations.ts | 15 - packages/remix-node/index.ts | 87 - packages/remix-node/install.d.ts | 1 - packages/remix-node/install.js | 8 - packages/remix-node/jest.config.js | 5 - packages/remix-node/package.json | 56 - packages/remix-node/rollup.config.js | 58 - packages/remix-node/sessions/fileStorage.ts | 112 - packages/remix-node/stream.ts | 178 - packages/remix-node/tsconfig.json | 20 - .../remix-node/upload/fileUploadHandler.ts | 251 - packages/remix-react/CHANGELOG.md | 1256 -- packages/remix-react/README.md | 13 - .../remix-react/__tests__/components-test.tsx | 347 - .../__tests__/deferred-scripts-test.tsx | 102 - .../remix-react/__tests__/exports-test.tsx | 68 - .../__tests__/integration/meta-test.tsx | 377 - .../__tests__/scroll-restoration-test.tsx | 164 - packages/remix-react/__tests__/setup.ts | 8 - packages/remix-react/browser.tsx | 430 - packages/remix-react/components.tsx | 1356 -- packages/remix-react/data.ts | 327 - packages/remix-react/entry.ts | 62 - packages/remix-react/errorBoundaries.tsx | 189 - packages/remix-react/errors.ts | 46 - packages/remix-react/fallback.tsx | 26 - packages/remix-react/fog-of-war.ts | 339 - packages/remix-react/index.tsx | 126 - packages/remix-react/invariant.ts | 13 - packages/remix-react/jest.config.js | 6 - packages/remix-react/links.ts | 559 - packages/remix-react/markup.ts | 27 - packages/remix-react/package.json | 59 - packages/remix-react/rollup.config.js | 85 - packages/remix-react/routeModules.ts | 226 - packages/remix-react/routes.tsx | 666 - packages/remix-react/scroll-restoration.tsx | 86 - packages/remix-react/server.tsx | 112 - packages/remix-react/single-fetch.tsx | 557 - packages/remix-react/tsconfig.json | 19 - packages/remix-react/warnings.ts | 8 - packages/remix-route-config/CHANGELOG.md | 53 - packages/remix-route-config/README.md | 13 - .../__tests__/route-config-test.ts | 440 - packages/remix-route-config/index.ts | 13 - packages/remix-route-config/jest.config.js | 6 - packages/remix-route-config/package.json | 46 - packages/remix-route-config/rollup.config.js | 49 - packages/remix-route-config/routes.ts | 182 - packages/remix-route-config/tsconfig.json | 19 - .../remix-routes-option-adapter/CHANGELOG.md | 53 - .../remix-routes-option-adapter/README.md | 13 - packages/remix-routes-option-adapter/index.ts | 24 - .../remix-routes-option-adapter/package.json | 43 - .../rollup.config.js | 49 - .../remix-routes-option-adapter/tsconfig.json | 19 - packages/remix-serve/CHANGELOG.md | 716 - packages/remix-serve/README.md | 13 - packages/remix-serve/cli.ts | 154 - packages/remix-serve/package.json | 45 - packages/remix-serve/rollup.config.js | 7 - packages/remix-serve/tsconfig.json | 18 - packages/remix-server-runtime/.eslintrc.js | 14 - packages/remix-server-runtime/CHANGELOG.md | 1250 -- packages/remix-server-runtime/README.md | 26 - .../__tests__/.eslintrc.js | 7 - .../__tests__/cookies-test.ts | 215 - .../__tests__/data-test.ts | 352 - .../__tests__/formData-test.ts | 176 - .../__tests__/handle-error-test.ts | 227 - .../__tests__/handler-test.ts | 33 - .../__tests__/markup-test.ts | 56 - .../__tests__/responses-test.ts | 96 - .../__tests__/serialize-test.ts | 54 - .../__tests__/server-test.ts | 2334 --- .../__tests__/sessions-test.ts | 356 - .../remix-server-runtime/__tests__/setup.ts | 3 - .../remix-server-runtime/__tests__/utils.ts | 109 - packages/remix-server-runtime/build.ts | 58 - packages/remix-server-runtime/cookies.ts | 261 - packages/remix-server-runtime/crypto.ts | 64 - packages/remix-server-runtime/data.ts | 181 - packages/remix-server-runtime/deprecations.ts | 13 - packages/remix-server-runtime/dev.ts | 47 - packages/remix-server-runtime/entry.ts | 58 - packages/remix-server-runtime/errors.ts | 117 - packages/remix-server-runtime/formData.ts | 67 - packages/remix-server-runtime/future.ts | 1 - packages/remix-server-runtime/headers.ts | 103 - packages/remix-server-runtime/index.ts | 94 - packages/remix-server-runtime/interface.ts | 10 - packages/remix-server-runtime/invariant.ts | 16 - packages/remix-server-runtime/jest.config.js | 5 - packages/remix-server-runtime/jsonify.ts | 261 - packages/remix-server-runtime/links.ts | 192 - packages/remix-server-runtime/markup.ts | 19 - packages/remix-server-runtime/mode.ts | 16 - packages/remix-server-runtime/package.json | 51 - packages/remix-server-runtime/reexport.ts | 64 - packages/remix-server-runtime/responses.ts | 236 - .../remix-server-runtime/rollup.config.js | 73 - .../remix-server-runtime/routeMatching.ts | 29 - packages/remix-server-runtime/routeModules.ts | 268 - packages/remix-server-runtime/routes.ts | 135 - packages/remix-server-runtime/serialize.ts | 188 - packages/remix-server-runtime/server.ts | 798 - .../remix-server-runtime/serverHandoff.ts | 30 - packages/remix-server-runtime/sessions.ts | 314 - .../sessions/cookieStorage.ts | 69 - .../sessions/memoryStorage.ts | 73 - packages/remix-server-runtime/single-fetch.ts | 630 - packages/remix-server-runtime/tsconfig.json | 19 - packages/remix-server-runtime/typecheck.ts | 15 - .../remix-server-runtime/upload/errors.ts | 5 - .../upload/memoryUploadHandler.ts | 50 - packages/remix-server-runtime/warnings.ts | 8 - packages/remix-testing/CHANGELOG.md | 677 - packages/remix-testing/README.md | 13 - .../remix-testing/__tests__/stub-test.tsx | 227 - packages/remix-testing/create-remix-stub.tsx | 218 - packages/remix-testing/index.ts | 2 - packages/remix-testing/jest.config.js | 8 - packages/remix-testing/jest.setup.js | 8 - packages/remix-testing/package.json | 56 - packages/remix-testing/rollup.config.js | 72 - packages/remix-testing/tsconfig.json | 19 - packages/remix/CHANGELOG.md | 3 - packages/remix/README.md | 20 - packages/remix/index.ts | 13 - packages/remix/package.json | 31 - packages/remix/rollup.config.js | 60 - packages/remix/tsconfig.json | 19 - ...ngesets__assemble-release-plan@5.2.2.patch | 39 - playground/README.md | 3 - pnpm-lock.yaml | 15834 ---------------- pnpm-workspace.yaml | 4 - prettier.config.js | 2 - rollup.config.js | 15 - rollup.utils.js | 239 - scripts/build.mjs | 41 - scripts/bump-fetch-versions.sh | 24 - scripts/bump-router-versions.sh | 49 - scripts/clean-build.mjs | 35 - scripts/close-v2-issues-comment.md | 17 - scripts/close-v2-issues.mjs | 107 - scripts/close-v2-prs-comment.md | 17 - scripts/compile-release-notes.mjs | 167 - scripts/copy-build-to-dist.mjs | 169 - scripts/copy-templates-to-fixtures.sh | 17 - scripts/deployment-test/_shared.mjs | 148 - scripts/deployment-test/arc.mjs | 148 - scripts/deployment-test/cf-pages.mjs | 155 - scripts/deployment-test/cf-workers.mjs | 130 - scripts/deployment-test/cypress.json | 1 - scripts/deployment-test/cypress/.eslintrc.js | 6 - scripts/deployment-test/cypress/e2e/smoke.ts | 6 - .../cypress/fixtures/example.json | 1 - .../deployment-test/cypress/plugins/index.ts | 22 - .../deployment-test/cypress/support/index.js | 1 - scripts/deployment-test/cypress/tsconfig.json | 27 - scripts/deployment-test/deno-deploy.mjs | 70 - scripts/deployment-test/fly.mjs | 131 - scripts/deployment-test/package.json | 20 - scripts/find-release-from-changeset.js | 37 - scripts/lint-templates.sh | 39 - scripts/markdown-references.mjs | 34 - scripts/patchup-version.mjs | 126 - scripts/playground/new.js | 69 - scripts/playground/template/.env | 2 - scripts/playground/template/.gitignore | 4 - scripts/playground/template/.prettierignore | 7 - scripts/playground/template/README.md | 5 - scripts/playground/template/app/db.server.ts | 24 - .../playground/template/app/entry.client.tsx | 22 - .../playground/template/app/entry.server.tsx | 59 - .../template/app/models/note.server.ts | 54 - .../template/app/models/user.server.ts | 59 - scripts/playground/template/app/root.tsx | 46 - .../playground/template/app/routes/index.tsx | 44 - .../playground/template/app/routes/join.tsx | 172 - .../playground/template/app/routes/login.tsx | 181 - .../playground/template/app/routes/logout.tsx | 12 - .../playground/template/app/routes/notes.tsx | 74 - .../template/app/routes/notes/$noteId.tsx | 70 - .../template/app/routes/notes/index.tsx | 17 - .../template/app/routes/notes/new.tsx | 113 - .../playground/template/app/session.server.ts | 97 - .../template/app/styles/tailwind.css | 3 - scripts/playground/template/app/utils.ts | 71 - scripts/playground/template/package.json | 58 - .../20220307190657_init/migration.sql | 31 - .../prisma/migrations/migration_lock.toml | 3 - .../playground/template/prisma/schema.prisma | 38 - scripts/playground/template/prisma/seed.ts | 53 - .../playground/template/public/favicon.ico | Bin 16958 -> 0 bytes scripts/playground/template/remix.config.js | 5 - scripts/playground/template/remix.env.d.ts | 2 - .../playground/template/remix.init/index.js | 15 - scripts/playground/template/server.js | 51 - .../playground/template/tailwind.config.js | 8 - scripts/playground/template/tsconfig.json | 26 - scripts/prompt-confirm.d.ts | 7 - scripts/publish-private.js | 80 - scripts/publish.js | 87 - scripts/release.js | 422 - scripts/remove-prerelease-changelogs.mjs | 123 - scripts/run-migration-on-examples.js | 40 - scripts/tsconfig.json | 15 - scripts/unist.d.ts | 62 - scripts/utils.js | 252 - scripts/version.js | 67 - templates/.eslintignore | 1 - templates/.gitignore | 4 - .../classic-remix-compiler/arc/.eslintrc.cjs | 83 - .../classic-remix-compiler/arc/.gitignore | 12 - .../classic-remix-compiler/arc/README.md | 41 - templates/classic-remix-compiler/arc/app.arc | 21 - .../arc/app/entry.client.tsx | 18 - .../arc/app/entry.server.tsx | 140 - .../classic-remix-compiler/arc/app/root.tsx | 34 - .../arc/app/routes/_index.tsx | 41 - .../classic-remix-compiler/arc/package.json | 42 - .../arc/plugin-remix.js | 51 - .../arc/public/favicon.ico | Bin 16958 -> 0 bytes .../arc/remix.config.js | 10 - .../classic-remix-compiler/arc/remix.env.d.ts | 2 - .../classic-remix-compiler/arc/server.ts | 9 - .../classic-remix-compiler/arc/tsconfig.json | 23 - .../cloudflare-pages/.eslintrc.cjs | 84 - .../cloudflare-pages/.gitignore | 10 - .../cloudflare-pages/.node-version | 1 - .../cloudflare-pages/README.md | 22 - .../cloudflare-pages/app/entry.client.tsx | 18 - .../cloudflare-pages/app/entry.server.tsx | 56 - .../cloudflare-pages/app/root.tsx | 33 - .../cloudflare-pages/app/routes/_index.tsx | 41 - .../cloudflare-pages/package.json | 40 - .../cloudflare-pages/public/_headers | 4 - .../cloudflare-pages/public/_routes.json | 5 - .../cloudflare-pages/public/favicon.ico | Bin 16958 -> 0 bytes .../cloudflare-pages/remix.config.js | 15 - .../cloudflare-pages/remix.env.d.ts | 3 - .../cloudflare-pages/server.ts | 9 - .../cloudflare-pages/tsconfig.json | 23 - .../cloudflare-workers/.eslintrc.cjs | 83 - .../cloudflare-workers/.gitignore | 7 - .../cloudflare-workers/README.md | 37 - .../cloudflare-workers/app/entry.client.tsx | 18 - .../cloudflare-workers/app/entry.server.tsx | 56 - .../cloudflare-workers/app/root.tsx | 33 - .../cloudflare-workers/app/routes/_index.tsx | 41 - .../cloudflare-workers/package.json | 41 - .../cloudflare-workers/public/favicon.ico | Bin 16958 -> 0 bytes .../cloudflare-workers/remix.config.js | 18 - .../cloudflare-workers/remix.env.d.ts | 8 - .../cloudflare-workers/server.ts | 56 - .../cloudflare-workers/tsconfig.json | 23 - .../cloudflare-workers/wrangler.toml | 12 - .../classic-remix-compiler/deno/.gitignore | 6 - .../deno/.vscode/extensions.json | 3 - .../deno/.vscode/resolve_npm_imports.json | 22 - .../deno/.vscode/settings.json | 4 - .../classic-remix-compiler/deno/README.md | 128 - .../deno/app/entry.client.tsx | 18 - .../deno/app/entry.server.tsx | 55 - .../classic-remix-compiler/deno/app/root.tsx | 34 - .../deno/app/routes/_index.tsx | 42 - .../classic-remix-compiler/deno/deno.json | 6 - .../classic-remix-compiler/deno/package.json | 31 - .../deno/public/favicon.ico | Bin 16958 -> 0 bytes .../deno/remix.config.js | 14 - .../classic-remix-compiler/deno/server.ts | 11 - .../express/.eslintrc.cjs | 84 - .../classic-remix-compiler/express/.gitignore | 6 - .../classic-remix-compiler/express/README.md | 36 - .../express/app/entry.client.tsx | 18 - .../express/app/entry.server.tsx | 140 - .../express/app/root.tsx | 33 - .../express/app/routes/_index.tsx | 41 - .../express/package.json | 48 - .../express/public/favicon.ico | Bin 16958 -> 0 bytes .../express/remix.config.js | 9 - .../express/remix.env.d.ts | 2 - .../classic-remix-compiler/express/server.js | 113 - .../express/tsconfig.json | 23 - .../classic-remix-compiler/fly/.eslintrc.cjs | 83 - .../classic-remix-compiler/fly/.gitignore | 6 - .../classic-remix-compiler/fly/README.md | 41 - .../fly/app/entry.client.tsx | 18 - .../fly/app/entry.server.tsx | 140 - .../classic-remix-compiler/fly/app/root.tsx | 33 - .../fly/app/routes/_index.tsx | 41 - .../classic-remix-compiler/fly/package.json | 39 - .../fly/public/favicon.ico | Bin 16958 -> 0 bytes .../fly/remix.config.js | 8 - .../classic-remix-compiler/fly/remix.env.d.ts | 2 - .../classic-remix-compiler/fly/tsconfig.json | 23 - .../remix-javascript/.eslintrc.cjs | 56 - .../remix-javascript/.gitignore | 6 - .../remix-javascript/README.md | 38 - .../remix-javascript/app/entry.client.jsx | 18 - .../remix-javascript/app/entry.server.jsx | 121 - .../remix-javascript/app/root.jsx | 32 - .../remix-javascript/app/routes/_index.jsx | 36 - .../remix-javascript/package.json | 30 - .../remix-javascript/public/favicon.ico | Bin 16958 -> 0 bytes .../remix-javascript/remix.config.js | 8 - .../remix/.eslintrc.cjs | 83 - .../classic-remix-compiler/remix/.gitignore | 6 - .../classic-remix-compiler/remix/README.md | 38 - .../remix/app/entry.client.tsx | 18 - .../remix/app/entry.server.tsx | 140 - .../classic-remix-compiler/remix/app/root.tsx | 33 - .../remix/app/routes/_index.tsx | 41 - .../classic-remix-compiler/remix/package.json | 38 - .../remix/public/favicon.ico | Bin 16958 -> 0 bytes .../remix/remix.config.js | 8 - .../remix/remix.env.d.ts | 2 - .../remix/tsconfig.json | 23 - templates/cloudflare-workers/.eslintrc.cjs | 83 - templates/cloudflare-workers/.gitignore | 6 - templates/cloudflare-workers/README.md | 43 - .../cloudflare-workers/app/entry.client.tsx | 18 - .../cloudflare-workers/app/entry.server.tsx | 56 - templates/cloudflare-workers/app/root.tsx | 45 - .../cloudflare-workers/app/routes/_index.tsx | 138 - templates/cloudflare-workers/app/tailwind.css | 12 - templates/cloudflare-workers/load-context.ts | 22 - templates/cloudflare-workers/package.json | 46 - .../cloudflare-workers/postcss.config.js | 6 - .../cloudflare-workers/public/favicon.ico | Bin 16958 -> 0 bytes .../cloudflare-workers/public/logo-dark.png | Bin 80332 -> 0 bytes .../cloudflare-workers/public/logo-light.png | Bin 5906 -> 0 bytes templates/cloudflare-workers/server.ts | 37 - .../cloudflare-workers/tailwind.config.ts | 22 - templates/cloudflare-workers/tsconfig.json | 37 - templates/cloudflare-workers/vite.config.ts | 42 - .../worker-configuration.d.ts | 3 - templates/cloudflare-workers/wrangler.toml | 14 - templates/cloudflare/.eslintrc.cjs | 84 - templates/cloudflare/.gitignore | 8 - templates/cloudflare/README.md | 47 - templates/cloudflare/app/entry.client.tsx | 18 - templates/cloudflare/app/entry.server.tsx | 56 - templates/cloudflare/app/root.tsx | 45 - templates/cloudflare/app/routes/_index.tsx | 138 - templates/cloudflare/app/tailwind.css | 12 - templates/cloudflare/functions/[[path]].ts | 8 - templates/cloudflare/load-context.ts | 17 - templates/cloudflare/package.json | 46 - templates/cloudflare/postcss.config.js | 6 - templates/cloudflare/public/_headers | 4 - templates/cloudflare/public/_routes.json | 5 - templates/cloudflare/public/favicon.ico | Bin 16958 -> 0 bytes templates/cloudflare/public/logo-dark.png | Bin 80332 -> 0 bytes templates/cloudflare/public/logo-light.png | Bin 5906 -> 0 bytes templates/cloudflare/tailwind.config.ts | 22 - templates/cloudflare/tsconfig.json | 32 - templates/cloudflare/vite.config.ts | 28 - templates/express/.eslintrc.cjs | 84 - templates/express/.gitignore | 5 - templates/express/README.md | 40 - templates/express/app/entry.client.tsx | 18 - templates/express/app/entry.server.tsx | 140 - templates/express/app/root.tsx | 45 - templates/express/app/routes/_index.tsx | 138 - templates/express/app/tailwind.css | 12 - templates/express/package.json | 49 - templates/express/postcss.config.js | 6 - templates/express/public/favicon.ico | Bin 16958 -> 0 bytes templates/express/public/logo-dark.png | Bin 80332 -> 0 bytes templates/express/public/logo-light.png | Bin 5906 -> 0 bytes templates/express/server.js | 51 - templates/express/tailwind.config.ts | 22 - templates/express/tsconfig.json | 32 - templates/express/vite.config.ts | 24 - templates/remix-javascript/.eslintrc.cjs | 61 - templates/remix-javascript/.gitignore | 5 - templates/remix-javascript/README.md | 40 - .../remix-javascript/app/entry.client.jsx | 18 - .../remix-javascript/app/entry.server.jsx | 139 - templates/remix-javascript/app/root.jsx | 44 - .../remix-javascript/app/routes/_index.jsx | 136 - templates/remix-javascript/app/tailwind.css | 12 - templates/remix-javascript/package.json | 34 - templates/remix-javascript/postcss.config.js | 6 - templates/remix-javascript/public/favicon.ico | Bin 16958 -> 0 bytes .../remix-javascript/public/logo-dark.png | Bin 80332 -> 0 bytes .../remix-javascript/public/logo-light.png | Bin 5906 -> 0 bytes templates/remix-javascript/tailwind.config.js | 20 - templates/remix-javascript/vite.config.js | 16 - templates/remix-tutorial/.eslintrc.cjs | 84 - templates/remix-tutorial/.gitignore | 5 - templates/remix-tutorial/README.md | 38 - templates/remix-tutorial/app/app.css | 397 - templates/remix-tutorial/app/data.ts | 316 - templates/remix-tutorial/app/root.tsx | 53 - templates/remix-tutorial/package.json | 42 - templates/remix-tutorial/public/favicon.ico | Bin 16958 -> 0 bytes templates/remix-tutorial/tsconfig.json | 31 - templates/remix-tutorial/vite.config.ts | 12 - templates/remix/.eslintrc.cjs | 84 - templates/remix/.gitignore | 5 - templates/remix/README.md | 40 - templates/remix/app/entry.client.tsx | 18 - templates/remix/app/entry.server.tsx | 140 - templates/remix/app/root.tsx | 45 - templates/remix/app/routes/_index.tsx | 138 - templates/remix/app/tailwind.css | 12 - templates/remix/package.json | 42 - templates/remix/postcss.config.js | 6 - templates/remix/public/favicon.ico | Bin 16958 -> 0 bytes templates/remix/public/logo-dark.png | Bin 80332 -> 0 bytes templates/remix/public/logo-light.png | Bin 5906 -> 0 bytes templates/remix/tailwind.config.ts | 22 - templates/remix/tsconfig.json | 32 - templates/remix/vite.config.ts | 24 - templates/spa/.eslintrc.cjs | 84 - templates/spa/.gitignore | 6 - templates/spa/README.md | 51 - templates/spa/app/entry.client.tsx | 18 - templates/spa/app/root.tsx | 49 - templates/spa/app/routes/_index.tsx | 138 - templates/spa/app/tailwind.css | 12 - templates/spa/package.json | 40 - templates/spa/postcss.config.js | 6 - templates/spa/public/favicon.ico | Bin 16958 -> 0 bytes templates/spa/public/logo-dark.png | Bin 80332 -> 0 bytes templates/spa/public/logo-light.png | Bin 5906 -> 0 bytes templates/spa/tailwind.config.ts | 22 - templates/spa/tsconfig.json | 25 - templates/spa/vite.config.ts | 25 - 1144 files changed, 2 insertions(+), 166539 deletions(-) delete mode 100644 .changeset/README.md delete mode 100644 .changeset/config.json delete mode 100644 .eslintignore delete mode 100644 .eslintrc.js delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml delete mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md delete mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/close-v2-issues.yml delete mode 100644 .github/workflows/deduplicate-lock-file.yml delete mode 100644 .github/workflows/deployments.yml delete mode 100644 .github/workflows/format.yml delete mode 100644 .github/workflows/lint.yml delete mode 100644 .github/workflows/merged-pr.yml delete mode 100644 .github/workflows/nightly.yml delete mode 100644 .github/workflows/no-response.yml delete mode 100644 .github/workflows/release-comments.yml delete mode 100644 .github/workflows/release-experimental.yml delete mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/shared-build.yml delete mode 100644 .github/workflows/shared-test-integration.yml delete mode 100644 .github/workflows/shared-test-unit.yml delete mode 100644 .github/workflows/stacks.yml delete mode 100644 .github/workflows/test-full.yml delete mode 100644 .github/workflows/test-pr-ubuntu.yml delete mode 100644 .github/workflows/test-pr-windows-macos.yml delete mode 100644 .github/workflows/website.yml delete mode 100644 .gitignore delete mode 100644 .prettierignore delete mode 100644 .vscode/README.md delete mode 100644 .vscode/deno_resolve_npm_imports.json delete mode 100644 .vscode/extensions.json delete mode 100644 CHANGELOG.md delete mode 100644 CLA.md delete mode 100644 CODE_OF_CONDUCT.md delete mode 100644 CONTRIBUTING.md delete mode 100644 DEVELOPMENT.md delete mode 100644 LICENSE.md delete mode 100644 babel.config.js delete mode 100644 contributors.yml delete mode 100644 decisions/0001-use-npm-to-manage-npm-dependencies-for-deno-projects.md delete mode 100644 decisions/0002-do-not-clone-request.md delete mode 100644 decisions/0003-infer-types-for-useloaderdata-and-useactiondata-from-loader-and-action-via-generics.md delete mode 100644 decisions/0004-streaming-apis.md delete mode 100644 decisions/0005-remixing-react-router.md delete mode 100644 decisions/0006-linear-workflow.md delete mode 100644 decisions/0007-remix-on-react-router-6-4-0.md delete mode 100644 decisions/0008-only-support-js-conversion-for-app-code.md delete mode 100644 decisions/0009-do-not-rely-on-treeshaking-for-correctness.md delete mode 100644 decisions/0010-splitting-up-client-and-server-code-in-vite.md delete mode 100644 decisions/template.md delete mode 100644 docs/components/await.md delete mode 100644 docs/components/form.md delete mode 100644 docs/components/index.md delete mode 100644 docs/components/link.md delete mode 100644 docs/components/links.md delete mode 100644 docs/components/live-reload.md delete mode 100644 docs/components/meta.md delete mode 100644 docs/components/nav-link.md delete mode 100644 docs/components/outlet.md delete mode 100644 docs/components/prefetch-page-links.md delete mode 100644 docs/components/scripts.md delete mode 100644 docs/components/scroll-restoration.md delete mode 100644 docs/discussion/component-data.md delete mode 100644 docs/discussion/concurrency.md delete mode 100644 docs/discussion/cookies-and-sessions.md delete mode 100644 docs/discussion/data-flow.md delete mode 100644 docs/discussion/error-handling.md delete mode 100644 docs/discussion/form-validation.md delete mode 100644 docs/discussion/form-vs-fetcher.md delete mode 100644 docs/discussion/formdata.md delete mode 100644 docs/discussion/hot-module-replacement.md delete mode 100644 docs/discussion/html-forms.md delete mode 100644 docs/discussion/index.md delete mode 100644 docs/discussion/introduction.md delete mode 100644 docs/discussion/multiple-forms.md delete mode 100644 docs/discussion/nested-routes.md delete mode 100644 docs/discussion/pending-ui.md delete mode 100644 docs/discussion/progressive-enhancement.md delete mode 100644 docs/discussion/react-router.md delete mode 100644 docs/discussion/resubmissions.md delete mode 100644 docs/discussion/routes.md delete mode 100644 docs/discussion/runtimes.md delete mode 100644 docs/discussion/server-vs-client.md delete mode 100644 docs/discussion/state-management.md delete mode 100644 docs/discussion/testing.md delete mode 100644 docs/file-conventions/-client.md delete mode 100644 docs/file-conventions/-server.md delete mode 100644 docs/file-conventions/asset-imports.md delete mode 100644 docs/file-conventions/entry.client.md delete mode 100644 docs/file-conventions/entry.server.md delete mode 100644 docs/file-conventions/index.md delete mode 100644 docs/file-conventions/remix-config.md delete mode 100644 docs/file-conventions/root.md delete mode 100644 docs/file-conventions/routes.md delete mode 100644 docs/file-conventions/vite-config.md delete mode 100644 docs/guides/accessibility.md delete mode 100644 docs/guides/api-development-strategy.md delete mode 100644 docs/guides/api-routes.md delete mode 100644 docs/guides/authentication.md delete mode 100644 docs/guides/bff.md delete mode 100644 docs/guides/breadcrumbs.md delete mode 100644 docs/guides/browser-support.md delete mode 100644 docs/guides/cache-control.md delete mode 100644 docs/guides/client-data.md delete mode 100644 docs/guides/concurrent-submissions.md delete mode 100644 docs/guides/constraints.md delete mode 100644 docs/guides/contributing.md delete mode 100644 docs/guides/css-files.md delete mode 100644 docs/guides/data-loading.md delete mode 100644 docs/guides/data-writes.md delete mode 100644 docs/guides/debugging.md delete mode 100644 docs/guides/dependency-optimization.md delete mode 100644 docs/guides/deployment.md delete mode 100644 docs/guides/disabling-javascript.md delete mode 100644 docs/guides/envvars.md delete mode 100644 docs/guides/errors.md delete mode 100644 docs/guides/faq.md delete mode 100644 docs/guides/file-uploads.md delete mode 100644 docs/guides/form-validation.md delete mode 100644 docs/guides/gotchas.md delete mode 100644 docs/guides/images.md delete mode 100644 docs/guides/index-query-param.md delete mode 100644 docs/guides/index.md delete mode 100644 docs/guides/lazy-route-discovery.md delete mode 100644 docs/guides/local-tls.md delete mode 100644 docs/guides/manual-mode.md delete mode 100644 docs/guides/mdx.md delete mode 100644 docs/guides/meta.md delete mode 100644 docs/guides/migrating-react-router-app.md delete mode 100644 docs/guides/not-found.md delete mode 100644 docs/guides/performance.md delete mode 100644 docs/guides/presets.md delete mode 100644 docs/guides/progressive-enhancement.md delete mode 100644 docs/guides/resource-routes.md delete mode 100644 docs/guides/server-bundles.md delete mode 100644 docs/guides/single-fetch.md delete mode 100644 docs/guides/spa-mode.md delete mode 100644 docs/guides/streaming.md delete mode 100644 docs/guides/templates.md delete mode 100644 docs/guides/typescript.md delete mode 100644 docs/guides/vite.md delete mode 100644 docs/hooks/index.md delete mode 100644 docs/hooks/use-action-data.md delete mode 100644 docs/hooks/use-async-error.md delete mode 100644 docs/hooks/use-async-value.md delete mode 100644 docs/hooks/use-before-unload.md delete mode 100644 docs/hooks/use-blocker.md delete mode 100644 docs/hooks/use-fetcher.md delete mode 100644 docs/hooks/use-fetchers.md delete mode 100644 docs/hooks/use-form-action.md delete mode 100644 docs/hooks/use-href.md delete mode 100644 docs/hooks/use-loader-data.md delete mode 100644 docs/hooks/use-location.md delete mode 100644 docs/hooks/use-matches.md delete mode 100644 docs/hooks/use-navigate.md delete mode 100644 docs/hooks/use-navigation-type.md delete mode 100644 docs/hooks/use-navigation.md delete mode 100644 docs/hooks/use-outlet-context.md delete mode 100644 docs/hooks/use-outlet.md delete mode 100644 docs/hooks/use-params.md delete mode 100644 docs/hooks/use-prompt.md delete mode 100644 docs/hooks/use-resolved-path.md delete mode 100644 docs/hooks/use-revalidator.md delete mode 100644 docs/hooks/use-route-error.md delete mode 100644 docs/hooks/use-route-loader-data.md delete mode 100644 docs/hooks/use-search-params.md delete mode 100644 docs/hooks/use-submit.md delete mode 100644 docs/hooks/use-view-transition-state.md delete mode 100644 docs/index.md delete mode 100644 docs/other-api/adapter.md delete mode 100644 docs/other-api/create-remix.md delete mode 100644 docs/other-api/dev.md delete mode 100644 docs/other-api/index.md delete mode 100644 docs/other-api/node.md delete mode 100644 docs/other-api/serve.md delete mode 100644 docs/other-api/testing.md delete mode 100644 docs/prettier.config.js delete mode 100644 docs/route/action.md delete mode 100644 docs/route/client-action.md delete mode 100644 docs/route/client-loader.md delete mode 100644 docs/route/component.md delete mode 100644 docs/route/error-boundary.md delete mode 100644 docs/route/handle.md delete mode 100644 docs/route/headers.md delete mode 100644 docs/route/hydrate-fallback.md delete mode 100644 docs/route/index.md delete mode 100644 docs/route/links.md delete mode 100644 docs/route/loader.md delete mode 100644 docs/route/meta.md delete mode 100644 docs/route/should-revalidate.md delete mode 100644 docs/start/changelog.md delete mode 100644 docs/start/community.md delete mode 100644 docs/start/future-flags.md delete mode 100644 docs/start/index.md delete mode 100644 docs/start/quickstart.md delete mode 100644 docs/start/tutorial.md delete mode 100644 docs/start/v2.md delete mode 100644 docs/styling/bundling.md delete mode 100644 docs/styling/css-imports.md delete mode 100644 docs/styling/css-in-js.md delete mode 100644 docs/styling/css-modules.md delete mode 100644 docs/styling/css.md delete mode 100644 docs/styling/index.md delete mode 100644 docs/styling/postcss.md delete mode 100644 docs/styling/tailwind.md delete mode 100644 docs/styling/vanilla-extract.md delete mode 100644 docs/tutorials/blog.md delete mode 100644 docs/tutorials/index.md delete mode 100644 docs/tutorials/jokes.md delete mode 100644 docs/utils/cookies.md delete mode 100644 docs/utils/create-remix-stub.md delete mode 100644 docs/utils/data.md delete mode 100644 docs/utils/defer.md delete mode 100644 docs/utils/index.md delete mode 100644 docs/utils/is-route-error-response.md delete mode 100644 docs/utils/json.md delete mode 100644 docs/utils/parse-multipart-form-data.md delete mode 100644 docs/utils/redirect.md delete mode 100644 docs/utils/redirectDocument.md delete mode 100644 docs/utils/replace.md delete mode 100644 docs/utils/sessions.md delete mode 100644 docs/utils/unstable-create-file-upload-handler.md delete mode 100644 docs/utils/unstable-create-memory-upload-handler.md delete mode 100644 examples/README.md delete mode 100644 integration/CHANGELOG.md delete mode 100644 integration/abort-signal-test.ts delete mode 100644 integration/action-test.ts delete mode 100644 integration/assets/toupload.txt delete mode 100644 integration/assets/touploadtoobig.txt delete mode 100644 integration/blocking-test.ts delete mode 100644 integration/browser-entry-test.ts delete mode 100644 integration/bug-report-test.ts delete mode 100644 integration/catch-boundary-data-test.ts delete mode 100644 integration/catch-boundary-test.ts delete mode 100644 integration/cf-compiler-test.ts delete mode 100644 integration/client-data-test.ts delete mode 100644 integration/compiler-mjs-cjs-output-test.ts delete mode 100644 integration/compiler-test.ts delete mode 100644 integration/css-modules-test.ts delete mode 100644 integration/css-side-effect-imports-test.ts delete mode 100644 integration/custom-entry-server-test.ts delete mode 100644 integration/defer-loader-test.ts delete mode 100644 integration/defer-test.ts delete mode 100644 integration/deno-compiler-test.ts delete mode 100644 integration/deterministic-build-output-test.ts delete mode 100644 integration/error-boundary-test.ts delete mode 100644 integration/error-boundary-v2-test.ts delete mode 100644 integration/error-data-request-test.ts delete mode 100644 integration/error-sanitization-test.ts delete mode 100644 integration/fetch-globals-test.ts delete mode 100644 integration/fetcher-layout-test.ts delete mode 100644 integration/fetcher-test.ts delete mode 100644 integration/file-uploads-test.ts delete mode 100644 integration/flat-routes-test.ts delete mode 100644 integration/fog-of-war-test.ts delete mode 100644 integration/form-data-test.ts delete mode 100644 integration/form-test.ts delete mode 100644 integration/headers-test.ts delete mode 100644 integration/helpers/cf-template/.gitignore delete mode 100644 integration/helpers/cf-template/app/root.tsx delete mode 100644 integration/helpers/cf-template/app/routes/_index.tsx delete mode 100644 integration/helpers/cf-template/package.json delete mode 100644 integration/helpers/cf-template/public/favicon.ico delete mode 100644 integration/helpers/cf-template/remix.config.js delete mode 100644 integration/helpers/cf-template/remix.env.d.ts delete mode 100644 integration/helpers/cf-template/server.ts delete mode 100644 integration/helpers/cf-template/tsconfig.json delete mode 100644 integration/helpers/cf-template/wrangler.toml delete mode 100644 integration/helpers/cleanup.mjs delete mode 100644 integration/helpers/create-fixture.ts delete mode 100644 integration/helpers/deno-template/.gitignore delete mode 100644 integration/helpers/deno-template/app/root.tsx delete mode 100644 integration/helpers/deno-template/app/routes/_index.tsx delete mode 100644 integration/helpers/deno-template/package.json delete mode 100644 integration/helpers/deno-template/public/favicon.ico delete mode 100644 integration/helpers/deno-template/remix.config.js delete mode 100644 integration/helpers/deno-template/server.ts delete mode 100644 integration/helpers/killtree.ts delete mode 100644 integration/helpers/node-template/.gitignore delete mode 100644 integration/helpers/node-template/app/root.tsx delete mode 100644 integration/helpers/node-template/app/routes/_index.tsx delete mode 100644 integration/helpers/node-template/package.json delete mode 100644 integration/helpers/node-template/public/favicon.ico delete mode 100644 integration/helpers/node-template/remix.config.js delete mode 100644 integration/helpers/node-template/remix.env.d.ts delete mode 100644 integration/helpers/node-template/tsconfig.json delete mode 100644 integration/helpers/playwright-fixture.ts delete mode 100644 integration/helpers/vite-5-template/.gitignore delete mode 100644 integration/helpers/vite-5-template/app/root.tsx delete mode 100644 integration/helpers/vite-5-template/app/routes/_index.tsx delete mode 100644 integration/helpers/vite-5-template/env.d.ts delete mode 100644 integration/helpers/vite-5-template/package.json delete mode 100644 integration/helpers/vite-5-template/public/favicon.ico delete mode 100644 integration/helpers/vite-5-template/tsconfig.json delete mode 100644 integration/helpers/vite-5-template/vite.config.ts delete mode 100644 integration/helpers/vite-6-template/.gitignore delete mode 100644 integration/helpers/vite-6-template/app/root.tsx delete mode 100644 integration/helpers/vite-6-template/app/routes/_index.tsx delete mode 100644 integration/helpers/vite-6-template/env.d.ts delete mode 100644 integration/helpers/vite-6-template/package.json delete mode 100644 integration/helpers/vite-6-template/public/favicon.ico delete mode 100644 integration/helpers/vite-6-template/tsconfig.json delete mode 100644 integration/helpers/vite-6-template/vite.config.ts delete mode 100644 integration/helpers/vite-cloudflare-template/.gitignore delete mode 100644 integration/helpers/vite-cloudflare-template/app/root.tsx delete mode 100644 integration/helpers/vite-cloudflare-template/app/routes/_index.tsx delete mode 100644 integration/helpers/vite-cloudflare-template/env.d.ts delete mode 100644 integration/helpers/vite-cloudflare-template/package.json delete mode 100644 integration/helpers/vite-cloudflare-template/public/favicon.ico delete mode 100644 integration/helpers/vite-cloudflare-template/tsconfig.json delete mode 100644 integration/helpers/vite-cloudflare-template/vite.config.ts delete mode 100644 integration/helpers/vite.ts delete mode 100644 integration/hmr-test.ts delete mode 100644 integration/hook-useSubmit-test.ts delete mode 100644 integration/js-routes-test.ts delete mode 100644 integration/layout-route-test.ts delete mode 100644 integration/link-test.ts delete mode 100644 integration/loader-test.ts delete mode 100644 integration/matches-test.ts delete mode 100644 integration/mdx-test.ts delete mode 100644 integration/multiple-cookies-test.ts delete mode 100644 integration/navigation-state-test.ts delete mode 100644 integration/package.json delete mode 100644 integration/path-mapping-test.ts delete mode 100644 integration/playwright.config.ts delete mode 100644 integration/postcss-test.ts delete mode 100644 integration/prefetch-test.ts delete mode 100644 integration/redirects-test.ts delete mode 100644 integration/remix-serve-test.ts delete mode 100644 integration/rendering-test.ts delete mode 100644 integration/request-test.ts delete mode 100644 integration/resource-routes-test.ts delete mode 100644 integration/revalidate-test.ts delete mode 100644 integration/root-route-test.ts delete mode 100644 integration/route-collisions-test.ts delete mode 100644 integration/scroll-test.ts delete mode 100644 integration/server-code-in-browser-message-test.ts delete mode 100644 integration/server-entry-test.ts delete mode 100644 integration/server-source-maps-test.ts delete mode 100644 integration/set-cookie-revalidation-test.ts delete mode 100644 integration/shared-route-imports-test.ts delete mode 100644 integration/single-fetch-test.ts delete mode 100644 integration/splat-routes-test.ts delete mode 100644 integration/svg-in-node-modules-test.ts delete mode 100644 integration/tailwind-test.ts delete mode 100644 integration/transition-test.ts delete mode 100644 integration/tsconfig.json delete mode 100644 integration/upload-test.ts delete mode 100644 integration/vanilla-extract-test.ts delete mode 100644 integration/vite-absolute-base-test.ts delete mode 100644 integration/vite-basename-test.ts delete mode 100644 integration/vite-build-test.ts delete mode 100644 integration/vite-cloudflare-test.ts delete mode 100644 integration/vite-css-test.ts delete mode 100644 integration/vite-dev-custom-entry-test.ts delete mode 100644 integration/vite-dev-test.ts delete mode 100644 integration/vite-dot-client-test.ts delete mode 100644 integration/vite-dot-server-test.ts delete mode 100644 integration/vite-dotenv-test.ts delete mode 100644 integration/vite-fs-routes-test.ts delete mode 100644 integration/vite-hmr-hdr-test.ts delete mode 100644 integration/vite-loader-context-test.ts delete mode 100644 integration/vite-manifests-test.ts delete mode 100644 integration/vite-node-env-test.ts delete mode 100644 integration/vite-plugin-order-validation-test.ts delete mode 100644 integration/vite-presets-test.ts delete mode 100644 integration/vite-route-added-test.ts delete mode 100644 integration/vite-route-config-test.ts delete mode 100644 integration/vite-route-exports-modified-offscreen-test.ts delete mode 100644 integration/vite-server-bundles-test.ts delete mode 100644 integration/vite-server-fs-allow-test.ts delete mode 100644 integration/vite-spa-mode-test.ts delete mode 100644 integration/vite-unused-route-exports-test.ts delete mode 100644 jest.config.js delete mode 100644 jest/buildRemix.js delete mode 100644 jest/jest.config.shared.js delete mode 100644 jest/transform.js delete mode 100644 package.json delete mode 100644 packages/ADDING_A_PACKAGE.md delete mode 100644 packages/create-remix/.eslintrc.js delete mode 100644 packages/create-remix/CHANGELOG.md delete mode 100644 packages/create-remix/README.md delete mode 100644 packages/create-remix/__tests__/create-remix-test.ts delete mode 100644 packages/create-remix/__tests__/fixtures/arc.tar.gz delete mode 100644 packages/create-remix/__tests__/fixtures/arc.tgz delete mode 100644 packages/create-remix/__tests__/fixtures/blank/package.json delete mode 100644 packages/create-remix/__tests__/fixtures/examples-main.tar.gz delete mode 100644 packages/create-remix/__tests__/fixtures/failing-remix-init/package.json delete mode 100644 packages/create-remix/__tests__/fixtures/failing-remix-init/remix.init/index.js delete mode 100644 packages/create-remix/__tests__/fixtures/nested-dir-repo.tar.gz delete mode 100644 packages/create-remix/__tests__/fixtures/remix-repo.tar.gz delete mode 100644 packages/create-remix/__tests__/fixtures/stack.tar.gz delete mode 100644 packages/create-remix/__tests__/fixtures/stack/.gitignore delete mode 100644 packages/create-remix/__tests__/fixtures/stack/README.md delete mode 100644 packages/create-remix/__tests__/fixtures/stack/app/entry.client.tsx delete mode 100644 packages/create-remix/__tests__/fixtures/stack/app/entry.server.tsx delete mode 100644 packages/create-remix/__tests__/fixtures/stack/app/root.tsx delete mode 100644 packages/create-remix/__tests__/fixtures/stack/app/utils.ts delete mode 100644 packages/create-remix/__tests__/fixtures/stack/package.json delete mode 100644 packages/create-remix/__tests__/fixtures/stack/public/favicon.ico delete mode 100644 packages/create-remix/__tests__/fixtures/stack/remix.config.js delete mode 100644 packages/create-remix/__tests__/fixtures/stack/remix.env.d.ts delete mode 100644 packages/create-remix/__tests__/fixtures/stack/remix.init/index.js delete mode 100644 packages/create-remix/__tests__/fixtures/stack/tsconfig.json delete mode 100644 packages/create-remix/__tests__/fixtures/successful-remix-init/package.json delete mode 100644 packages/create-remix/__tests__/fixtures/successful-remix-init/remix.init/index.js delete mode 100644 packages/create-remix/__tests__/fixtures/tar.js delete mode 100644 packages/create-remix/__tests__/fixtures/with-ignored-dir/package.json delete mode 100644 packages/create-remix/__tests__/github-mocks.ts delete mode 100644 packages/create-remix/__tests__/msw-register.ts delete mode 100644 packages/create-remix/__tests__/msw.ts delete mode 100644 packages/create-remix/__tests__/setupAfterEnv.ts delete mode 100644 packages/create-remix/cli.ts delete mode 100644 packages/create-remix/copy-template.ts delete mode 100644 packages/create-remix/index.ts delete mode 100644 packages/create-remix/jest.config.js delete mode 100644 packages/create-remix/loading-indicator.ts delete mode 100644 packages/create-remix/package.json delete mode 100644 packages/create-remix/prompt.ts delete mode 100644 packages/create-remix/prompts-confirm.ts delete mode 100644 packages/create-remix/prompts-multi-select.ts delete mode 100644 packages/create-remix/prompts-prompt-base.ts delete mode 100644 packages/create-remix/prompts-select.ts delete mode 100644 packages/create-remix/prompts-text.ts delete mode 100644 packages/create-remix/rollup.config.js delete mode 100644 packages/create-remix/tsconfig.json delete mode 100644 packages/create-remix/utils.ts delete mode 100644 packages/remix-architect/CHANGELOG.md delete mode 100644 packages/remix-architect/README.md delete mode 100644 packages/remix-architect/__tests__/554828.jpeg delete mode 100644 packages/remix-architect/__tests__/binaryTypes-test.ts delete mode 100644 packages/remix-architect/__tests__/server-test.ts delete mode 100644 packages/remix-architect/__tests__/setup.ts delete mode 100644 packages/remix-architect/binaryTypes.ts delete mode 100644 packages/remix-architect/index.ts delete mode 100644 packages/remix-architect/jest.config.js delete mode 100644 packages/remix-architect/package.json delete mode 100644 packages/remix-architect/rollup.config.js delete mode 100644 packages/remix-architect/server.ts delete mode 100644 packages/remix-architect/sessions/arcTableSessionStorage.ts delete mode 100644 packages/remix-architect/tsconfig.json delete mode 100644 packages/remix-cloudflare-pages/CHANGELOG.md delete mode 100644 packages/remix-cloudflare-pages/README.md delete mode 100644 packages/remix-cloudflare-pages/index.ts delete mode 100644 packages/remix-cloudflare-pages/package.json delete mode 100644 packages/remix-cloudflare-pages/rollup.config.js delete mode 100644 packages/remix-cloudflare-pages/tsconfig.json delete mode 100644 packages/remix-cloudflare-pages/worker.ts delete mode 100644 packages/remix-cloudflare-workers/CHANGELOG.md delete mode 100644 packages/remix-cloudflare-workers/README.md delete mode 100644 packages/remix-cloudflare-workers/index.ts delete mode 100644 packages/remix-cloudflare-workers/package.json delete mode 100644 packages/remix-cloudflare-workers/rollup.config.js delete mode 100644 packages/remix-cloudflare-workers/tsconfig.json delete mode 100644 packages/remix-cloudflare-workers/worker.ts delete mode 100644 packages/remix-cloudflare/CHANGELOG.md delete mode 100644 packages/remix-cloudflare/crypto.ts delete mode 100644 packages/remix-cloudflare/globals.ts delete mode 100644 packages/remix-cloudflare/implementations.ts delete mode 100644 packages/remix-cloudflare/index.ts delete mode 100644 packages/remix-cloudflare/package.json delete mode 100644 packages/remix-cloudflare/rollup.config.js delete mode 100644 packages/remix-cloudflare/sessions/workersKVStorage.ts delete mode 100644 packages/remix-cloudflare/tsconfig.json delete mode 100644 packages/remix-css-bundle/CHANGELOG.md delete mode 100644 packages/remix-css-bundle/README.md delete mode 100644 packages/remix-css-bundle/index.ts delete mode 100644 packages/remix-css-bundle/package.json delete mode 100644 packages/remix-css-bundle/rollup.config.js delete mode 100644 packages/remix-css-bundle/tsconfig.json delete mode 100644 packages/remix-deno/.empty.js delete mode 100644 packages/remix-deno/CHANGELOG.md delete mode 100644 packages/remix-deno/README.md delete mode 100644 packages/remix-deno/crypto.ts delete mode 100644 packages/remix-deno/globals.ts delete mode 100644 packages/remix-deno/implementations.ts delete mode 100644 packages/remix-deno/index.ts delete mode 100644 packages/remix-deno/package.json delete mode 100644 packages/remix-deno/rollup.config.js delete mode 100644 packages/remix-deno/server.ts delete mode 100644 packages/remix-deno/sessions/fileStorage.ts delete mode 100644 packages/remix-dev/.gitignore delete mode 100644 packages/remix-dev/CHANGELOG.md delete mode 100644 packages/remix-dev/README.md delete mode 100644 packages/remix-dev/__tests__/cli-test.ts delete mode 100644 packages/remix-dev/__tests__/cssSideEffectImports-test.ts delete mode 100644 packages/remix-dev/__tests__/defineRoutes-test.ts delete mode 100644 packages/remix-dev/__tests__/fixtures/cloudflare/.gitignore delete mode 100644 packages/remix-dev/__tests__/fixtures/cloudflare/.node-version delete mode 100644 packages/remix-dev/__tests__/fixtures/cloudflare/README.md delete mode 100644 packages/remix-dev/__tests__/fixtures/cloudflare/app/root.tsx delete mode 100644 packages/remix-dev/__tests__/fixtures/cloudflare/app/routes/_index.tsx delete mode 100644 packages/remix-dev/__tests__/fixtures/cloudflare/package.json delete mode 100644 packages/remix-dev/__tests__/fixtures/cloudflare/public/_headers delete mode 100644 packages/remix-dev/__tests__/fixtures/cloudflare/public/_routes.json delete mode 100644 packages/remix-dev/__tests__/fixtures/cloudflare/public/favicon.ico delete mode 100644 packages/remix-dev/__tests__/fixtures/cloudflare/remix.config.js delete mode 100644 packages/remix-dev/__tests__/fixtures/cloudflare/remix.env.d.ts delete mode 100644 packages/remix-dev/__tests__/fixtures/cloudflare/server.ts delete mode 100644 packages/remix-dev/__tests__/fixtures/cloudflare/tsconfig.json delete mode 100644 packages/remix-dev/__tests__/fixtures/deno/.gitignore delete mode 100644 packages/remix-dev/__tests__/fixtures/deno/.vscode/extensions.json delete mode 100644 packages/remix-dev/__tests__/fixtures/deno/.vscode/resolve_npm_imports.json delete mode 100644 packages/remix-dev/__tests__/fixtures/deno/.vscode/settings.json delete mode 100644 packages/remix-dev/__tests__/fixtures/deno/README.md delete mode 100644 packages/remix-dev/__tests__/fixtures/deno/app/root.tsx delete mode 100644 packages/remix-dev/__tests__/fixtures/deno/app/routes/_index.tsx delete mode 100644 packages/remix-dev/__tests__/fixtures/deno/deno.json delete mode 100644 packages/remix-dev/__tests__/fixtures/deno/package.json delete mode 100644 packages/remix-dev/__tests__/fixtures/deno/public/favicon.ico delete mode 100644 packages/remix-dev/__tests__/fixtures/deno/remix.config.js delete mode 100644 packages/remix-dev/__tests__/fixtures/deno/server.ts delete mode 100644 packages/remix-dev/__tests__/fixtures/examples-main.tar.gz delete mode 100644 packages/remix-dev/__tests__/fixtures/failing-remix-init/package.json delete mode 100644 packages/remix-dev/__tests__/fixtures/failing-remix-init/remix.init/index.js delete mode 100644 packages/remix-dev/__tests__/fixtures/nested-dir-repo.tar.gz delete mode 100644 packages/remix-dev/__tests__/fixtures/node/.gitignore delete mode 100644 packages/remix-dev/__tests__/fixtures/node/README.md delete mode 100644 packages/remix-dev/__tests__/fixtures/node/app/root.tsx delete mode 100644 packages/remix-dev/__tests__/fixtures/node/app/routes/_index.tsx delete mode 100644 packages/remix-dev/__tests__/fixtures/node/package.json delete mode 100644 packages/remix-dev/__tests__/fixtures/node/public/favicon.ico delete mode 100644 packages/remix-dev/__tests__/fixtures/node/remix.config.js delete mode 100644 packages/remix-dev/__tests__/fixtures/node/remix.env.d.ts delete mode 100644 packages/remix-dev/__tests__/fixtures/node/tsconfig.json delete mode 100644 packages/remix-dev/__tests__/fixtures/remix-repo.tar.gz delete mode 100644 packages/remix-dev/__tests__/fixtures/stack.tar.gz delete mode 100644 packages/remix-dev/__tests__/fixtures/stack/.gitignore delete mode 100644 packages/remix-dev/__tests__/fixtures/stack/README.md delete mode 100644 packages/remix-dev/__tests__/fixtures/stack/app/entry.client.tsx delete mode 100644 packages/remix-dev/__tests__/fixtures/stack/app/entry.server.tsx delete mode 100644 packages/remix-dev/__tests__/fixtures/stack/app/root.tsx delete mode 100644 packages/remix-dev/__tests__/fixtures/stack/app/utils.ts delete mode 100644 packages/remix-dev/__tests__/fixtures/stack/package.json delete mode 100644 packages/remix-dev/__tests__/fixtures/stack/public/favicon.ico delete mode 100644 packages/remix-dev/__tests__/fixtures/stack/remix.config.js delete mode 100644 packages/remix-dev/__tests__/fixtures/stack/remix.env.d.ts delete mode 100644 packages/remix-dev/__tests__/fixtures/stack/remix.init/index.js delete mode 100644 packages/remix-dev/__tests__/fixtures/stack/tsconfig.json delete mode 100644 packages/remix-dev/__tests__/fixtures/successful-remix-init/package.json delete mode 100644 packages/remix-dev/__tests__/fixtures/successful-remix-init/remix.init/index.js delete mode 100644 packages/remix-dev/__tests__/fixtures/tar.js delete mode 100644 packages/remix-dev/__tests__/flat-routes-test.ts delete mode 100644 packages/remix-dev/__tests__/github-mocks.ts delete mode 100644 packages/remix-dev/__tests__/init-test.ts delete mode 100644 packages/remix-dev/__tests__/msw.ts delete mode 100644 packages/remix-dev/__tests__/readConfig-test.ts delete mode 100644 packages/remix-dev/__tests__/reveal-test.ts delete mode 100644 packages/remix-dev/__tests__/routeManifestToRouteConfig-test.ts delete mode 100644 packages/remix-dev/__tests__/setupAfterEnv.ts delete mode 100644 packages/remix-dev/__tests__/styles-test.ts delete mode 100644 packages/remix-dev/__tests__/utils/captureError.ts delete mode 100644 packages/remix-dev/__tests__/utils/cli.ts delete mode 100644 packages/remix-dev/__tests__/utils/eol.ts delete mode 100644 packages/remix-dev/__tests__/utils/git.ts delete mode 100644 packages/remix-dev/__tests__/utils/withApp.ts delete mode 100644 packages/remix-dev/__tests__/validateRouteConfig-test.ts delete mode 100644 packages/remix-dev/assets-manifest.d.ts delete mode 100644 packages/remix-dev/cache.ts delete mode 100644 packages/remix-dev/channel.ts delete mode 100644 packages/remix-dev/cli.ts delete mode 100644 packages/remix-dev/cli/commands.ts delete mode 100644 packages/remix-dev/cli/detectPackageManager.ts delete mode 100644 packages/remix-dev/cli/index.ts delete mode 100644 packages/remix-dev/cli/run.ts delete mode 100644 packages/remix-dev/cli/useJavascript.ts delete mode 100644 packages/remix-dev/colors.ts delete mode 100644 packages/remix-dev/compiler/analysis.ts delete mode 100644 packages/remix-dev/compiler/build.ts delete mode 100644 packages/remix-dev/compiler/cancel.ts delete mode 100644 packages/remix-dev/compiler/compiler.ts delete mode 100644 packages/remix-dev/compiler/context.ts delete mode 100644 packages/remix-dev/compiler/css/bundle.ts delete mode 100644 packages/remix-dev/compiler/css/compiler.ts delete mode 100644 packages/remix-dev/compiler/css/index.ts delete mode 100644 packages/remix-dev/compiler/css/plugins/bundleEntry.ts delete mode 100644 packages/remix-dev/compiler/fileWatchCache.ts delete mode 100644 packages/remix-dev/compiler/index.ts delete mode 100644 packages/remix-dev/compiler/js/compiler.ts delete mode 100644 packages/remix-dev/compiler/js/index.ts delete mode 100644 packages/remix-dev/compiler/js/plugins/browserNodeBuiltinsPolyfill.ts delete mode 100644 packages/remix-dev/compiler/js/plugins/hmr.ts delete mode 100644 packages/remix-dev/compiler/js/plugins/routes.ts delete mode 100644 packages/remix-dev/compiler/js/write.ts delete mode 100644 packages/remix-dev/compiler/lazyValue.ts delete mode 100644 packages/remix-dev/compiler/manifest.ts delete mode 100644 packages/remix-dev/compiler/options.ts delete mode 100644 packages/remix-dev/compiler/plugins/absoluteCssUrlsPlugin.ts delete mode 100644 packages/remix-dev/compiler/plugins/cssBundlePlugin.ts delete mode 100644 packages/remix-dev/compiler/plugins/cssImports.ts delete mode 100644 packages/remix-dev/compiler/plugins/cssModuleImports.ts delete mode 100644 packages/remix-dev/compiler/plugins/cssSideEffectImports.ts delete mode 100644 packages/remix-dev/compiler/plugins/emptyModules.ts delete mode 100644 packages/remix-dev/compiler/plugins/external.ts delete mode 100644 packages/remix-dev/compiler/plugins/mdx.ts delete mode 100644 packages/remix-dev/compiler/plugins/vanillaExtract.ts delete mode 100644 packages/remix-dev/compiler/server/compiler.ts delete mode 100644 packages/remix-dev/compiler/server/index.ts delete mode 100644 packages/remix-dev/compiler/server/plugins/bareImports.ts delete mode 100644 packages/remix-dev/compiler/server/plugins/entry.ts delete mode 100644 packages/remix-dev/compiler/server/plugins/manifest.ts delete mode 100644 packages/remix-dev/compiler/server/plugins/routes.ts delete mode 100644 packages/remix-dev/compiler/server/plugins/serverNodeBuiltinsPolyfill.ts delete mode 100644 packages/remix-dev/compiler/server/virtualModules.ts delete mode 100644 packages/remix-dev/compiler/server/write.ts delete mode 100644 packages/remix-dev/compiler/utils/crypto.ts delete mode 100644 packages/remix-dev/compiler/utils/loaders.ts delete mode 100644 packages/remix-dev/compiler/utils/log.ts delete mode 100644 packages/remix-dev/compiler/utils/postcss.ts delete mode 100644 packages/remix-dev/compiler/utils/routeExports.ts delete mode 100644 packages/remix-dev/compiler/utils/tsconfig.ts delete mode 100644 packages/remix-dev/compiler/watch.ts delete mode 100644 packages/remix-dev/config.ts delete mode 100644 packages/remix-dev/config/defaults/entry.client.tsx delete mode 100644 packages/remix-dev/config/defaults/entry.dev.ts delete mode 100644 packages/remix-dev/config/defaults/entry.server.cloudflare.tsx delete mode 100644 packages/remix-dev/config/defaults/entry.server.deno.tsx delete mode 100644 packages/remix-dev/config/defaults/entry.server.node.tsx delete mode 100644 packages/remix-dev/config/defaults/entry.server.spa.tsx delete mode 100644 packages/remix-dev/config/flat-routes.ts delete mode 100644 packages/remix-dev/config/format.ts delete mode 100644 packages/remix-dev/config/routes.ts delete mode 100644 packages/remix-dev/config/serverModes.ts delete mode 100644 packages/remix-dev/dependencies.ts delete mode 100644 packages/remix-dev/devServer/index.ts delete mode 100644 packages/remix-dev/devServer/liveReload.ts delete mode 100644 packages/remix-dev/devServer_unstable/env.ts delete mode 100644 packages/remix-dev/devServer_unstable/hdr.ts delete mode 100644 packages/remix-dev/devServer_unstable/hmr.ts delete mode 100644 packages/remix-dev/devServer_unstable/index.ts delete mode 100644 packages/remix-dev/devServer_unstable/proc.ts delete mode 100644 packages/remix-dev/devServer_unstable/socket.ts delete mode 100644 packages/remix-dev/index.ts delete mode 100644 packages/remix-dev/invariant.ts delete mode 100644 packages/remix-dev/jest.config.js delete mode 100644 packages/remix-dev/manifest.ts delete mode 100644 packages/remix-dev/modules.ts delete mode 100644 packages/remix-dev/package.json delete mode 100644 packages/remix-dev/result.ts delete mode 100644 packages/remix-dev/rollup.config.js delete mode 100644 packages/remix-dev/server-build.ts delete mode 100644 packages/remix-dev/tsconfig.json delete mode 100644 packages/remix-dev/tux/format.ts delete mode 100644 packages/remix-dev/tux/index.ts delete mode 100644 packages/remix-dev/tux/logger.ts delete mode 100644 packages/remix-dev/vite/babel.ts delete mode 100644 packages/remix-dev/vite/build.ts delete mode 100644 packages/remix-dev/vite/cloudflare-proxy-plugin.ts delete mode 100644 packages/remix-dev/vite/combine-urls-test.ts delete mode 100644 packages/remix-dev/vite/combine-urls.ts delete mode 100644 packages/remix-dev/vite/dev.ts delete mode 100644 packages/remix-dev/vite/index.ts delete mode 100644 packages/remix-dev/vite/is-in-remix-monorepo.ts delete mode 100644 packages/remix-dev/vite/node-adapter.ts delete mode 100644 packages/remix-dev/vite/plugin.ts delete mode 100644 packages/remix-dev/vite/profiler.ts delete mode 100644 packages/remix-dev/vite/remove-exports-test.ts delete mode 100644 packages/remix-dev/vite/remove-exports.ts delete mode 100644 packages/remix-dev/vite/resolve-file-url.ts delete mode 100644 packages/remix-dev/vite/ssr-externals.ts delete mode 100644 packages/remix-dev/vite/static/refresh-utils.cjs delete mode 100644 packages/remix-dev/vite/styles.ts delete mode 100644 packages/remix-dev/vite/vite-node.ts delete mode 100644 packages/remix-dev/vite/vite.ts delete mode 100644 packages/remix-dev/vite/vmod.ts delete mode 100644 packages/remix-eslint-config/CHANGELOG.md delete mode 100644 packages/remix-eslint-config/README.md delete mode 100644 packages/remix-eslint-config/index.js delete mode 100644 packages/remix-eslint-config/internal.js delete mode 100644 packages/remix-eslint-config/jest-testing-library.js delete mode 100644 packages/remix-eslint-config/node.js delete mode 100644 packages/remix-eslint-config/package.json delete mode 100644 packages/remix-eslint-config/rules/core.js delete mode 100644 packages/remix-eslint-config/rules/import.js delete mode 100644 packages/remix-eslint-config/rules/jest-dom.js delete mode 100644 packages/remix-eslint-config/rules/jest.js delete mode 100644 packages/remix-eslint-config/rules/jsx-a11y.js delete mode 100644 packages/remix-eslint-config/rules/react.js delete mode 100644 packages/remix-eslint-config/rules/testing-library.js delete mode 100644 packages/remix-eslint-config/rules/typescript.js delete mode 100644 packages/remix-eslint-config/settings/import.js delete mode 100644 packages/remix-eslint-config/settings/react.js delete mode 100644 packages/remix-express/CHANGELOG.md delete mode 100644 packages/remix-express/README.md delete mode 100644 packages/remix-express/__tests__/server-test.ts delete mode 100644 packages/remix-express/__tests__/setup.ts delete mode 100644 packages/remix-express/index.ts delete mode 100644 packages/remix-express/jest.config.js delete mode 100644 packages/remix-express/package.json delete mode 100644 packages/remix-express/rollup.config.js delete mode 100644 packages/remix-express/server.ts delete mode 100644 packages/remix-express/tsconfig.json delete mode 100644 packages/remix-fs-routes/CHANGELOG.md delete mode 100644 packages/remix-fs-routes/README.md delete mode 100644 packages/remix-fs-routes/index.ts delete mode 100644 packages/remix-fs-routes/package.json delete mode 100644 packages/remix-fs-routes/rollup.config.js delete mode 100644 packages/remix-fs-routes/tsconfig.json delete mode 100644 packages/remix-node/.gitignore delete mode 100644 packages/remix-node/CHANGELOG.md delete mode 100644 packages/remix-node/README.md delete mode 100644 packages/remix-node/__tests__/assets/test.txt delete mode 100644 packages/remix-node/__tests__/fileUploadHandler-test.ts delete mode 100644 packages/remix-node/__tests__/sessions-test.ts delete mode 100644 packages/remix-node/__tests__/setup.ts delete mode 100644 packages/remix-node/__tests__/utils.ts delete mode 100644 packages/remix-node/crypto.ts delete mode 100644 packages/remix-node/globals.ts delete mode 100644 packages/remix-node/implementations.ts delete mode 100644 packages/remix-node/index.ts delete mode 100644 packages/remix-node/install.d.ts delete mode 100644 packages/remix-node/install.js delete mode 100644 packages/remix-node/jest.config.js delete mode 100644 packages/remix-node/package.json delete mode 100644 packages/remix-node/rollup.config.js delete mode 100644 packages/remix-node/sessions/fileStorage.ts delete mode 100644 packages/remix-node/stream.ts delete mode 100644 packages/remix-node/tsconfig.json delete mode 100644 packages/remix-node/upload/fileUploadHandler.ts delete mode 100644 packages/remix-react/CHANGELOG.md delete mode 100644 packages/remix-react/README.md delete mode 100644 packages/remix-react/__tests__/components-test.tsx delete mode 100644 packages/remix-react/__tests__/deferred-scripts-test.tsx delete mode 100644 packages/remix-react/__tests__/exports-test.tsx delete mode 100644 packages/remix-react/__tests__/integration/meta-test.tsx delete mode 100644 packages/remix-react/__tests__/scroll-restoration-test.tsx delete mode 100644 packages/remix-react/__tests__/setup.ts delete mode 100644 packages/remix-react/browser.tsx delete mode 100644 packages/remix-react/components.tsx delete mode 100644 packages/remix-react/data.ts delete mode 100644 packages/remix-react/entry.ts delete mode 100644 packages/remix-react/errorBoundaries.tsx delete mode 100644 packages/remix-react/errors.ts delete mode 100644 packages/remix-react/fallback.tsx delete mode 100644 packages/remix-react/fog-of-war.ts delete mode 100644 packages/remix-react/index.tsx delete mode 100644 packages/remix-react/invariant.ts delete mode 100644 packages/remix-react/jest.config.js delete mode 100644 packages/remix-react/links.ts delete mode 100644 packages/remix-react/markup.ts delete mode 100644 packages/remix-react/package.json delete mode 100644 packages/remix-react/rollup.config.js delete mode 100644 packages/remix-react/routeModules.ts delete mode 100644 packages/remix-react/routes.tsx delete mode 100644 packages/remix-react/scroll-restoration.tsx delete mode 100644 packages/remix-react/server.tsx delete mode 100644 packages/remix-react/single-fetch.tsx delete mode 100644 packages/remix-react/tsconfig.json delete mode 100644 packages/remix-react/warnings.ts delete mode 100644 packages/remix-route-config/CHANGELOG.md delete mode 100644 packages/remix-route-config/README.md delete mode 100644 packages/remix-route-config/__tests__/route-config-test.ts delete mode 100644 packages/remix-route-config/index.ts delete mode 100644 packages/remix-route-config/jest.config.js delete mode 100644 packages/remix-route-config/package.json delete mode 100644 packages/remix-route-config/rollup.config.js delete mode 100644 packages/remix-route-config/routes.ts delete mode 100644 packages/remix-route-config/tsconfig.json delete mode 100644 packages/remix-routes-option-adapter/CHANGELOG.md delete mode 100644 packages/remix-routes-option-adapter/README.md delete mode 100644 packages/remix-routes-option-adapter/index.ts delete mode 100644 packages/remix-routes-option-adapter/package.json delete mode 100644 packages/remix-routes-option-adapter/rollup.config.js delete mode 100644 packages/remix-routes-option-adapter/tsconfig.json delete mode 100644 packages/remix-serve/CHANGELOG.md delete mode 100644 packages/remix-serve/README.md delete mode 100644 packages/remix-serve/cli.ts delete mode 100644 packages/remix-serve/package.json delete mode 100644 packages/remix-serve/rollup.config.js delete mode 100644 packages/remix-serve/tsconfig.json delete mode 100644 packages/remix-server-runtime/.eslintrc.js delete mode 100644 packages/remix-server-runtime/CHANGELOG.md delete mode 100644 packages/remix-server-runtime/README.md delete mode 100644 packages/remix-server-runtime/__tests__/.eslintrc.js delete mode 100644 packages/remix-server-runtime/__tests__/cookies-test.ts delete mode 100644 packages/remix-server-runtime/__tests__/data-test.ts delete mode 100644 packages/remix-server-runtime/__tests__/formData-test.ts delete mode 100644 packages/remix-server-runtime/__tests__/handle-error-test.ts delete mode 100644 packages/remix-server-runtime/__tests__/handler-test.ts delete mode 100644 packages/remix-server-runtime/__tests__/markup-test.ts delete mode 100644 packages/remix-server-runtime/__tests__/responses-test.ts delete mode 100644 packages/remix-server-runtime/__tests__/serialize-test.ts delete mode 100644 packages/remix-server-runtime/__tests__/server-test.ts delete mode 100644 packages/remix-server-runtime/__tests__/sessions-test.ts delete mode 100644 packages/remix-server-runtime/__tests__/setup.ts delete mode 100644 packages/remix-server-runtime/__tests__/utils.ts delete mode 100644 packages/remix-server-runtime/build.ts delete mode 100644 packages/remix-server-runtime/cookies.ts delete mode 100644 packages/remix-server-runtime/crypto.ts delete mode 100644 packages/remix-server-runtime/data.ts delete mode 100644 packages/remix-server-runtime/deprecations.ts delete mode 100644 packages/remix-server-runtime/dev.ts delete mode 100644 packages/remix-server-runtime/entry.ts delete mode 100644 packages/remix-server-runtime/errors.ts delete mode 100644 packages/remix-server-runtime/formData.ts delete mode 100644 packages/remix-server-runtime/future.ts delete mode 100644 packages/remix-server-runtime/headers.ts delete mode 100644 packages/remix-server-runtime/index.ts delete mode 100644 packages/remix-server-runtime/interface.ts delete mode 100644 packages/remix-server-runtime/invariant.ts delete mode 100644 packages/remix-server-runtime/jest.config.js delete mode 100644 packages/remix-server-runtime/jsonify.ts delete mode 100644 packages/remix-server-runtime/links.ts delete mode 100644 packages/remix-server-runtime/markup.ts delete mode 100644 packages/remix-server-runtime/mode.ts delete mode 100644 packages/remix-server-runtime/package.json delete mode 100644 packages/remix-server-runtime/reexport.ts delete mode 100644 packages/remix-server-runtime/responses.ts delete mode 100644 packages/remix-server-runtime/rollup.config.js delete mode 100644 packages/remix-server-runtime/routeMatching.ts delete mode 100644 packages/remix-server-runtime/routeModules.ts delete mode 100644 packages/remix-server-runtime/routes.ts delete mode 100644 packages/remix-server-runtime/serialize.ts delete mode 100644 packages/remix-server-runtime/server.ts delete mode 100644 packages/remix-server-runtime/serverHandoff.ts delete mode 100644 packages/remix-server-runtime/sessions.ts delete mode 100644 packages/remix-server-runtime/sessions/cookieStorage.ts delete mode 100644 packages/remix-server-runtime/sessions/memoryStorage.ts delete mode 100644 packages/remix-server-runtime/single-fetch.ts delete mode 100644 packages/remix-server-runtime/tsconfig.json delete mode 100644 packages/remix-server-runtime/typecheck.ts delete mode 100644 packages/remix-server-runtime/upload/errors.ts delete mode 100644 packages/remix-server-runtime/upload/memoryUploadHandler.ts delete mode 100644 packages/remix-server-runtime/warnings.ts delete mode 100644 packages/remix-testing/CHANGELOG.md delete mode 100644 packages/remix-testing/README.md delete mode 100644 packages/remix-testing/__tests__/stub-test.tsx delete mode 100644 packages/remix-testing/create-remix-stub.tsx delete mode 100644 packages/remix-testing/index.ts delete mode 100644 packages/remix-testing/jest.config.js delete mode 100644 packages/remix-testing/jest.setup.js delete mode 100644 packages/remix-testing/package.json delete mode 100644 packages/remix-testing/rollup.config.js delete mode 100644 packages/remix-testing/tsconfig.json delete mode 100644 packages/remix/CHANGELOG.md delete mode 100644 packages/remix/README.md delete mode 100644 packages/remix/index.ts delete mode 100644 packages/remix/package.json delete mode 100644 packages/remix/rollup.config.js delete mode 100644 packages/remix/tsconfig.json delete mode 100644 patches/@changesets__assemble-release-plan@5.2.2.patch delete mode 100644 playground/README.md delete mode 100644 pnpm-lock.yaml delete mode 100644 pnpm-workspace.yaml delete mode 100644 prettier.config.js delete mode 100644 rollup.config.js delete mode 100644 rollup.utils.js delete mode 100644 scripts/build.mjs delete mode 100755 scripts/bump-fetch-versions.sh delete mode 100755 scripts/bump-router-versions.sh delete mode 100644 scripts/clean-build.mjs delete mode 100644 scripts/close-v2-issues-comment.md delete mode 100644 scripts/close-v2-issues.mjs delete mode 100644 scripts/close-v2-prs-comment.md delete mode 100644 scripts/compile-release-notes.mjs delete mode 100644 scripts/copy-build-to-dist.mjs delete mode 100644 scripts/copy-templates-to-fixtures.sh delete mode 100644 scripts/deployment-test/_shared.mjs delete mode 100644 scripts/deployment-test/arc.mjs delete mode 100644 scripts/deployment-test/cf-pages.mjs delete mode 100644 scripts/deployment-test/cf-workers.mjs delete mode 100644 scripts/deployment-test/cypress.json delete mode 100644 scripts/deployment-test/cypress/.eslintrc.js delete mode 100644 scripts/deployment-test/cypress/e2e/smoke.ts delete mode 100644 scripts/deployment-test/cypress/fixtures/example.json delete mode 100644 scripts/deployment-test/cypress/plugins/index.ts delete mode 100644 scripts/deployment-test/cypress/support/index.js delete mode 100644 scripts/deployment-test/cypress/tsconfig.json delete mode 100644 scripts/deployment-test/deno-deploy.mjs delete mode 100644 scripts/deployment-test/fly.mjs delete mode 100644 scripts/deployment-test/package.json delete mode 100644 scripts/find-release-from-changeset.js delete mode 100755 scripts/lint-templates.sh delete mode 100644 scripts/markdown-references.mjs delete mode 100644 scripts/patchup-version.mjs delete mode 100644 scripts/playground/new.js delete mode 100644 scripts/playground/template/.env delete mode 100644 scripts/playground/template/.gitignore delete mode 100644 scripts/playground/template/.prettierignore delete mode 100644 scripts/playground/template/README.md delete mode 100644 scripts/playground/template/app/db.server.ts delete mode 100644 scripts/playground/template/app/entry.client.tsx delete mode 100644 scripts/playground/template/app/entry.server.tsx delete mode 100644 scripts/playground/template/app/models/note.server.ts delete mode 100644 scripts/playground/template/app/models/user.server.ts delete mode 100644 scripts/playground/template/app/root.tsx delete mode 100644 scripts/playground/template/app/routes/index.tsx delete mode 100644 scripts/playground/template/app/routes/join.tsx delete mode 100644 scripts/playground/template/app/routes/login.tsx delete mode 100644 scripts/playground/template/app/routes/logout.tsx delete mode 100644 scripts/playground/template/app/routes/notes.tsx delete mode 100644 scripts/playground/template/app/routes/notes/$noteId.tsx delete mode 100644 scripts/playground/template/app/routes/notes/index.tsx delete mode 100644 scripts/playground/template/app/routes/notes/new.tsx delete mode 100644 scripts/playground/template/app/session.server.ts delete mode 100644 scripts/playground/template/app/styles/tailwind.css delete mode 100644 scripts/playground/template/app/utils.ts delete mode 100644 scripts/playground/template/package.json delete mode 100644 scripts/playground/template/prisma/migrations/20220307190657_init/migration.sql delete mode 100644 scripts/playground/template/prisma/migrations/migration_lock.toml delete mode 100644 scripts/playground/template/prisma/schema.prisma delete mode 100644 scripts/playground/template/prisma/seed.ts delete mode 100644 scripts/playground/template/public/favicon.ico delete mode 100644 scripts/playground/template/remix.config.js delete mode 100644 scripts/playground/template/remix.env.d.ts delete mode 100644 scripts/playground/template/remix.init/index.js delete mode 100644 scripts/playground/template/server.js delete mode 100644 scripts/playground/template/tailwind.config.js delete mode 100644 scripts/playground/template/tsconfig.json delete mode 100644 scripts/prompt-confirm.d.ts delete mode 100644 scripts/publish-private.js delete mode 100644 scripts/publish.js delete mode 100644 scripts/release.js delete mode 100644 scripts/remove-prerelease-changelogs.mjs delete mode 100644 scripts/run-migration-on-examples.js delete mode 100644 scripts/tsconfig.json delete mode 100644 scripts/unist.d.ts delete mode 100644 scripts/utils.js delete mode 100644 scripts/version.js delete mode 100644 templates/.eslintignore delete mode 100644 templates/.gitignore delete mode 100644 templates/classic-remix-compiler/arc/.eslintrc.cjs delete mode 100644 templates/classic-remix-compiler/arc/.gitignore delete mode 100644 templates/classic-remix-compiler/arc/README.md delete mode 100644 templates/classic-remix-compiler/arc/app.arc delete mode 100644 templates/classic-remix-compiler/arc/app/entry.client.tsx delete mode 100644 templates/classic-remix-compiler/arc/app/entry.server.tsx delete mode 100644 templates/classic-remix-compiler/arc/app/root.tsx delete mode 100644 templates/classic-remix-compiler/arc/app/routes/_index.tsx delete mode 100644 templates/classic-remix-compiler/arc/package.json delete mode 100644 templates/classic-remix-compiler/arc/plugin-remix.js delete mode 100644 templates/classic-remix-compiler/arc/public/favicon.ico delete mode 100644 templates/classic-remix-compiler/arc/remix.config.js delete mode 100644 templates/classic-remix-compiler/arc/remix.env.d.ts delete mode 100644 templates/classic-remix-compiler/arc/server.ts delete mode 100644 templates/classic-remix-compiler/arc/tsconfig.json delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/.eslintrc.cjs delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/.gitignore delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/.node-version delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/README.md delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/app/entry.client.tsx delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/app/entry.server.tsx delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/app/root.tsx delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/app/routes/_index.tsx delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/package.json delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/public/_headers delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/public/_routes.json delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/public/favicon.ico delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/remix.config.js delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/remix.env.d.ts delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/server.ts delete mode 100644 templates/classic-remix-compiler/cloudflare-pages/tsconfig.json delete mode 100644 templates/classic-remix-compiler/cloudflare-workers/.eslintrc.cjs delete mode 100644 templates/classic-remix-compiler/cloudflare-workers/.gitignore delete mode 100644 templates/classic-remix-compiler/cloudflare-workers/README.md delete mode 100644 templates/classic-remix-compiler/cloudflare-workers/app/entry.client.tsx delete mode 100644 templates/classic-remix-compiler/cloudflare-workers/app/entry.server.tsx delete mode 100644 templates/classic-remix-compiler/cloudflare-workers/app/root.tsx delete mode 100644 templates/classic-remix-compiler/cloudflare-workers/app/routes/_index.tsx delete mode 100644 templates/classic-remix-compiler/cloudflare-workers/package.json delete mode 100644 templates/classic-remix-compiler/cloudflare-workers/public/favicon.ico delete mode 100644 templates/classic-remix-compiler/cloudflare-workers/remix.config.js delete mode 100644 templates/classic-remix-compiler/cloudflare-workers/remix.env.d.ts delete mode 100644 templates/classic-remix-compiler/cloudflare-workers/server.ts delete mode 100644 templates/classic-remix-compiler/cloudflare-workers/tsconfig.json delete mode 100644 templates/classic-remix-compiler/cloudflare-workers/wrangler.toml delete mode 100644 templates/classic-remix-compiler/deno/.gitignore delete mode 100644 templates/classic-remix-compiler/deno/.vscode/extensions.json delete mode 100644 templates/classic-remix-compiler/deno/.vscode/resolve_npm_imports.json delete mode 100644 templates/classic-remix-compiler/deno/.vscode/settings.json delete mode 100644 templates/classic-remix-compiler/deno/README.md delete mode 100644 templates/classic-remix-compiler/deno/app/entry.client.tsx delete mode 100644 templates/classic-remix-compiler/deno/app/entry.server.tsx delete mode 100644 templates/classic-remix-compiler/deno/app/root.tsx delete mode 100644 templates/classic-remix-compiler/deno/app/routes/_index.tsx delete mode 100644 templates/classic-remix-compiler/deno/deno.json delete mode 100644 templates/classic-remix-compiler/deno/package.json delete mode 100644 templates/classic-remix-compiler/deno/public/favicon.ico delete mode 100644 templates/classic-remix-compiler/deno/remix.config.js delete mode 100644 templates/classic-remix-compiler/deno/server.ts delete mode 100644 templates/classic-remix-compiler/express/.eslintrc.cjs delete mode 100644 templates/classic-remix-compiler/express/.gitignore delete mode 100644 templates/classic-remix-compiler/express/README.md delete mode 100644 templates/classic-remix-compiler/express/app/entry.client.tsx delete mode 100644 templates/classic-remix-compiler/express/app/entry.server.tsx delete mode 100644 templates/classic-remix-compiler/express/app/root.tsx delete mode 100644 templates/classic-remix-compiler/express/app/routes/_index.tsx delete mode 100644 templates/classic-remix-compiler/express/package.json delete mode 100644 templates/classic-remix-compiler/express/public/favicon.ico delete mode 100644 templates/classic-remix-compiler/express/remix.config.js delete mode 100644 templates/classic-remix-compiler/express/remix.env.d.ts delete mode 100644 templates/classic-remix-compiler/express/server.js delete mode 100644 templates/classic-remix-compiler/express/tsconfig.json delete mode 100644 templates/classic-remix-compiler/fly/.eslintrc.cjs delete mode 100644 templates/classic-remix-compiler/fly/.gitignore delete mode 100644 templates/classic-remix-compiler/fly/README.md delete mode 100644 templates/classic-remix-compiler/fly/app/entry.client.tsx delete mode 100644 templates/classic-remix-compiler/fly/app/entry.server.tsx delete mode 100644 templates/classic-remix-compiler/fly/app/root.tsx delete mode 100644 templates/classic-remix-compiler/fly/app/routes/_index.tsx delete mode 100644 templates/classic-remix-compiler/fly/package.json delete mode 100644 templates/classic-remix-compiler/fly/public/favicon.ico delete mode 100644 templates/classic-remix-compiler/fly/remix.config.js delete mode 100644 templates/classic-remix-compiler/fly/remix.env.d.ts delete mode 100644 templates/classic-remix-compiler/fly/tsconfig.json delete mode 100644 templates/classic-remix-compiler/remix-javascript/.eslintrc.cjs delete mode 100644 templates/classic-remix-compiler/remix-javascript/.gitignore delete mode 100644 templates/classic-remix-compiler/remix-javascript/README.md delete mode 100644 templates/classic-remix-compiler/remix-javascript/app/entry.client.jsx delete mode 100644 templates/classic-remix-compiler/remix-javascript/app/entry.server.jsx delete mode 100644 templates/classic-remix-compiler/remix-javascript/app/root.jsx delete mode 100644 templates/classic-remix-compiler/remix-javascript/app/routes/_index.jsx delete mode 100644 templates/classic-remix-compiler/remix-javascript/package.json delete mode 100644 templates/classic-remix-compiler/remix-javascript/public/favicon.ico delete mode 100644 templates/classic-remix-compiler/remix-javascript/remix.config.js delete mode 100644 templates/classic-remix-compiler/remix/.eslintrc.cjs delete mode 100644 templates/classic-remix-compiler/remix/.gitignore delete mode 100644 templates/classic-remix-compiler/remix/README.md delete mode 100644 templates/classic-remix-compiler/remix/app/entry.client.tsx delete mode 100644 templates/classic-remix-compiler/remix/app/entry.server.tsx delete mode 100644 templates/classic-remix-compiler/remix/app/root.tsx delete mode 100644 templates/classic-remix-compiler/remix/app/routes/_index.tsx delete mode 100644 templates/classic-remix-compiler/remix/package.json delete mode 100644 templates/classic-remix-compiler/remix/public/favicon.ico delete mode 100644 templates/classic-remix-compiler/remix/remix.config.js delete mode 100644 templates/classic-remix-compiler/remix/remix.env.d.ts delete mode 100644 templates/classic-remix-compiler/remix/tsconfig.json delete mode 100644 templates/cloudflare-workers/.eslintrc.cjs delete mode 100644 templates/cloudflare-workers/.gitignore delete mode 100644 templates/cloudflare-workers/README.md delete mode 100644 templates/cloudflare-workers/app/entry.client.tsx delete mode 100644 templates/cloudflare-workers/app/entry.server.tsx delete mode 100644 templates/cloudflare-workers/app/root.tsx delete mode 100644 templates/cloudflare-workers/app/routes/_index.tsx delete mode 100644 templates/cloudflare-workers/app/tailwind.css delete mode 100644 templates/cloudflare-workers/load-context.ts delete mode 100644 templates/cloudflare-workers/package.json delete mode 100644 templates/cloudflare-workers/postcss.config.js delete mode 100644 templates/cloudflare-workers/public/favicon.ico delete mode 100644 templates/cloudflare-workers/public/logo-dark.png delete mode 100644 templates/cloudflare-workers/public/logo-light.png delete mode 100644 templates/cloudflare-workers/server.ts delete mode 100644 templates/cloudflare-workers/tailwind.config.ts delete mode 100644 templates/cloudflare-workers/tsconfig.json delete mode 100644 templates/cloudflare-workers/vite.config.ts delete mode 100644 templates/cloudflare-workers/worker-configuration.d.ts delete mode 100644 templates/cloudflare-workers/wrangler.toml delete mode 100644 templates/cloudflare/.eslintrc.cjs delete mode 100644 templates/cloudflare/.gitignore delete mode 100644 templates/cloudflare/README.md delete mode 100644 templates/cloudflare/app/entry.client.tsx delete mode 100644 templates/cloudflare/app/entry.server.tsx delete mode 100644 templates/cloudflare/app/root.tsx delete mode 100644 templates/cloudflare/app/routes/_index.tsx delete mode 100644 templates/cloudflare/app/tailwind.css delete mode 100644 templates/cloudflare/functions/[[path]].ts delete mode 100644 templates/cloudflare/load-context.ts delete mode 100644 templates/cloudflare/package.json delete mode 100644 templates/cloudflare/postcss.config.js delete mode 100644 templates/cloudflare/public/_headers delete mode 100644 templates/cloudflare/public/_routes.json delete mode 100644 templates/cloudflare/public/favicon.ico delete mode 100644 templates/cloudflare/public/logo-dark.png delete mode 100644 templates/cloudflare/public/logo-light.png delete mode 100644 templates/cloudflare/tailwind.config.ts delete mode 100644 templates/cloudflare/tsconfig.json delete mode 100644 templates/cloudflare/vite.config.ts delete mode 100644 templates/express/.eslintrc.cjs delete mode 100644 templates/express/.gitignore delete mode 100644 templates/express/README.md delete mode 100644 templates/express/app/entry.client.tsx delete mode 100644 templates/express/app/entry.server.tsx delete mode 100644 templates/express/app/root.tsx delete mode 100644 templates/express/app/routes/_index.tsx delete mode 100644 templates/express/app/tailwind.css delete mode 100644 templates/express/package.json delete mode 100644 templates/express/postcss.config.js delete mode 100644 templates/express/public/favicon.ico delete mode 100644 templates/express/public/logo-dark.png delete mode 100644 templates/express/public/logo-light.png delete mode 100644 templates/express/server.js delete mode 100644 templates/express/tailwind.config.ts delete mode 100644 templates/express/tsconfig.json delete mode 100644 templates/express/vite.config.ts delete mode 100644 templates/remix-javascript/.eslintrc.cjs delete mode 100644 templates/remix-javascript/.gitignore delete mode 100644 templates/remix-javascript/README.md delete mode 100644 templates/remix-javascript/app/entry.client.jsx delete mode 100644 templates/remix-javascript/app/entry.server.jsx delete mode 100644 templates/remix-javascript/app/root.jsx delete mode 100644 templates/remix-javascript/app/routes/_index.jsx delete mode 100644 templates/remix-javascript/app/tailwind.css delete mode 100644 templates/remix-javascript/package.json delete mode 100644 templates/remix-javascript/postcss.config.js delete mode 100644 templates/remix-javascript/public/favicon.ico delete mode 100644 templates/remix-javascript/public/logo-dark.png delete mode 100644 templates/remix-javascript/public/logo-light.png delete mode 100644 templates/remix-javascript/tailwind.config.js delete mode 100644 templates/remix-javascript/vite.config.js delete mode 100644 templates/remix-tutorial/.eslintrc.cjs delete mode 100644 templates/remix-tutorial/.gitignore delete mode 100644 templates/remix-tutorial/README.md delete mode 100644 templates/remix-tutorial/app/app.css delete mode 100644 templates/remix-tutorial/app/data.ts delete mode 100644 templates/remix-tutorial/app/root.tsx delete mode 100644 templates/remix-tutorial/package.json delete mode 100644 templates/remix-tutorial/public/favicon.ico delete mode 100644 templates/remix-tutorial/tsconfig.json delete mode 100644 templates/remix-tutorial/vite.config.ts delete mode 100644 templates/remix/.eslintrc.cjs delete mode 100644 templates/remix/.gitignore delete mode 100644 templates/remix/README.md delete mode 100644 templates/remix/app/entry.client.tsx delete mode 100644 templates/remix/app/entry.server.tsx delete mode 100644 templates/remix/app/root.tsx delete mode 100644 templates/remix/app/routes/_index.tsx delete mode 100644 templates/remix/app/tailwind.css delete mode 100644 templates/remix/package.json delete mode 100644 templates/remix/postcss.config.js delete mode 100644 templates/remix/public/favicon.ico delete mode 100644 templates/remix/public/logo-dark.png delete mode 100644 templates/remix/public/logo-light.png delete mode 100644 templates/remix/tailwind.config.ts delete mode 100644 templates/remix/tsconfig.json delete mode 100644 templates/remix/vite.config.ts delete mode 100644 templates/spa/.eslintrc.cjs delete mode 100644 templates/spa/.gitignore delete mode 100644 templates/spa/README.md delete mode 100644 templates/spa/app/entry.client.tsx delete mode 100644 templates/spa/app/root.tsx delete mode 100644 templates/spa/app/routes/_index.tsx delete mode 100644 templates/spa/app/tailwind.css delete mode 100644 templates/spa/package.json delete mode 100644 templates/spa/postcss.config.js delete mode 100644 templates/spa/public/favicon.ico delete mode 100644 templates/spa/public/logo-dark.png delete mode 100644 templates/spa/public/logo-light.png delete mode 100644 templates/spa/tailwind.config.ts delete mode 100644 templates/spa/tsconfig.json delete mode 100644 templates/spa/vite.config.ts diff --git a/.changeset/README.md b/.changeset/README.md deleted file mode 100644 index e5b6d8d6a67..00000000000 --- a/.changeset/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Changesets - -Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works -with multi-package repos, or single-package repos to help you version and publish your code. You can -find the full documentation for it [in our repository](https://github.com/changesets/changesets) - -We have a quick list of common questions to get you started engaging with this project in -[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json deleted file mode 100644 index ec26afca268..00000000000 --- a/.changeset/config.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "$schema": "https://unpkg.com/@changesets/config@2.0.0/schema.json", - "changelog": ["@remix-run/changelog-github", { "repo": "remix-run/remix" }], - "commit": false, - "fixed": [ - [ - "create-remix", - "remix", - "@remix-run/architect", - "@remix-run/cloudflare", - "@remix-run/cloudflare-pages", - "@remix-run/cloudflare-workers", - "@remix-run/css-bundle", - "@remix-run/deno", - "@remix-run/dev", - "@remix-run/eslint-config", - "@remix-run/express", - "@remix-run/fs-routes", - "@remix-run/node", - "@remix-run/react", - "@remix-run/route-config", - "@remix-run/routes-option-adapter", - "@remix-run/serve", - "@remix-run/server-runtime", - "@remix-run/testing" - ] - ], - "linked": [], - "access": "public", - "baseBranch": "dev", - "updateInternalDependencies": "patch", - "ignore": ["integration", "integration-*"], - "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { - "onlyUpdatePeerDependentsWhenOutOfRange": true - } -} diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index e26dc5e8bf1..00000000000 --- a/.eslintignore +++ /dev/null @@ -1,18 +0,0 @@ -**/build/ -**/tests/__snapshots/ -**/node_modules/ -.tmp -pnpm-lock.yaml -/playground -**/__tests__/fixtures -**/__tests__/**/*/fixtures -/packages/*/dist/ - -# Deno -integration/helpers/deno-template -packages/remix-deno -templates/deno - -packages/remix-dev/config/defaults -templates/remix-tutorial/app/data.ts -templates/cloudflare-workers/worker-configuration.d.ts diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index cf59e693bea..00000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,64 +0,0 @@ -const OFF = 0; -const WARN = 1; - -/** @type {import('eslint').Linter.Config} */ -module.exports = { - root: true, - extends: [ - require.resolve("./packages/remix-eslint-config/internal.js"), - "plugin:markdown/recommended", - ], - plugins: ["markdown"], - settings: { - "import/internal-regex": "^~/", - }, - overrides: [ - { - files: ["**/*.md/**"], - rules: { - "import/no-extraneous-dependencies": OFF, - "no-dupe-keys": OFF, - "no-undef": OFF, - "no-unused-expressions": OFF, - "no-unused-vars": OFF, - "@typescript-eslint/no-redeclare": OFF, - }, - }, - { - files: ["rollup.config.js"], - rules: { - "import/no-extraneous-dependencies": OFF, - }, - }, - { - files: [ - "**/*.md/*.js?(x)", - "**/*.md/*.ts?(x)", - "integration/helpers/cf-template/**/*.*", - "integration/helpers/deno-template/**/*.*", - "integration/helpers/node-template/**/*.*", - "packages/remix-dev/config/defaults/**/*.*", - "templates/**/*.*", - ], - rules: { - "prefer-let/prefer-let": OFF, - "prefer-const": WARN, - - "import/order": [ - WARN, - { - alphabetize: { caseInsensitive: true, order: "asc" }, - groups: ["builtin", "external", "internal", "parent", "sibling"], - "newlines-between": "always", - }, - ], - - "react/jsx-no-leaked-render": [WARN, { validStrategies: ["ternary"] }], - }, - }, - ], - // Report unused `eslint-disable` comments. - reportUnusedDisableDirectives: true, - // Tell ESLint not to ignore dot-files, which are ignored by default. - ignorePatterns: ["!.*.js"], -}; diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml deleted file mode 100644 index 246dece0607..00000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: 🐛 Bug Report -description: Something is wrong with Remix. -labels: - - "bug:unverified" -body: - - type: markdown - attributes: - value: | - Thank you for helping to improve Remix! - - ## Option 1: Submit a PR with a failing test - - 🏆 The most helpful reproduction is to use our _bug report integration test_ template: - - 1. [Fork `remix-run/remix`](https://github.com/remix-run/remix/fork) - 2. Open [`integration/bug-report-test.ts`](https://github.com/remix-run/remix/blob/dev/integration/bug-report-test.ts) in your editor - 3. Follow the instructions and submit a pull request with a failing bug report test! - - ## Option 2: Continue filling out this form - - If you'd rather open a GitHub issue, here are other ways to share a reproduction (ordered from most helpful to least): - - - 🥇 Link to a [StackBlitz](https://remix.new) environment - - 🥈 Link to a GitHub repository - - 🥉 Description of project including template, `remix.config.js`, `package.json` scripts, etc. - - - type: textarea - id: reproduction - attributes: - label: Reproduction - description: Link to reproduction and steps to reproduce the behavior - placeholder: Go to https://stackblitz.com/edit/... and click the "Submit" button - validations: - required: true - - type: textarea - id: system-info - attributes: - label: System Info - description: Output of `npx envinfo --system --npmPackages '{vite,@remix-run/*}' --binaries --browsers` - render: shell - placeholder: System, Binaries, Browsers - validations: - required: true - - type: dropdown - id: package-manager - attributes: - label: Used Package Manager - description: Select the used package manager - options: - - npm - - yarn - - pnpm - validations: - required: true - - type: textarea - attributes: - label: Expected Behavior - description: A concise description of what you expected to happen. - validations: - required: true - - type: textarea - attributes: - label: Actual Behavior - description: A concise description of what you're experiencing. - validations: - required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 23fc00082af..00000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,21 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: Get Help - url: https://github.com/remix-run/remix/discussions/new?category=q-a - about: - If you can't get something to work the way you expect, open a question in - the Remix discussions. - - name: Feature Request - url: https://github.com/remix-run/remix/discussions/new?category=ideas - about: - We appreciate you taking the time to improve Remix with your ideas, but we - use the Discussions for this instead of the issues tab 🙂. - - name: 💬 Remix Discord Channel - url: https://rmx.as/discord - about: Interact with other people using Remix 📀 - - name: 💬 New Updates (Twitter) - url: https://twitter.com/remix_run - about: Stay up to date with Remix news on twitter - - name: 🍿 Remix YouTube Channel - url: https://rmx.as/youtube - about: Are you a tech lead or wanting to learn more about Remix in depth? Checkout the Remix YouTube Channel diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 86c916b9bee..00000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,42 +0,0 @@ - - -Closes: # - -- [ ] Docs -- [ ] Tests - -Testing Strategy: - - diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 253bcb76bad..00000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,6 +0,0 @@ -version: 2 -updates: - - package-ecosystem: github-actions - directory: / - schedule: - interval: daily diff --git a/.github/workflows/close-v2-issues.yml b/.github/workflows/close-v2-issues.yml deleted file mode 100644 index 6dd1c2a3360..00000000000 --- a/.github/workflows/close-v2-issues.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: 🚪 Close v2 Issues/PRs - -on: - workflow_dispatch: - inputs: - type: - type: choice - description: Type - options: - - issues - - prs - required: true - prior_to_date: - required: true - -concurrency: ${{ github.workflow }}-${{ github.ref }} - -jobs: - experimental: - name: 🚪 Close v2 Issues/PRs - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - env: - CI: "true" - GH_TOKEN: ${{ github.token }} - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: "pnpm" - - - name: 📥 Install deps - run: pnpm install --frozen-lockfile - - - name: 🚪 Close Issues - run: node ./scripts/close-v2-issues.mjs --type ${{ github.event.inputs.type }} --date ${{ github.event.inputs.prior_to_date }} diff --git a/.github/workflows/deduplicate-lock-file.yml b/.github/workflows/deduplicate-lock-file.yml deleted file mode 100644 index 7bdabf220ff..00000000000 --- a/.github/workflows/deduplicate-lock-file.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: ⚙️ Deduplicate lock file - -on: - push: - branches: - - dev - paths: - - pnpm-lock.yaml - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - deduplicate: - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - with: - token: ${{ secrets.FORMAT_PAT }} - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: "pnpm" - - - name: ️️⚙️ Deduplicate pnpm-lock.yaml - run: pnpm dedupe && rm -rf ./node_modules && pnpm install - - - name: 💪 Commit - run: | - git config --local user.email "github-actions[bot]@users.noreply.github.com" - git config --local user.name "github-actions[bot]" - - git add . - if [ -z "$(git status --porcelain)" ]; then - echo "💿 no deduplication needed" - exit 0 - fi - git commit -m "chore: deduplicate pnpm-lock.yaml" - git push - echo "💿 https://github.com/$GITHUB_REPOSITORY/commit/$(git rev-parse HEAD)" diff --git a/.github/workflows/deployments.yml b/.github/workflows/deployments.yml deleted file mode 100644 index c3801c9042d..00000000000 --- a/.github/workflows/deployments.yml +++ /dev/null @@ -1,222 +0,0 @@ -name: 🚀 Deployment Tests - -on: - workflow_call: - secrets: - TEST_AWS_ACCESS_KEY_ID: - required: true - TEST_AWS_SECRET_ACCESS_KEY: - required: true - TEST_CF_ACCOUNT_ID: - required: true - TEST_CF_GLOBAL_API_KEY: - required: true - TEST_CF_EMAIL: - required: true - TEST_CF_PAGES_API_TOKEN: - required: true - TEST_CF_API_TOKEN: - required: true - TEST_DENO_DEPLOY_TOKEN: - required: true - TEST_FLY_TOKEN: - required: true - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - arc_deploy: - name: Architect Deploy - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: npm - cache-dependency-path: ./scripts/deployment-test/package.json # no lockfile, key caching off package.json - - # some deployment targets require the latest version of npm - # TODO: remove this eventually when the default version we get - # is "latest" enough. - - name: 📦 Install latest version of npm - run: npm install -g npm@latest - working-directory: ./scripts/deployment-test - - - name: 📥 Install deployment-test deps - run: npm install - working-directory: ./scripts/deployment-test - - - name: 🚀 Deploy to Arc - run: node ./arc.mjs - working-directory: ./scripts/deployment-test - env: - CI: true - AWS_ACCESS_KEY_ID: ${{ secrets.TEST_AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.TEST_AWS_SECRET_ACCESS_KEY }} - - cf_pages_deploy: - name: "CF Pages Deploy" - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: npm - cache-dependency-path: ./scripts/deployment-test/package.json # no lockfile, key caching off package.json - - # some deployment targets require the latest version of npm - # TODO: remove this eventually when the default version we get - # is "latest" enough. - - name: 📦 Install latest version of npm - run: npm install -g npm@latest - working-directory: ./scripts/deployment-test - - - name: 📥 Install deployment-test deps - run: npm install - working-directory: ./scripts/deployment-test - - - name: 🚀 Deploy to Cloudflare Pages - run: node ./cf-pages.mjs - working-directory: ./scripts/deployment-test - env: - CLOUDFLARE_ACCOUNT_ID: ${{ secrets.TEST_CF_ACCOUNT_ID }} - CLOUDFLARE_GLOBAL_API_KEY: ${{ secrets.TEST_CF_GLOBAL_API_KEY }} - CLOUDFLARE_EMAIL: ${{ secrets.TEST_CF_EMAIL }} - CLOUDFLARE_API_TOKEN: ${{ secrets.TEST_CF_PAGES_API_TOKEN }} - - cf_workers_deploy: - name: "CF Workers Deploy" - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: npm - cache-dependency-path: ./scripts/deployment-test/package.json # no lockfile, key caching off package.json - - # some deployment targets require the latest version of npm - # TODO: remove this eventually when the default version we get - # is "latest" enough. - - name: 📦 Install latest version of npm - run: npm install -g npm@latest - working-directory: ./scripts/deployment-test - - - name: 📥 Install deployment-test deps - run: npm install - working-directory: ./scripts/deployment-test - - - name: 🚀 Deploy to Cloudflare Workers - run: node ./cf-workers.mjs - working-directory: ./scripts/deployment-test - env: - CLOUDFLARE_ACCOUNT_ID: ${{ secrets.TEST_CF_ACCOUNT_ID }} - CLOUDFLARE_API_TOKEN: ${{ secrets.TEST_CF_API_TOKEN }} - CLOUDFLARE_EMAIL: ${{ secrets.CLOUDFLARE_EMAIL }} - CLOUDFLARE_GLOBAL_API_KEY: ${{ secrets.CLOUDFLARE_GLOBAL_API_KEY }} - - # "deploy deploy" is not a typo, we are deploying to Deno Deploy - deno_deploy_deploy: - name: "Deno Deploy Deploy" - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: npm - cache-dependency-path: ./scripts/deployment-test/package.json # no lockfile, key caching off package.json - - # some deployment targets require the latest version of npm - # TODO: remove this eventually when the default version we get - # is "latest" enough. - - name: 📦 Install latest version of npm - run: npm install -g npm@latest - working-directory: ./scripts/deployment-test - - - name: 📥 Install deployment-test deps - run: npm install - working-directory: ./scripts/deployment-test - - - name: 🦕 Install Deno - uses: denoland/setup-deno@v1 - with: - deno-version: vx.x.x - - name: 🦕 Deno Deploy CLI - run: deno install --allow-read --allow-write --allow-env --allow-net --allow-run --no-check -r -f https://deno.land/x/deploy/deployctl.ts - - - name: 🚀 Deploy to Deno Deploy - run: node ./deno-deploy.mjs - working-directory: ./scripts/deployment-test - env: - DENO_DEPLOY_TOKEN: ${{ secrets.TEST_DENO_DEPLOY_TOKEN }} - - fly_deploy: - name: "Fly Deploy" - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: npm - cache-dependency-path: ./scripts/deployment-test/package.json # no lockfile, key caching off package.json - - # some deployment targets require the latest version of npm - # TODO: remove this eventually when the default version we get - # is "latest" enough. - - name: 📦 Install latest version of npm - run: npm install -g npm@latest - working-directory: ./scripts/deployment-test - - - name: 📥 Install deployment-test deps - run: npm install - working-directory: ./scripts/deployment-test - - - name: 🎈 Install the Fly CLI - run: curl -L https://fly.io/install.sh | FLYCTL_INSTALL=/usr/local sh - - - name: 🚀 Deploy to Fly - run: node ./fly.mjs - working-directory: ./scripts/deployment-test - env: - FLY_API_TOKEN: ${{ secrets.TEST_FLY_TOKEN }} diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml deleted file mode 100644 index 9e094a0088e..00000000000 --- a/.github/workflows/format.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: 👔 Format - -on: - push: - branches: - - main - - dev - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - format: - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - with: - token: ${{ secrets.FORMAT_PAT }} - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: "pnpm" - - - name: 📥 Install deps - run: pnpm install --frozen-lockfile - - - name: 🔗 Convert Docs links to references - run: node scripts/markdown-references.mjs - - - name: 🔃 Sort contributors.yml - run: sort --ignore-case --output contributors.yml contributors.yml - - - name: 👔 Format - run: pnpm format - - - name: 🦕 Install Deno - uses: denoland/setup-deno@v1 - with: - deno-version: vx.x.x - - - name: 👔 Format Deno files - run: pnpm format:deno - - - name: 💪 Commit - run: | - git config --local user.email "hello@remix.run" - git config --local user.name "Remix Run Bot" - - git add . - if [ -z "$(git status --porcelain)" ]; then - echo "💿 no formatting changed" - exit 0 - fi - git commit -m "chore: format" - git push - echo "💿 pushed formatting changes https://github.com/$GITHUB_REPOSITORY/commit/$(git rev-parse HEAD)" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 413cdf0c8ed..00000000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: ⬣ Lint - -on: - push: - branches: - - main - - dev - pull_request: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - lint: - name: ⬣ Lint - runs-on: ubuntu-latest - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: "pnpm" - - - name: Disable GitHub Actions Annotations - run: | - echo "::remove-matcher owner=tsc::" - echo "::remove-matcher owner=eslint-compact::" - echo "::remove-matcher owner=eslint-stylish::" - - - name: 📥 Install deps - run: pnpm install --frozen-lockfile - - - name: 🔬 Lint - run: pnpm lint - - - name: 🦕 Install Deno - uses: denoland/setup-deno@v1 - with: - deno-version: vx.x.x - - - name: 🔬 Lint deno files - run: pnpm lint:deno diff --git a/.github/workflows/merged-pr.yml b/.github/workflows/merged-pr.yml deleted file mode 100644 index d77d49d89e0..00000000000 --- a/.github/workflows/merged-pr.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: 📦 Merged PR - -on: - pull_request: - types: [closed] - branches: - - dev - paths: - - "packages/**" - -permissions: - pull-requests: write - -jobs: - merged: - name: Add label to merged PR - if: github.event.pull_request.merged == true && github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - steps: - - uses: actions/github-script@v7 - with: - retries: 3 - script: | - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - labels: ['awaiting release'], - }) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml deleted file mode 100644 index d3113d76121..00000000000 --- a/.github/workflows/nightly.yml +++ /dev/null @@ -1,122 +0,0 @@ -name: 🌒 Nightly Release - -on: - workflow_dispatch: - schedule: - - cron: "0 7 * * *" # every day at 12AM PST - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -env: - CI: true - -jobs: - # HEADS UP! this "nightly" job will only ever run on the `main` branch due to it being a cron job, - # and the last commit on main will be what github shows as the trigger - # however in the checkout below we specify the `dev` branch, so all the scripts - # in this job will be ran from that, confusing i know, so in some cases we'll need to create - # multiple PRs when modifying nightly release processes - nightly: - name: 🌒 Nightly Release - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - outputs: - # allows this to be used in the `comment` job below - will be undefined if there's no release necessary - NEXT_VERSION: ${{ steps.version.outputs.NEXT_VERSION }} - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - with: - ref: dev - # checkout using a custom token so that we can push later on - token: ${{ secrets.NIGHTLY_PAT }} - fetch-depth: 0 - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: "pnpm" - - - name: 📥 Install deps - run: pnpm install --frozen-lockfile - - - name: 🕵️ Check for changes - id: version - run: | - SHORT_SHA=$(git rev-parse --short HEAD) - - # get latest nightly tag - LATEST_NIGHTLY_TAG=$(git tag -l v0.0.0-nightly-\* --sort=-creatordate | head -n 1) - - # check if last commit to dev starts would be the nightly tag we're about to create (minus the date) - # if it is, we'll skip the nightly creation - # if not, we'll create a new nightly tag - if [[ ${LATEST_NIGHTLY_TAG} == v0.0.0-nightly-${SHORT_SHA}-* ]]; then - echo "🛑 Latest nightly tag is the same as the latest commit sha, skipping nightly release" - else - # yyyyMMdd format (e.g. 20221207) - DATE=$(date '+%Y%m%d') - # v0.0.0-nightly-- - NEXT_VERSION=0.0.0-nightly-${SHORT_SHA}-${DATE} - # set output so it can be used in other jobs - echo "NEXT_VERSION=${NEXT_VERSION}" >> $GITHUB_OUTPUT - fi - - - name: ⤴️ Update version - if: steps.version.outputs.NEXT_VERSION - run: | - git config --local user.email "hello@remix.run" - git config --local user.name "Remix Run Bot" - git checkout -b nightly/${{ steps.version.outputs.NEXT_VERSION }} - pnpm run version ${{steps.version.outputs.NEXT_VERSION}} --skip-prompt - git push origin --tags - - - name: 🏗 Build - if: steps.version.outputs.NEXT_VERSION - run: pnpm build - - - name: 🔐 Setup npm auth - if: steps.version.outputs.NEXT_VERSION - run: | - echo "registry=https://registry.npmjs.org" >> ~/.npmrc - echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" >> ~/.npmrc - - - name: 🚀 Publish - if: steps.version.outputs.NEXT_VERSION - run: npm run publish - - comment: - needs: [nightly] - name: 📝 Comment on related issues and pull requests - if: github.repository == 'remix-run/remix' && needs.nightly.outputs.NEXT_VERSION - uses: ./.github/workflows/release-comments.yml - - deployments: - needs: [nightly] - name: 🚀 Deployment Tests - if: github.repository == 'remix-run/remix' && needs.nightly.outputs.NEXT_VERSION - uses: remix-run/remix/.github/workflows/deployments.yml@main - secrets: - TEST_AWS_ACCESS_KEY_ID: ${{ secrets.TEST_AWS_ACCESS_KEY_ID }} - TEST_AWS_SECRET_ACCESS_KEY: ${{ secrets.TEST_AWS_SECRET_ACCESS_KEY }} - TEST_CF_ACCOUNT_ID: ${{ secrets.TEST_CF_ACCOUNT_ID }} - TEST_CF_GLOBAL_API_KEY: ${{ secrets.TEST_CF_GLOBAL_API_KEY }} - TEST_CF_EMAIL: ${{ secrets.TEST_CF_EMAIL }} - TEST_CF_PAGES_API_TOKEN: ${{ secrets.TEST_CF_PAGES_API_TOKEN }} - TEST_CF_API_TOKEN: ${{ secrets.TEST_CF_API_TOKEN }} - TEST_DENO_DEPLOY_TOKEN: ${{ secrets.TEST_DENO_DEPLOY_TOKEN }} - TEST_FLY_TOKEN: ${{ secrets.TEST_FLY_TOKEN }} - - stacks: - needs: [nightly] - name: 🥞 Remix Stacks Test - if: github.repository == 'remix-run/remix' && needs.nightly.outputs.NEXT_VERSION - uses: remix-run/remix/.github/workflows/stacks.yml@main - with: - version: "${{ needs.nightly.outputs.NEXT_VERSION }}" diff --git a/.github/workflows/no-response.yml b/.github/workflows/no-response.yml deleted file mode 100644 index a1d7f33f627..00000000000 --- a/.github/workflows/no-response.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: 🥺 No Response - -on: - schedule: - # Schedule for five minutes after the hour, every hour - - cron: "5 * * * *" - -permissions: - issues: write - pull-requests: write - -jobs: - stale: - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - steps: - - name: 🥺 Handle Ghosting - uses: actions/stale@v9 - with: - days-before-close: 10 - close-issue-message: > - This issue has been automatically closed because we haven't received a - response from the original author 🙈. This automation helps keep the issue - tracker clean from issues that are unactionable. Please reach out if you - have more information for us! 🙂 - close-pr-message: > - This PR has been automatically closed because we haven't received a - response from the original author 🙈. This automation helps keep the issue - tracker clean from PRs that are unactionable. Please reach out if you - have more information for us! 🙂 - # don't automatically mark issues/PRs as stale - days-before-stale: -1 - stale-issue-label: needs-response - stale-pr-label: needs-response diff --git a/.github/workflows/release-comments.yml b/.github/workflows/release-comments.yml deleted file mode 100644 index 32927cdc0ae..00000000000 --- a/.github/workflows/release-comments.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: 📝 Comment on Release - -on: - workflow_call: - -jobs: - comment: - name: 📝 Comment on related issues and pull requests - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: 📝 Comment on related issues and pull requests - uses: remix-run/release-comment-action@v0.4.1 - with: - DIRECTORY_TO_CHECK: "./packages" - PACKAGE_NAME: "remix" - PR_LABELS_TO_REMOVE: "awaiting release" diff --git a/.github/workflows/release-experimental.yml b/.github/workflows/release-experimental.yml deleted file mode 100644 index b25a2d5bd0c..00000000000 --- a/.github/workflows/release-experimental.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: 🧪 Experimental Release - -on: - workflow_dispatch: - inputs: - branch: - required: true - -concurrency: ${{ github.workflow }}-${{ github.ref }} - -env: - CI: true - -jobs: - experimental: - name: 🧪 Experimental Release - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.branch }} - # checkout using a custom token so that we can push later on - token: ${{ secrets.NIGHTLY_PAT }} - fetch-depth: 0 - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: "pnpm" - - - name: 📥 Install deps - run: pnpm install --frozen-lockfile - - - name: ⤴️ Update version - run: | - git config --local user.email "hello@remix.run" - git config --local user.name "Remix Run Bot" - SHORT_SHA=$(git rev-parse --short HEAD) - NEXT_VERSION=0.0.0-experimental-${SHORT_SHA} - git checkout -b experimental/${NEXT_VERSION} - pnpm run version ${NEXT_VERSION} --skip-prompt - git push origin --tags - - - name: 🏗 Build - run: pnpm build - - - name: 🔐 Setup npm auth - run: | - echo "registry=https://registry.npmjs.org" >> ~/.npmrc - echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" >> ~/.npmrc - - - name: 🚀 Publish - run: pnpm run publish diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index e711d5a21a5..00000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,123 +0,0 @@ -name: 🦋 Changesets Release -on: - push: - branches: - - release - - "release-*" - - "!release-experimental" - - "!release-experimental-*" - - "!release-manual" - - "!release-manual-*" - -jobs: - release: - name: 🦋 Changesets Release - # we need to check for `nightly` refs and skip them as we dont want to - # double publish a version as it would fail. unfortunately even using curl - # and a `repository_dispatch` trigger, actions still aren't ran if a version - # is published using the default secrets.GITHUB_TOKEN. - if: | - github.repository == 'remix-run/remix' && - !contains(github.ref, 'nightly') - runs-on: ubuntu-latest - outputs: - published_packages: ${{ steps.changesets.outputs.publishedPackages }} - published: ${{ steps.changesets.outputs.published }} - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: "pnpm" - - - name: 📥 Install deps - run: pnpm install --frozen-lockfile - - - name: 🔐 Setup npm auth - run: | - echo "registry=https://registry.npmjs.org" >> ~/.npmrc - echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" >> ~/.npmrc - - # This action has two responsibilities. The first time the workflow runs - # (initial push to a `release-*` branch) it will create a new branch and - # then open a PR with the related changes for the new version. After the - # PR is merged, the workflow will run again and this action will build + - # publish to npm. - - name: 🚀 PR / Publish - id: changesets - uses: changesets/action@v1 - with: - version: pnpm run changeset:version - commit: "chore: Update version for release" - title: "chore: Update version for release" - publish: pnpm run changeset:release - createGithubReleases: false - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - find_package_version: - name: 🦋 Find Package - needs: [release] - runs-on: ubuntu-latest - if: github.repository == 'remix-run/remix' && needs.release.outputs.published == 'true' - outputs: - package_version: ${{ steps.find_package_version.outputs.package_version }} - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: "pnpm" - - - id: find_package_version - run: | - package_version=$(node ./scripts/find-release-from-changeset.js) - echo "package_version=${package_version}" >> $GITHUB_OUTPUT - env: - PACKAGE_VERSION_TO_FOLLOW: "remix" - PUBLISHED_PACKAGES: ${{ needs.release.outputs.published_packages }} - - comment: - name: 📝 Comment on related issues and pull requests - if: github.repository == 'remix-run/remix' && needs.find_package_version.outputs.package_version != '' - needs: [release, find_package_version] - uses: ./.github/workflows/release-comments.yml - - # deployments: - # name: 🚀 Deployment Tests - # if: github.repository == 'remix-run/remix' - # needs: [release, find_package_version] - # uses: ./.github/workflows/deployments.yml - # secrets: - # TEST_AWS_ACCESS_KEY_ID: ${{ secrets.TEST_AWS_ACCESS_KEY_ID }} - # TEST_AWS_SECRET_ACCESS_KEY: ${{ secrets.TEST_AWS_SECRET_ACCESS_KEY }} - # TEST_CF_ACCOUNT_ID: ${{ secrets.TEST_CF_ACCOUNT_ID }} - # TEST_CF_GLOBAL_API_KEY: ${{ secrets.TEST_CF_GLOBAL_API_KEY }} - # TEST_CF_EMAIL: ${{ secrets.TEST_CF_EMAIL }} - # TEST_CF_PAGES_API_TOKEN: ${{ secrets.TEST_CF_PAGES_API_TOKEN }} - # TEST_CF_API_TOKEN: ${{ secrets.TEST_CF_API_TOKEN }} - # TEST_DENO_DEPLOY_TOKEN: ${{ secrets.TEST_DENO_DEPLOY_TOKEN }} - # TEST_FLY_TOKEN: ${{ secrets.TEST_FLY_TOKEN }} - - # stacks: - # name: 🥞 Remix Stacks Test - # if: github.repository == 'remix-run/remix' - # needs: [release, find_package_version] - # uses: ./.github/workflows/stacks.yml - # with: - # version: ${{ needs.find_package_version.outputs.package_version }} diff --git a/.github/workflows/shared-build.yml b/.github/workflows/shared-build.yml deleted file mode 100644 index e8122b92ca8..00000000000 --- a/.github/workflows/shared-build.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: 🛠️ Build - -on: - workflow_call: - -env: - CI: true - CYPRESS_INSTALL_BINARY: 0 - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - cache: "pnpm" - - - name: Disable GitHub Actions Annotations - run: | - echo "::remove-matcher owner=tsc::" - echo "::remove-matcher owner=eslint-compact::" - echo "::remove-matcher owner=eslint-stylish::" - - - name: 📥 Install deps - run: pnpm install --frozen-lockfile - - - name: 🏗 Build - run: pnpm build diff --git a/.github/workflows/shared-test-integration.yml b/.github/workflows/shared-test-integration.yml deleted file mode 100644 index 4110c74f9f8..00000000000 --- a/.github/workflows/shared-test-integration.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: 🧪 Test (Integration) - -on: - workflow_call: - inputs: - os: - required: true - type: string - node_version: - required: true - # this is limited to string | boolean | number (https://github.community/t/can-action-inputs-be-arrays/16457) - # but we want to pass an array (node_version: "[18, 20]"), - # so we'll need to manually stringify it for now - type: string - browser: - required: true - # this is limited to string | boolean | number (https://github.community/t/can-action-inputs-be-arrays/16457) - # but we want to pass an array (browser: "['chromium', 'firefox']"), - # so we'll need to manually stringify it for now - type: string - -env: - CI: true - CYPRESS_INSTALL_BINARY: 0 - -jobs: - integration: - name: "${{ inputs.os }} / node@${{ matrix.node }} / ${{ matrix.browser }}" - strategy: - fail-fast: false - matrix: - node: ${{ fromJSON(inputs.node_version) }} - browser: ${{ fromJSON(inputs.browser) }} - - runs-on: ${{ inputs.os }} - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node ${{ matrix.node }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node }} - cache: "pnpm" - - - name: Disable GitHub Actions Annotations - run: | - echo "::remove-matcher owner=tsc::" - echo "::remove-matcher owner=eslint-compact::" - echo "::remove-matcher owner=eslint-stylish::" - - - name: 📥 Install deps - run: pnpm install --frozen-lockfile - - - name: 📥 Install Playwright - run: npx playwright install --with-deps ${{ matrix.browser }} - - - name: 👀 Run Integration Tests ${{ matrix.browser }} - run: "pnpm test:integration --project=${{ matrix.browser }}" diff --git a/.github/workflows/shared-test-unit.yml b/.github/workflows/shared-test-unit.yml deleted file mode 100644 index ed399bbdebe..00000000000 --- a/.github/workflows/shared-test-unit.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: 🧪 Test (Unit) - -on: - workflow_call: - inputs: - os: - required: true - type: string - node_version: - required: true - # this is limited to string | boolean | number (https://github.community/t/can-action-inputs-be-arrays/16457) - # but we want to pass an array (node_version: "[18, 20]"), - # so we'll need to manually stringify it for now - type: string - -env: - CI: true - CYPRESS_INSTALL_BINARY: 0 - -jobs: - test: - name: "${{ inputs.os }} / node@${{ matrix.node }}" - strategy: - fail-fast: false - matrix: - node: ${{ fromJSON(inputs.node_version) }} - runs-on: ${{ inputs.os }} - steps: - - name: ⬇️ Checkout repo - uses: actions/checkout@v4 - - - name: 📦 Setup pnpm - uses: pnpm/action-setup@v4.1.0 - - - name: ⎔ Setup node ${{ matrix.node }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node }} - cache: "pnpm" - - - name: Disable GitHub Actions Annotations - run: | - echo "::remove-matcher owner=tsc::" - echo "::remove-matcher owner=eslint-compact::" - echo "::remove-matcher owner=eslint-stylish::" - - - name: 📥 Install deps - run: pnpm install --frozen-lockfile - - # It's faster to use the built `cli.js` in tests if its available and up-to-date - - name: 🏗 Build - run: pnpm build - - - name: 🧪 Run Primary Tests - run: "pnpm test:primary" diff --git a/.github/workflows/stacks.yml b/.github/workflows/stacks.yml deleted file mode 100644 index 4edeecd9e79..00000000000 --- a/.github/workflows/stacks.yml +++ /dev/null @@ -1,253 +0,0 @@ -name: 🥞 Remix Stacks Test - -on: - workflow_call: - inputs: - version: - required: true - type: string - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - setup: - name: Remix Stacks Test - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - stack: - - repo: "remix-run/indie-stack" - name: "indie" - - repo: "remix-run/blues-stack" - name: "blues" - - repo: "remix-run/grunge-stack" - name: "grunge" - steps: - - name: ⎔ Setup node - uses: actions/setup-node@v4 - with: - node-version: 18 - - - name: ⚒️ Create new ${{ matrix.stack.name }} app with ${{ inputs.version }} - run: | - npx -y create-remix@${{ inputs.version }} ${{ matrix.stack.name }} --template ${{ matrix.stack.repo }} --no-install --no-git-init - - - name: ⎔ Setup dependency caching - uses: actions/setup-node@v4 - with: - cache: npm - cache-dependency-path: ${{ matrix.stack.name }}/package.json - - - name: 📥 Install deps - run: npm install - working-directory: ${{ matrix.stack.name }} - - - name: Run `remix init` - run: | - cd ${{ matrix.stack.name }} - npx remix init - - - name: 🏄 Copy test env vars - run: | - cd ${{ matrix.stack.name }} - cp .env.example .env - - - name: 📁 Zip artifact - run: zip ${{ matrix.stack.name }}.zip ./${{ matrix.stack.name }} -r -x "**/node_modules/*" - - - name: 🗄️ Archive ${{ matrix.stack.name }} - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.stack.name }}-archive - path: ${{ matrix.stack.name }}.zip - - lint: - name: ⬣ ESLint - if: github.repository == 'remix-run/remix' - needs: [setup] - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - stack: - - repo: "remix-run/indie-stack" - name: "indie" - - repo: "remix-run/blues-stack" - name: "blues" - - repo: "remix-run/grunge-stack" - name: "grunge" - steps: - - name: 🗄️ Restore ${{ matrix.stack.name }} - uses: actions/download-artifact@v4 - with: - name: ${{ matrix.stack.name }}-archive - - - name: 📁 Unzip artifact - run: unzip ${{ matrix.stack.name }}.zip - - - name: ⎔ Setup node and dependency caching - uses: actions/setup-node@v4 - with: - node-version: 18 - cache: npm - cache-dependency-path: ${{ matrix.stack.name }}/package.json - - - name: 📥 Install deps - run: npm install - working-directory: ${{ matrix.stack.name }} - - - name: 🔬 Lint - run: | - cd ${{ matrix.stack.name }} - npm run lint - - typecheck: - name: ʦ TypeScript - needs: [setup] - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - stack: - - repo: "remix-run/indie-stack" - name: "indie" - - repo: "remix-run/blues-stack" - name: "blues" - - repo: "remix-run/grunge-stack" - name: "grunge" - steps: - - name: 🗄️ Restore ${{ matrix.stack.name }} - uses: actions/download-artifact@v4 - with: - name: ${{ matrix.stack.name }}-archive - - - name: 📁 Unzip artifact - run: unzip ${{ matrix.stack.name }}.zip - - - name: ⎔ Setup node and dependency caching - uses: actions/setup-node@v4 - with: - node-version: 18 - cache: npm - cache-dependency-path: ${{ matrix.stack.name }}/package.json - - - name: 📥 Install deps - run: npm install - working-directory: ${{ matrix.stack.name }} - - - name: 🔎 Type check - run: | - cd ${{ matrix.stack.name }} - npm run typecheck --if-present - - vitest: - name: ⚡ Vitest - if: github.repository == 'remix-run/remix' - needs: [setup] - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - stack: - - repo: "remix-run/indie-stack" - name: "indie" - - repo: "remix-run/blues-stack" - name: "blues" - - repo: "remix-run/grunge-stack" - name: "grunge" - steps: - - name: 🗄️ Restore ${{ matrix.stack.name }} - uses: actions/download-artifact@v4 - with: - name: ${{ matrix.stack.name }}-archive - - - name: 📁 Unzip artifact - run: unzip ${{ matrix.stack.name }}.zip - - - name: ⎔ Setup node and dependency caching - uses: actions/setup-node@v4 - with: - node-version: 18 - cache: npm - cache-dependency-path: ${{ matrix.stack.name }}/package.json - - - name: 📥 Install deps - run: npm install - working-directory: ${{ matrix.stack.name }} - - - name: ⚡ Run vitest - run: | - cd ${{ matrix.stack.name }} - npm run test -- --coverage - - cypress: - name: ⚫️ Cypress - if: github.repository == 'remix-run/remix' - needs: [setup] - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - stack: - - repo: "remix-run/indie-stack" - name: "indie" - cypress: "npm run start:mocks" - - repo: "remix-run/blues-stack" - name: "blues" - cypress: "npm run start:mocks" - - repo: "remix-run/grunge-stack" - name: "grunge" - cypress: "npm run dev" - steps: - - name: 🗄️ Restore ${{ matrix.stack.name }} - uses: actions/download-artifact@v4 - with: - name: ${{ matrix.stack.name }}-archive - - - name: 📁 Unzip artifact - run: unzip ${{ matrix.stack.name }}.zip - - - name: ⎔ Setup node and dependency caching - uses: actions/setup-node@v4 - with: - node-version: 18 - cache: npm - cache-dependency-path: ${{ matrix.stack.name }}/package.json - - - name: 📥 Install deps - run: npm install - working-directory: ${{ matrix.stack.name }} - - - name: 🐳 Docker compose - if: ${{ matrix.stack.name == 'blues' }} - # the sleep is just there to give time for postgres to get started - run: | - cd ${{ matrix.stack.name }} - docker-compose up -d && sleep 3 - env: - DATABASE_URL: "postgresql://postgres:postgres@localhost:5432/postgres" - - - name: 🛠 Setup Database - if: ${{ matrix.stack.name != 'grunge' }} - run: | - cd ${{ matrix.stack.name }} - npx prisma migrate reset --force - - - name: ⚙️ Build - run: | - cd ${{ matrix.stack.name }} - npm run build - - - name: 🌳 Cypress run - uses: cypress-io/github-action@v6 - with: - start: ${{ matrix.stack.cypress }} - wait-on: "http://localhost:8811" - working-directory: ${{ matrix.stack.name }} - env: - PORT: "8811" diff --git a/.github/workflows/test-full.yml b/.github/workflows/test-full.yml deleted file mode 100644 index 9eb2c9f9bad..00000000000 --- a/.github/workflows/test-full.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: Branch - -# main/dev/release-* branches and nightly tags will get the full run across -# all OS/browsers for multiple node versions - -on: - push: - branches: - - main - - dev - - release-* - tags: - - "v0.0.0-nightly-*" - paths-ignore: - - "docs/**" - - "scripts/**" - - "contributors.yml" - - "**/*.md" - -jobs: - build: - name: "⚙️ Build" - if: github.repository == 'remix-run/remix' - uses: ./.github/workflows/shared-build.yml - - unit-ubuntu: - name: "🧪 Unit Test" - if: github.repository == 'remix-run/remix' - uses: ./.github/workflows/shared-test-unit.yml - with: - os: "ubuntu-latest" - node_version: "[18, 20]" - - unit-windows: - name: "🧪 Unit Test" - if: github.repository == 'remix-run/remix' - uses: ./.github/workflows/shared-test-unit.yml - with: - os: "windows-latest" - node_version: "[18, 20]" - - integration-ubuntu: - name: "👀 Integration Test" - if: github.repository == 'remix-run/remix' - uses: ./.github/workflows/shared-test-integration.yml - with: - os: "ubuntu-latest" - node_version: "[18, 20]" - browser: '["chromium", "firefox"]' - - integration-windows: - name: "👀 Integration Test" - if: github.repository == 'remix-run/remix' - uses: ./.github/workflows/shared-test-integration.yml - with: - os: "windows-latest" - node_version: "[18, 20]" - browser: '["msedge"]' - - integration-macos: - name: "👀 Integration Test" - if: github.repository == 'remix-run/remix' - uses: ./.github/workflows/shared-test-integration.yml - with: - os: "macos-latest" - node_version: "[18, 20]" - browser: '["webkit"]' diff --git a/.github/workflows/test-pr-ubuntu.yml b/.github/workflows/test-pr-ubuntu.yml deleted file mode 100644 index 709a238e2c5..00000000000 --- a/.github/workflows/test-pr-ubuntu.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: PR (Base) - -# All PRs touching code will run tests on ubuntu/node/chromium - -on: - pull_request: - paths-ignore: - - "docs/**" - - "templates/**" - - "scripts/**" - - "contributors.yml" - - "**/*.md" - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build: - name: "⚙️ Build" - if: github.repository == 'remix-run/remix' - uses: ./.github/workflows/shared-build.yml - - unit-ubuntu: - name: "🧪 Unit Test" - if: github.repository == 'remix-run/remix' - uses: ./.github/workflows/shared-test-unit.yml - with: - os: "ubuntu-latest" - node_version: "[20]" - - integration-chromium: - name: "👀 Integration Test" - if: github.repository == 'remix-run/remix' - uses: ./.github/workflows/shared-test-integration.yml - with: - os: "ubuntu-latest" - node_version: "[20]" - browser: '["chromium"]' diff --git a/.github/workflows/test-pr-windows-macos.yml b/.github/workflows/test-pr-windows-macos.yml deleted file mode 100644 index c3f42de20f6..00000000000 --- a/.github/workflows/test-pr-windows-macos.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: PR (Full) - -# PRs touching create-remix/remix-dev will also run on Windows and OSX - -on: - pull_request: - paths: - - "packages/create-remix/**" - - "packages/remix-dev/**" - - "!**/*.md" - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - unit-windows: - name: "🧪 Unit Test" - if: github.repository == 'remix-run/remix' - uses: ./.github/workflows/shared-test-unit.yml - with: - os: "windows-latest" - node_version: "[20]" - - integration-firefox: - name: "👀 Integration Test" - if: github.repository == 'remix-run/remix' - uses: ./.github/workflows/shared-test-integration.yml - with: - os: "ubuntu-latest" - node_version: "[20]" - browser: '["firefox"]' - - integration-msedge: - name: "👀 Integration Test" - if: github.repository == 'remix-run/remix' - uses: ./.github/workflows/shared-test-integration.yml - with: - os: "windows-latest" - node_version: "[20]" - browser: '["msedge"]' - - integration-webkit: - name: "👀 Integration Test" - if: github.repository == 'remix-run/remix' - uses: ./.github/workflows/shared-test-integration.yml - with: - os: "macos-latest" - node_version: "[20]" - browser: '["webkit"]' diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml deleted file mode 100644 index 7d2c75af349..00000000000 --- a/.github/workflows/website.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: 🌐 Website - -on: - schedule: - # every hour - - cron: "0 * * * *" - push: - branches: [main, dev] - paths: [docs/**] - release: - types: [published] - -jobs: - website: - if: github.repository == 'remix-run/remix' - runs-on: ubuntu-latest - - steps: - - name: 🔄 Refresh the docs - uses: fjogeleit/http-request-action@v1 - with: - url: "${{ secrets.DOCS_REFRESH_URL }}?ref=${{ github.ref }}" - method: "POST" - customHeaders: '{"Authorization": "${{ secrets.DOCS_REFRESH_TOKEN }}"}' diff --git a/.gitignore b/.gitignore deleted file mode 100644 index eff078309b5..00000000000 --- a/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -.DS_Store - -/.env -/build/ -/packages/*/dist/ -/packages/*/LICENSE.md -node_modules/ -yarn-error.log -tsconfig.tsbuildinfo - -/jacob -/fixtures/cloudflare -/fixtures/test -/fixtures/my-remix-app -/fixtures/deno-app -/integration/playwright-report -/integration/test-results -/uploads - -.eslintcache -.tmp - -/scripts/deployment-test/apps -/scripts/deployment-test/package-lock.json -/scripts/deployment-test/yarn.lock -/scripts/deployment-test/pnpm-lock.yaml - -/.idea/ -/playground -/scripts/playground/template.local -/scripts/playground/template/build -/scripts/playground/template/package-lock.json -/scripts/playground/template/yarn.lock -/scripts/playground/template/pnpm-lock.yaml - -/NOTES.md -/RELEASENOTES.md diff --git a/.nvmrc b/.nvmrc index 3c032078a4a..2bd5a0a98a3 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18 +22 diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index f233a5aae6e..00000000000 --- a/.prettierignore +++ /dev/null @@ -1,2 +0,0 @@ -.changeset/*.md -pnpm-lock.yaml diff --git a/.vscode/README.md b/.vscode/README.md deleted file mode 100644 index 4adba632f9a..00000000000 --- a/.vscode/README.md +++ /dev/null @@ -1,5 +0,0 @@ -A note on `deno_resolve_npm_imports.json` - -The `"imports"` field in `deno_resolve_npm_imports.json` is used to resolve NPM imports for `packages/remix-deno`. This import map is used solely for the d`enoland.vscode-deno` extension. - -Remix does not support import maps. Dependency management is done through `npm` and `node_modules/` instead. Deno-only dependencies may be imported via URL imports (without using import maps). diff --git a/.vscode/deno_resolve_npm_imports.json b/.vscode/deno_resolve_npm_imports.json deleted file mode 100644 index c8e7dbc973b..00000000000 --- a/.vscode/deno_resolve_npm_imports.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "imports": { - "@remix-run/server-runtime": "https://esm.sh/@remix-run/server-runtime@nightly", - "mime": "https://esm.sh/mime@^3.0.0" - } -} diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index b91c276711f..00000000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "recommendations": [ - "dbaeumer.vscode-eslint", - "denoland.vscode-deno", - "esbenp.prettier-vscode" - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json index 885b1c44c63..25fa6215fdd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,3 @@ { - "typescript.tsdk": "node_modules/typescript/lib", - "deno.enablePaths": ["./packages/remix-deno/"], - "deno.importMap": "./.vscode/deno_resolve_npm_imports.json" + "typescript.tsdk": "node_modules/typescript/lib" } diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index fb99f18ad3b..00000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,2440 +0,0 @@ - - -# Remix Releases - -This page lists all releases/release notes for Remix back to `v2.0.0`. For releases prior to v2, please refer to the [Github Releases Page](https://github.com/remix-run/remix/releases). - -We manage release notes in this file instead of the paginated Github Releases Page for 2 reasons: - -- Pagination in the Github UI means that you cannot easily search release notes for a large span of releases at once -- The paginated Github interface also cuts off longer releases notes without indication in list view, and you need to click into the detail view to see the full set of release notes - -
- Table of Contents - -- [Remix Releases](#remix-releases) - - [v2.16.7](#v2167) - - [Patch Changes](#patch-changes) - - [v2.16.6](#v2166) - - [Patch Changes](#patch-changes-1) - - [v2.16.5](#v2165) - - [Patch Changes](#patch-changes-2) - - [v2.16.4](#v2164) - - [Patch Changes](#patch-changes-3) - - [v2.16.3](#v2163) - - [Security Notice](#security-notice) - - [Patch Changes](#patch-changes-4) - - [v2.16.2](#v2162) - - [Patch Changes](#patch-changes-5) - - [v2.16.1](#v2161) - - [Patch Changes](#patch-changes-6) - - [v2.16.0](#v2160) - - [Minor Changes](#minor-changes) - - [Patch Changes](#patch-changes-7) - - [Updated Dependencies](#updated-dependencies) - - [v2.15.3](#v2153) - - [Patch Changes](#patch-changes-8) - - [Updated Dependencies](#updated-dependencies-1) - - [v2.15.2](#v2152) - - [Patch Changes](#patch-changes-9) - - [Updated Dependencies](#updated-dependencies-2) - - [v2.15.1](#v2151) - - [Patch Changes](#patch-changes-10) - - [v2.15.0](#v2150) - - [Patch Changes](#patch-changes-11) - - [v2.14.0](#v2140) - - [Minor Changes](#minor-changes-1) - - [Patch Changes](#patch-changes-12) - - [Updated Dependencies](#updated-dependencies-3) - - [Changes by Package](#changes-by-package) - - [v2.13.1](#v2131) - - [Patch Changes](#patch-changes-13) - - [v2.13.0](#v2130) - - [What's Changed](#whats-changed) - - [Stabilized APIs](#stabilized-apis) - - [Minor Changes](#minor-changes-2) - - [Patch Changes](#patch-changes-14) - - [Updated Dependencies](#updated-dependencies-4) - - [Changes by Package](#changes-by-package-1) - - [v2.12.1](#v2121) - - [Patch Changes](#patch-changes-15) - - [Changes by Package](#changes-by-package-2) - - [v2.12.0](#v2120) - - [What's Changed](#whats-changed-1) - - [Future Flag for Automatic Dependency Optimization (unstable)](#future-flag-for-automatic-dependency-optimization-unstable) - - [Improved Single Fetch Type Safety (unstable)](#improved-single-fetch-type-safety-unstable) - - [Updates to Single Fetch Revalidation Behavior (unstable)](#updates-to-single-fetch-revalidation-behavior-unstable) - - [Minor Changes](#minor-changes-3) - - [Patch Changes](#patch-changes-16) - - [Updated Dependencies](#updated-dependencies-5) - - [Changes by Package](#changes-by-package-3) - - [v2.11.2](#v2112) - - [Patch Changes](#patch-changes-17) - - [Updated Dependencies](#updated-dependencies-6) - - [Changes by Package](#changes-by-package-4) - - [v2.11.1](#v2111) - - [Patch Changes](#patch-changes-18) - - [Changes by Package](#changes-by-package-5) - - [v2.11.0](#v2110) - - [What's Changed](#whats-changed-2) - - [Renamed `unstable_fogOfWar` future flag to `unstable_lazyRouteDiscovery` (unstable)](#renamed-unstable_fogofwar-future-flag-to-unstable_lazyroutediscovery-unstable) - - [Removed `response` stub in Single Fetch (unstable)](#removed-response-stub-in-single-fetch-unstable) - - [Minor Changes](#minor-changes-4) - - [Patch Changes](#patch-changes-19) - - [Updated Dependencies](#updated-dependencies-7) - - [Changes by Package](#changes-by-package-6) - - [v2.10.3](#v2103) - - [Patch Changes](#patch-changes-20) - - [Updated Dependencies](#updated-dependencies-8) - - [Changes by Package](#changes-by-package-7) - - [v2.10.2](#v2102) - - [Patch Changes](#patch-changes-21) - - [Changes by Package](#changes-by-package-8) - - [v2.10.1](#v2101) - - [Patch Changes](#patch-changes-22) - - [Updated Dependencies](#updated-dependencies-9) - - [Changes by Package](#changes-by-package-9) - - [v2.10.0](#v2100) - - [What's Changed](#whats-changed-3) - - [Lazy Route Discovery (a.k.a. "Fog of War")](#lazy-route-discovery-aka-fog-of-war) - - [Minor Changes](#minor-changes-5) - - [Patch Changes](#patch-changes-23) - - [Updated Dependencies](#updated-dependencies-10) - - [Changes by Package](#changes-by-package-10) - - [v2.9.2](#v292) - - [What's Changed](#whats-changed-4) - - [Updated Type-Safety for Single Fetch](#updated-type-safety-for-single-fetch) - - [Patch Changes](#patch-changes-24) - - [Updated Dependencies](#updated-dependencies-11) - - [Changes by Package](#changes-by-package-11) - - [v2.9.1](#v291) - - [Patch Changes](#patch-changes-25) - - [Changes by Package](#changes-by-package-12) - - [v2.9.0](#v290) - - [What's Changed](#whats-changed-5) - - [Single Fetch (unstable)](#single-fetch-unstable) - - [Undici](#undici) - - [Minor Changes](#minor-changes-6) - - [Patch Changes](#patch-changes-26) - - [Updated Dependencies](#updated-dependencies-12) - - [Changes by Package](#changes-by-package-13) - - [v2.8.1](#v281) - - [Patch Changes](#patch-changes-27) - - [Updated Dependencies](#updated-dependencies-13) - - [Changes by Package](#changes-by-package-14) - - [v2.8.0](#v280) - - [Minor Changes](#minor-changes-7) - - [Patch Changes](#patch-changes-28) - - [Updated Dependencies](#updated-dependencies-14) - - [Changes by Package](#changes-by-package-15) - - [2.7.2](#272) - - [Patch Changes](#patch-changes-29) - - [2.7.1](#271) - - [Patch Changes](#patch-changes-30) - - [v2.7.0](#v270) - - [What's Changed](#whats-changed-6) - - [Stabilized Vite Plugin](#stabilized-vite-plugin) - - [New `Layout` Export](#new-layout-export) - - [Basename support](#basename-support) - - [Cloudflare Proxy as a Vite Plugin](#cloudflare-proxy-as-a-vite-plugin) - - [Minor Changes](#minor-changes-8) - - [Patch Changes](#patch-changes-31) - - [Updated Dependencies](#updated-dependencies-15) - - [Changes by Package](#changes-by-package-16) - - [v2.6.0](#v260) - - [What's Changed](#whats-changed-7) - - [Unstable Vite Plugin updates](#unstable-vite-plugin-updates) - - [Minor Changes](#minor-changes-9) - - [Patch Changes](#patch-changes-32) - - [Updated Dependencies](#updated-dependencies-16) - - [Changes by Package](#changes-by-package-17) - - [v2.5.1](#v251) - - [Patch Changes](#patch-changes-33) - - [Updated Dependencies](#updated-dependencies-17) - - [Changes by Package](#changes-by-package-18) - - [v2.5.0](#v250) - - [What's Changed](#whats-changed-8) - - [SPA Mode (unstable)](#spa-mode-unstable) - - [Server Bundles (unstable)](#server-bundles-unstable) - - [Minor Changes](#minor-changes-10) - - [Patch Changes](#patch-changes-34) - - [Updated Dependencies](#updated-dependencies-18) - - [Changes by Package](#changes-by-package-19) - - [v2.4.1](#v241) - - [Patch Changes](#patch-changes-35) - - [Updated Dependencies](#updated-dependencies-19) - - [Changes by Package](#changes-by-package-20) - - [v2.4.0](#v240) - - [What's Changed](#whats-changed-9) - - [Client Data](#client-data) - - [`future.v3_relativeSplatPath`](#futurev3_relativesplatpath) - - [Vite Updates (Unstable)](#vite-updates-unstable) - - [Minor Changes](#minor-changes-11) - - [Patch Changes](#patch-changes-36) - - [Updated Dependencies](#updated-dependencies-20) - - [Changes by Package](#changes-by-package-21) - - [v2.3.1](#v231) - - [Patch Changes](#patch-changes-37) - - [Updated Dependencies](#updated-dependencies-21) - - [Changes by Package](#changes-by-package-22) - - [v2.3.0](#v230) - - [What's Changed](#whats-changed-10) - - [Stabilized `useBlocker`](#stabilized-useblocker) - - [`unstable_flushSync` API](#unstable_flushsync-api) - - [Minor Changes](#minor-changes-12) - - [Patch Changes](#patch-changes-38) - - [Updated Dependencies](#updated-dependencies-22) - - [Changes by Package](#changes-by-package-23) - - [v2.2.0](#v220) - - [What's Changed](#whats-changed-11) - - [Vite!](#vite) - - [New Fetcher APIs](#new-fetcher-apis) - - [Persistence Future Flag](#persistence-future-flag) - - [Minor Changes](#minor-changes-13) - - [Patch Changes](#patch-changes-39) - - [Updated Dependencies](#updated-dependencies-23) - - [Changes by Package](#changes-by-package-24) - - [v2.1.0](#v210) - - [What's Changed](#whats-changed-12) - - [View Transitions](#view-transitions) - - [Stable `createRemixStub`](#stable-createremixstub) - - [Minor Changes](#minor-changes-14) - - [Patch Changes](#patch-changes-40) - - [Updated Dependencies](#updated-dependencies-24) - - [Changes by Package](#changes-by-package-25) - - [v2.0.1](#v201) - - [Patch Changes](#patch-changes-41) - - [Changes by Package 🔗](#changes-by-package-) - - [v2.0.0](#v200) - - [Breaking Changes](#breaking-changes) - - [Upgraded Dependency Requirements](#upgraded-dependency-requirements) - - [Removed Future Flags](#removed-future-flags) - - [Breaking Changes/API Removals](#breaking-changesapi-removals) - - [With deprecation warnings](#with-deprecation-warnings) - - [Without deprecation warnings](#without-deprecation-warnings) - - [Breaking Type Changes](#breaking-type-changes) - - [New Features](#new-features) - - [Other Notable Changes](#other-notable-changes) - - [Updated Dependencies](#updated-dependencies-25) - - [Changes by Package](#changes-by-package-26) - -
- - - -## v2.16.7 - -Date: 2025-05-19 - -### Patch Changes - -- `@remix-run/dev` - Update `vite-node` ([#10611](https://github.com/remix-run/remix/pull/10611)) - -**Full Changelog**: [`v2.16.6...v2.16.7`](https://github.com/remix-run/remix/compare/remix@2.16.6...remix@2.16.7) - -## v2.16.6 - -Date: 2025-05-08 - -### Patch Changes - -- `@remix-run/react` - Upgrade `turbo-stream` to `2.4.1` ([#9973](https://github.com/remix-run/remix/pull/9973)) -- `@remix-run/react` - Fix `window is not defined` error in Single Fetch when server-rendering `` ([#10601](https://github.com/remix-run/remix/pull/10601)) -- `@remix-run/serve` - Remove redundant `@remix-run/node/install` import from `remix-serve` because it manually calls `installGlobals` separately ([#10306](https://github.com/remix-run/remix/pull/10306)) - -**Full Changelog**: [`v2.16.5...v2.16.6`](https://github.com/remix-run/remix/compare/remix@2.16.5...remix@2.16.6) - -## v2.16.5 - -Date: 2025-04-09 - -### Patch Changes - -- `@remix-run/node` - Bump `undici` to version `6.21.2` to address a [security advisory](https://github.com/nodejs/undici/security/advisories/GHSA-c76h-2ccp-4975) ([#10562](https://github.com/remix-run/remix/pull/10562)) - -**Full Changelog**: [`v2.16.4...v2.16.5`](https://github.com/remix-run/remix/compare/remix@2.16.4...remix@2.16.5) - -## v2.16.4 - -Date: 2025-03-31 - -### Patch Changes - -- `@remix-run/server-runtime` - Bump `cookie` dependency from `^0.6.0 -> ^0.7.2` to fix [security advisory](https://github.com/advisories/GHSA-pxg6-pf52-xh8x) ([#10547](https://github.com/remix-run/remix/pull/10547)) - -**Full Changelog**: [`v2.16.3...v2.16.4`](https://github.com/remix-run/remix/compare/remix@2.16.3...remix@2.16.4) - -## v2.16.3 - -Date: 2025-03-28 - -### Security Notice - -Fixed a security vulnerability that allowed URL manipulation and potential cache pollution via the `Host` and `X-Forwarded-Host` headers due to inadequate port sanitization. - -### Patch Changes - -- `@remix-run/express` - Better validation of `x-forwarded-host` header to prevent potential security issues ([#10553](https://github.com/remix-run/remix/pull/10553)) - -**Full Changelog**: [`v2.16.2...v2.16.3`](https://github.com/remix-run/remix/compare/remix@2.16.2...remix@2.16.3) - -## v2.16.2 - -Date: 2025-03-19 - -### Patch Changes - -- `@remix-run/react` - Fix `shouldRevalidate` behavior for `clientLoader`-only routes in `ssr:true` apps ([#10527](https://github.com/remix-run/remix/pull/10527)) -- `@remix-run/server-runtime` - Load ancestor pathless/index routes in lazy route discovery for upwards non-eager-discovery routing ([#10535](https://github.com/remix-run/remix/pull/10535)) - -**Full Changelog**: [`v2.16.1...v2.16.2`](https://github.com/remix-run/remix/compare/remix@2.16.1...remix@2.16.2) - -## v2.16.1 - -Date: 2025-03-17 - -### Patch Changes - -- `@remix-run/dev` - Remove unused Vite file system watcher ([#10510](https://github.com/remix-run/remix/pull/10510)) -- `@remix-run/dev` - When `future.v3_routeConfig` is enabled, fix errors evaluating `routes.ts` when multiple copies of `@remix-run/dev` are present ([#10524](https://github.com/remix-run/remix/pull/10524)) -- `@remix-run/dev` - Fix Vite import analysis of `@remix-run/react` failing when the package is not marked as external ([#10528](https://github.com/remix-run/remix/pull/10528)) - -**Full Changelog**: [`v2.16.0...v2.16.1`](https://github.com/remix-run/remix/compare/remix@2.16.0...remix@2.16.1) - -## v2.16.0 - -Date: 2025-02-27 - -### Minor Changes - -- `@remix-run/dev` - Add Vite v6 support ([#10351](https://github.com/remix-run/remix/pull/10351)) - -### Patch Changes - -- `@remix-run/dev` - Clean up vite-node dev server when build finishes ([#10477](https://github.com/remix-run/remix/pull/10477)) -- `@remix-run/react` - Don't apply Single Fetch revalidation de-optimization when in SPA mode since there is no server HTTP request ([#10479](https://github.com/remix-run/remix/pull/10479)) -- `@remix-run/react` - When using Lazy Route Discovery (`future.v3_lazyRouteDiscovery`), Remix will now detect manifest version mismatches after a new deploy and trigger a document reload to sync up any active client sessions with the newly deployed version ([#10498](https://github.com/remix-run/remix/pull/10498)) - - On navigations to undiscovered routes, this mismatch will trigger a document reload of the destination path - - On `fetcher` calls to undiscovered routes, this mismatch will trigger a document reload of the current path - - While performing Eager Route Discovery on rendered `` components, mismatches will result in a no-op - -### Updated Dependencies - -- [`react-router-dom@6.30.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.30.0) -- [`@remix-run/router@1.23.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1230) - -**Full Changelog**: [`v2.15.3...v2.16.0`](https://github.com/remix-run/remix/compare/remix@2.15.3...remix@2.16.0) - -## v2.15.3 - -Date: 2025-01-30 - -### Patch Changes - -- `@remix-run/react` - Properly handle interrupted manifest requests in lazy route discovery ([#10447](https://github.com/remix-run/remix/pull/10447)) -- `@remix-run/server-runtime` - Avoid duplication of `Set-Cookie` headers if also returned from `headers` ([#10424](https://github.com/remix-run/remix/pull/10424)) -- `@remix-run/server-runtime` - Properly handle status codes that cannot have a body in single fetch responses (204, etc.) ([#10410](https://github.com/remix-run/remix/pull/10410)) - -### Updated Dependencies - -- [`react-router-dom@6.29.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.29.0) -- [`@remix-run/router@1.22.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1220) - -**Full Changelog**: [`v2.15.2...v2.15.3`](https://github.com/remix-run/remix/compare/remix@2.15.2...remix@2.15.3) - -## v2.15.2 - -Date: 2024-12-20 - -### Patch Changes - -- `@remix-run/dev` - Allow suppression of future flag warnings by setting them to `false` ([#10358](https://github.com/remix-run/remix/pull/10358)) -- `@remix-run/react` - Throw unwrapped Single Fetch `redirect` to align with pre-Single Fetch behavior ([#10317](https://github.com/remix-run/remix/pull/10317)) - -### Updated Dependencies - -- [`react-router-dom@6.28.1`](https://github.com/remix-run/react-router/releases/tag/react-router%406.28.1) - -**Full Changelog**: [`v2.15.1...v2.15.2`](https://github.com/remix-run/remix/compare/remix@2.15.1...remix@2.15.2) - -## v2.15.1 - -Date: 2024-12-09 - -### Patch Changes - -- `create-remix` - Move `fs-extra` from `devDependencies` to `dependencies` ([#10300](https://github.com/remix-run/remix/pull/10300)) - -**Full Changelog**: [`v2.15.0...v2.15.1`](https://github.com/remix-run/remix/compare/remix@2.15.0...remix@2.15.1) - -## v2.15.0 - -Date: 2024-11-19 - -### Patch Changes - -- Stabilize the `future.v3_routeConfig` future flag, replacing `future.unstable_routeConfig`. This enables support for `routes.ts` to assist with the migration to React Router v7. ([#10236](https://github.com/remix-run/remix/pull/10236)) - - Note that if you had already enabled the `future.unstable_routeConfig` flag, your route config in `app/routes.ts` is no longer defined via the `routes` export and must now be defined via the default export. - - ```diff - import { type RouteConfig } from "@remix-run/route-config"; - - -export const routes: RouteConfig = []; - +export default [] satisfies RouteConfig; - ``` - -## v2.14.0 - -Date: 2024-11-08 - -### Minor Changes - -- Deprecate `SerializeFrom` in favor of generics because it will be removed in React Router v7 ([#10173](https://github.com/remix-run/remix/pull/10173)) -- Add deprecation warning to `@remix-run/eslint-config` ([#10174](https://github.com/remix-run/remix/pull/10174)) -- Add support for `routes.ts` behind `future.unstable_routeConfig` flag to assist with the migration to React Router v7. ([#10107](https://github.com/remix-run/remix/pull/10107)) - - Config-based routing is the new default in React Router v7, configured via the `routes.ts` file in the app directory. Support for `routes.ts` and its related APIs in Remix are designed as a migration path to help minimize the number of changes required when moving your Remix project over to React Router v7. While some new packages have been introduced within the `@remix-run` scope, these new packages only exist to keep the code in `routes.ts` as similar as possible to the equivalent code for React Router v7. - - When the `unstable_routeConfig` future flag is enabled, Remix's built-in file system routing will be disabled and your project will opted into React Router v7's config-based routing. - - To enable the flag, in your `vite.config.ts` file: - - ```ts - remix({ - future: { - unstable_routeConfig: true, - }, - }); - ``` - - A minimal `routes.ts` file to support Remix's built-in file system routing looks like this: - - ```ts - // app/routes.ts - import { flatRoutes } from "@remix-run/fs-routes"; - import type { RouteConfig } from "@remix-run/route-config"; - - export const routes: RouteConfig = flatRoutes(); - ``` - -- Log deprecation warnings for v3 future flags ([#10126](https://github.com/remix-run/remix/pull/10126)) - - Add `@deprecated` annotations to `json`/`defer` utilities - -### Patch Changes - -- `@remix-run/react` - Fix `defaultShouldRevalidate` value when using Single Fetch ([#10139](https://github.com/remix-run/remix/pull/10139)) -- `@remix-run/server-runtime` - Update externally-accessed resource routes warning to cover `null` usage as well ([#10145](https://github.com/remix-run/remix/pull/10145)) - -### Updated Dependencies - -- [`react-router-dom@6.28.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.28.0) -- [`@remix-run/router@1.21.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1210) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/create-remix/CHANGELOG.md#2140) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-architect/CHANGELOG.md#2140) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-cloudflare/CHANGELOG.md#2140) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-cloudflare-pages/CHANGELOG.md#2140) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-cloudflare-workers/CHANGELOG.md#2140) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-css-bundle/CHANGELOG.md#2140) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-deno/CHANGELOG.md#2140) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-dev/CHANGELOG.md#2140) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-eslint-config/CHANGELOG.md#2140) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-express/CHANGELOG.md#2140) -- [`@remix-run/fs-routes`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-fs-routes/CHANGELOG.md#2140) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-node/CHANGELOG.md#2140) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-react/CHANGELOG.md#2140) -- [`@remix-run/route-config`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-route-config/CHANGELOG.md#2140) -- [`@remix-run/routes-option-adapter`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-routes-option-adapter/CHANGELOG.md#2140) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-serve/CHANGELOG.md#2140) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-server-runtime/CHANGELOG.md#2140) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.14.0/packages/remix-testing/CHANGELOG.md#2140) - -**Full Changelog**: [`v2.13.1...v2.14.0`](https://github.com/remix-run/remix/compare/remix@2.13.1...remix@2.14.0) - -## v2.13.1 - -Date: 2024-10-11 - -### Patch Changes - -- `@remix-run/dev` - Revert `future.v3_optimizeDeps` back to `future.unstable_optimizeDeps` as it was not intended to stabilize in Remix v2 ([#10099](https://github.com/remix-run/remix/pull/10099)) - -**Full Changelog**: [`v2.13.0...v2.13.1`](https://github.com/remix-run/remix/compare/remix@2.13.0...remix@2.13.1) - -## v2.13.0 - -Date: 2024-10-11 - -### What's Changed - -#### Stabilized APIs - -This release stabilizes a handful of "unstable" APIs in preparation for the [pending](https://x.com/remix_run/status/1841926034868077009) React Router v7 release (see [these](https://remix.run/blog/merging-remix-and-react-router) [posts](https://remix.run/blog/incremental-path-to-react-19) for more info): - -- `unstable_data` → `data` (for use with Single Fetch) -- `unstable_flushSync` → `flushSync` (`useSubmit`, `fetcher.load`, `fetcher.submit`) -- `unstable_viewTransition` → `viewTransition` (``, `
`, `useNavigate`, `useSubmit`) -- ~~`future.unstable_optimizeDeps` → `future.v3_optimizeDeps` ([Docs](https://remix.run/docs/en/main/guides/dependency-optimization))~~ - - ⚠️ This flag was not intended to stabilize in Remix v2 and was reverted back to `future.unstable_optimizeDeps` in `2.13.1` -- `future.unstable_lazyRouteDiscovery` → `future.v3_lazyRouteDiscovery` ([Docs](https://remix.run/docs/guides/lazy-route-discovery)) -- `future.unstable_singleFetch` → `future.v3_singleFetch` ([Docs](https://remix.run/docs/guides/single-fetch)) - -### Minor Changes - -- Stabilize React Router APIs in Remix ([#9980](https://github.com/remix-run/remix/pull/9980)) - - Adopt stabilized React Router APIs internally - - Single Fetch: `unstable_dataStrategy` -> `dataStrategy` - - Lazy Route Discovery: `unstable_patchRoutesOnNavigation` -> `patchRoutesOnNavigation` - - Stabilize public-facing APIs - - Single Fetch: `unstable_data()` -> `data()` - - `unstable_viewTransition` -> `viewTransition` (`Link`, `Form`, `navigate`, `submit`) - - `unstable_flushSync>` -> `` (`Link`, `Form`, `navigate`, `submit`, `useFetcher`) -- Stabilize future flags ([#10072](https://github.com/remix-run/remix/pull/10072), [#10092](https://github.com/remix-run/remix/pull/10092)) - - `future.unstable_lazyRouteDiscovery` -> `future.v3_lazyRouteDiscovery` - - `future.unstable_optimizeDeps` -> `future.v3_optimizeDeps` - - `future.unstable_singleFetch` -> `future.v3_singleFetch` - -### Patch Changes - -- `@remix-run/dev` - Stop passing `request.signal` as the `renderToReadableStream` `signal` to abort server rendering for cloudflare/deno runtimes because by the time that `request` is aborted, aborting the rendering is useless because there's no way for React to flush down the unresolved boundaries ([#10047](https://github.com/remix-run/remix/pull/10047)) - - This has been incorrect for some time, but only recently exposed due to a bug in how we were aborting requests when running via `remix vite:dev` because we were incorrectly aborting requests after successful renders - which was causing us to abort a completed React render, and try to close an already closed `ReadableStream` - - This has likely not shown up in any production scenarios because cloudflare/deno production runtimes are (correctly) not aborting the `request.signal` on successful renders - - The built-in `entry.server` files no longer pass a `signal` to `renderToReadableStream` because adding a timeout-based abort signal to the default behavior would constitute a breaking change - - Users can configure this abort behavior via their own `entry.server` via `remix reveal entry.server`, and the template entry.server files have been updated with an example approach for newly created Remix apps -- `@remix-run/express` - Fix adapter logic for aborting `request.signal` so we don't incorrectly abort on the `close` event for successful requests ([#10046](https://github.com/remix-run/remix/pull/10046)) -- `@remix-run/react` - Fix bug with `clientLoader.hydrate` in a layout route when hydrating with bubbled errors ([#10063](https://github.com/remix-run/remix/pull/10063)) - -### Updated Dependencies - -- [`react-router-dom@6.27.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.27.0) -- [`@remix-run/router@1.20.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1200) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/create-remix/CHANGELOG.md#2130) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/remix-architect/CHANGELOG.md#2130) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/remix-cloudflare/CHANGELOG.md#2130) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/remix-cloudflare-pages/CHANGELOG.md#2130) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/remix-cloudflare-workers/CHANGELOG.md#2130) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/remix-css-bundle/CHANGELOG.md#2130) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/remix-deno/CHANGELOG.md#2130) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/remix-dev/CHANGELOG.md#2130) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/remix-eslint-config/CHANGELOG.md#2130) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/remix-express/CHANGELOG.md#2130) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/remix-node/CHANGELOG.md#2130) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/remix-react/CHANGELOG.md#2130) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/remix-serve/CHANGELOG.md#2130) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/remix-server-runtime/CHANGELOG.md#2130) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.13.0/packages/remix-testing/CHANGELOG.md#2130) - -**Full Changelog**: [`v2.12.1...v2.13.0`](https://github.com/remix-run/remix/compare/remix@2.12.1...remix@2.13.0) - -## v2.12.1 - -Date: 2024-09-19 - -### Patch Changes - -- `@remix-run/dev` - Properly abort `request.signal` during `vite dev` when the node response is closed ([#9976](https://github.com/remix-run/remix/pull/9976)) -- `@remix-run/dev` - CSS imports with `?inline`, `?inline-css` and `?raw` are no longer incorrectly injected during SSR in development ([#9910](https://github.com/remix-run/remix/pull/9910)) -- `@remix-run/server-runtime`: Single Fetch: Fix types when `loader`, `action`, `clientLoader`, or `clientAction` return a mixture of bare objects, `json(...)`, `defer(...)`, and `unstable_data(...)`. ([#9999](https://github.com/remix-run/remix/pull/9999)) -- `@remix-run/node`/`@remix-run/cloudflare`/`@remix-run/deno` - Single Fetch: Re-export `interface Future` through runtime packages so that `pnpm` doesn't complain about `@remix-run/server-runtime` not being a dependency ([#9982](https://github.com/remix-run/remix/pull/9982)) - - If you've already opted into Single Fetch, you can change your [Single Fetch type augmentation](https://remix.run/docs/guides/single-fetch#enable-single-fetch-types) in `vite.config.ts` to augment `@remix-run/node` (or `cloudflare`/`deno`) instead of `@remix-run/server-runtime` - -### Changes by Package - -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.12.0/packages/remix-cloudflare/CHANGELOG.md#2121) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.12.0/packages/remix-deno/CHANGELOG.md#2121) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.12.0/packages/remix-dev/CHANGELOG.md#2121) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.12.0/packages/remix-node/CHANGELOG.md#2121) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.12.0/packages/remix-server-runtime/CHANGELOG.md#2121) - -**Full Changelog**: [`v2.12.0...v2.12.1`](https://github.com/remix-run/remix/compare/remix@2.12.0...remix@2.12.1) - -## v2.12.0 - -Date: 2024-09-09 - -### What's Changed - -#### Future Flag for Automatic Dependency Optimization (unstable) - -You can now opt-in to automatic dependency optimization during development by using the `future.unstable_optimizeDeps` future flag. For details, check out the docs at [Guides > Dependency optimization](https://remix.run/docs/en/main/guides/dependency-optimization). For users who were previously working around this limitation, you no longer need to explicitly add routes to Vite's `optimizeDeps.entries` nor do you need to disable the `remix-dot-server` plugin. - -#### Improved Single Fetch Type Safety (unstable) - -- If you were already using single-fetch types: - - Remove the `"@remix-run/react/future/single-fetch.d.ts"` override from `tsconfig.json` > `compilerOptions` > `types` - - Remove `defineLoader`, `defineAction`, `defineClientLoader`, `defineClientAction` helpers from your route modules - - Replace `UIMatch_SingleFetch` type helper with the original `UIMatch` - - Replace `MetaArgs_SingleFetch` type helper with the original `MetaArgs` - -Then you are ready for the new type safety setup: - -```ts -// vite.config.ts - -declare module "@remix-run/server-runtime" { - interface Future { - unstable_singleFetch: true; // 👈 enable _types_ for single-fetch - } -} - -export default defineConfig({ - plugins: [ - remix({ - future: { - unstable_singleFetch: true, // 👈 enable single-fetch - }, - }), - ], -}); -``` - -For more information, see [Guides > Single Fetch](https://remix.run/docs/guides/single-fetch) in our docs. - -#### Updates to Single Fetch Revalidation Behavior (unstable) - -With Single Fetch, re-used routes will now revalidate by default on `GET` navigations. This is aimed at improving caching of Single Fetch calls in the simple case while still allowing users to opt-into the previous behavior for more advanced use cases. - -With this new behavior, requests do not need special query params for granular route revalidations out of the box - i.e., `GET /a/b/c.data` - -There are two conditions that will trigger granular revalidation and will exclude certain routes from the single fetch call: - -- If a route opts out of revalidation via `shouldRevalidate` -- If a route defines a `clientLoader` - - If you call `serverLoader()` from your `clientLoader`, that will make a separate HTTP call for just that route loader - i.e., `GET /a/b/c.data?_routes=routes/a` for a `clientLoader` in `routes/a.tsx` - -When one or more routes are excluded from the Single Fetch call, the remaining routes that have loaders are included as query params. For example, when navigating to `/a/b/c`, if A was excluded, and the `root` route and `routes/b` had a `loader` but `routes/c` did not, the Single Fetch request would be `GET /a/b/c.data?_routes=root,routes/b`. - -For more information, see [Guides > Single Fetch](https://remix.run/docs/guides/single-fetch) in our docs. - -### Minor Changes - -- `@remix-run/dev` - New `future.unstable_optimizeDeps` flag for automatic dependency optimization ([#9921](https://github.com/remix-run/remix/pull/9921)) - -### Patch Changes - -- `@remix-run/dev` - Handle circular dependencies in modulepreload manifest generation ([#9917](https://github.com/remix-run/remix/pull/9917)) -- `@remix-run/dev` - Fix `dest already exists` build errors by only moving SSR assets to the client build directory when they're not already present on disk ([#9901](https://github.com/remix-run/remix/pull/9901)) -- `@remix-run/react` - Clarify wording in default `HydrateFallback` console warning ([#9899](https://github.com/remix-run/remix/pull/9899)) -- `@remix-run/react` - Remove hydration URL check that was originally added for React 17 hydration issues and we no longer support React 17 ([#9890](https://github.com/remix-run/remix/pull/9890)) - - Reverts the logic originally added in Remix `v1.18.0` via [#6409](https://github.com/remix-run/remix/pull/6409) - - This was added to resolve an issue that could arise when doing quick back/forward history navigations while JS was loading which would cause a mismatch between the server matches and client matches: [#1757](https://github.com/remix-run/remix/issues/1757) - - This specific hydration issue would then cause this React v17 only looping issue: [#1678](https://github.com/remix-run/remix/issues/1678) - - The URL comparison that we added in `1.18.0` turned out to be subject to false positives of it's own which could also put the user in looping scenarios - - Remix v2 upgraded it's minimal React version to v18 which eliminated the v17 hydration error loop - - React v18 handles this hydration error like any other error and does not result in a loop - - So we can remove our check and thus avoid the false-positive scenarios in which it may also trigger a loop -- `@remix-run/react` - Lazy Route Discovery: Sort `/__manifest` query parameters for better caching ([#9888](https://github.com/remix-run/remix/pull/9888)) -- `@remix-run/react` - Single Fetch: Improved type safety ([#9893](https://github.com/remix-run/remix/pull/9893)) -- `@remix-run/react` - Single Fetch: Fix revalidation behavior bugs ([#9938](https://github.com/remix-run/remix/pull/9938)) -- `@remix-run/server-runtime` - Do not render or try to include a body for 304 responses on document requests ([#9955](https://github.com/remix-run/remix/pull/9955)) -- `@remix-run/server-runtime` - Single Fetch: Do not try to encode a `turbo-stream` body into 304 responses ([#9941](https://github.com/remix-run/remix/pull/9941)) -- `@remix-run/server-runtime` - Single Fetch: Change content type on `.data` requests to `text/x-script` to allow Cloudflare compression ([#9889](https://github.com/remix-run/remix/pull/9889)) - -### Updated Dependencies - -- [`react-router-dom@6.26.2`](https://github.com/remix-run/react-router/releases/tag/react-router%406.26.2) -- [`@remix-run/router@1.19.2`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1192) - -### Changes by Package - -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.12.0/packages/remix-dev/CHANGELOG.md#2120) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.12.0/packages/remix-react/CHANGELOG.md#2120) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.12.0/packages/remix-server-runtime/CHANGELOG.md#2120) - -**Full Changelog**: [`v2.11.2...v2.12.0`](https://github.com/remix-run/remix/compare/remix@2.11.2...remix@2.12.0) - -## v2.11.2 - -Date: 2024-08-15 - -### Patch Changes - -- `@remix-run/react` - Fog of War: Simplify implementation now that React Router handles slug/splat edge cases and tracks previously discovered routes (see https://github.com/remix-run/react-router/pull/11883) ([#9860](https://github.com/remix-run/remix/pull/9860)) - - ⚠️ This changes the return signature of the internal `/__manifest` endpoint since we no longer need the `notFoundPaths` field -- `@remix-run/react` - Fog of War: Update to use renamed `unstable_patchRoutesOnNavigation` function in RR (see https://github.com/remix-run/react-router/pull/11888) ([#9860](https://github.com/remix-run/remix/pull/9860)) -- `@remix-run/server-runtime` - Single Fetch: Fix redirects when a `basename` is present ([#9848](https://github.com/remix-run/remix/pull/9848)) -- `@remix-run/server-runtime` - Single Fetch: Update `turbo-stream` to `v2.3.0` ([#9856](https://github.com/remix-run/remix/pull/9856)) - - Stabilize object key order for serialized payloads - - Remove memory limitations payloads sizes - -### Updated Dependencies - -- [`react-router-dom@6.26.1`](https://github.com/remix-run/react-router/releases/tag/react-router%406.26.1) -- [`@remix-run/router@1.19.1`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1191) - -### Changes by Package - -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.11.2/packages/remix-react/CHANGELOG.md#2112) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.11.2/packages/remix-server-runtime/CHANGELOG.md#2112) - -**Full Changelog**: [`v2.11.1...v2.11.2`](https://github.com/remix-run/remix/compare/remix@2.11.1...remix@2.11.2) - -## v2.11.1 - -Date: 2024-08-05 - -### Patch Changes - -- `@remix-run/react` - Revert #9695, stop infinite reload ([`a7cffe57`](https://github.com/remix-run/remix/commit/a7cffe5733c8b7d0f29bd2d8606876c537d87101)) - -### Changes by Package - -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.11.1/packages/remix-react/CHANGELOG.md#2111) - -**Full Changelog**: [`v2.11.0...v2.11.1`](https://github.com/remix-run/remix/compare/remix@2.11.0...remix@2.11.1) - -## v2.11.0 - -Date: 2024-08-01 - -### What's Changed - -#### Renamed `unstable_fogOfWar` future flag to `unstable_lazyRouteDiscovery` (unstable) - -We found that the `future.unstable_fogOfWar` flag name could be a bit confusing without the proper context (notably, the [blog post](https://remix.run/blog/fog-of-war)), so we've renamed the flag to `future.unstable_lazyRouteDiscovery` for clarity. If you had opted into this feature already, please update the name of the flag in your `vite.config.ts` file (or `remix.config.js`). - -#### Removed `response` stub in Single Fetch (unstable) - -The original Single Fetch approach was based on an assumption that an eventual `middleware` implementation would require something like the `ResponseStub` API so users could mutate `status`/`headers` in `middleware` before/after handlers as well as during handlers. As part of Single Fetch, we wanted to align how response headers would be merged between document and data requests. Thinking `response` was the future API, we aligned document requests to use the `response` stub that data requests were using, and we stopped using the `headers()` function. - -However, the realization/alignment between Michael and Ryan on the recent [roadmap planning](https://www.youtube.com/watch?v=f5z_axCofW0) made us realize that the original assumption was incorrect. `middleware` won't need a `response` stub - as users can just mutate the `Response` they get from `await next()` directly. - -Removing that assumption, and still wanting to align how headers get merged between document and data requests, it makes more sense to stick with the current `headers()` API and align Single Fetch data requests to use that existing API. This was we don't need to introduce any new header-related APIs which will make the adoption of Single Fetch much easier. - -With this change: - -- The `headers()` function will let you control header merging for both document and data requests -- In most cases, if you were returning `json()`/`defer()` _without_ setting a custom `status` or `headers`, you can just remove those utility functions and return the raw data - - ❌ `return json({ data: "whatever" });` - - ✅ `return { data: "whatever" };` -- If you _were_ returning a custom `status` or `headers` via `json`/`defer`: - - We've added a new API-compatible [`unstable_data`](https://remix.run/docs/utils/data) utility that will let you send back `status`/`headers` alongside your raw data without having to encode it into a `Response` -- We will be removing both `json` and `defer` in the next major version, but both _should_ still work in Single Fetch in v2 to allow for incremental adoption of the new behavior - -⚠️ If you've already adopted Single Fetch in it's unstable state and converted to `response` stub, you'll need to move those changes back to leveraging the `headers()` API. - -### Minor Changes - -- `@remix-run/dev` - Fog of War: Rename `future.unstable_fogOfWar` to `future.unstable_lazyRouteDiscovery` for clarity ([#9763](https://github.com/remix-run/remix/pull/9763)) -- `@remix-run/server-runtime` - Add a new `replace(url, init?)` alternative to `redirect(url, init?)` that performs a `history.replaceState` instead of a `history.pushState` on client-side navigation redirects ([#9764](https://github.com/remix-run/remix/pull/9764)) -- `@remix-run/server-runtime` - Single Fetch: Add a new `unstable_data()` API as a replacement for `json`/`defer` when custom `status`/`headers` are needed ([#9769](https://github.com/remix-run/remix/pull/9769)) -- `@remix-run/server-runtime` - Single Fetch: Remove `responseStub` in favor of `headers` ([#9769](https://github.com/remix-run/remix/pull/9769)) - -### Patch Changes - -- `@remix-run/dev` - Handle absolute Vite base URLs ([#9700](https://github.com/remix-run/remix/pull/9700)) -- `@remix-run/react` - Change initial hydration route mismatch from a URL check to a matches check to be resistant to URL inconsistencies ([#9695](https://github.com/remix-run/remix/pull/9695)) -- `@remix-run/react` - Single Fetch: Ensure calls don't include any trailing slash from the pathname (i.e., `/path/.data`) ([#9792](https://github.com/remix-run/remix/pull/9792)) -- `@remix-run/react` - Single Fetch: Add `undefined` to the `useRouteLoaderData` type override ([#9796](https://github.com/remix-run/remix/pull/9796)) - -### Updated Dependencies - -- [`react-router-dom@6.26.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.26.0) -- [`@remix-run/router@1.19.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1190) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/create-remix/CHANGELOG.md#2110) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/remix-architect/CHANGELOG.md#2110) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/remix-cloudflare/CHANGELOG.md#2110) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/remix-cloudflare-pages/CHANGELOG.md#2110) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/remix-cloudflare-workers/CHANGELOG.md#2110) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/remix-css-bundle/CHANGELOG.md#2110) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/remix-deno/CHANGELOG.md#2110) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/remix-dev/CHANGELOG.md#2110) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/remix-eslint-config/CHANGELOG.md#2110) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/remix-express/CHANGELOG.md#2110) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/remix-node/CHANGELOG.md#2110) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/remix-react/CHANGELOG.md#2110) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/remix-serve/CHANGELOG.md#2110) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/remix-server-runtime/CHANGELOG.md#2110) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.11.0/packages/remix-testing/CHANGELOG.md#2110) - -**Full Changelog**: [`v2.10.3...v2.11.0`](https://github.com/remix-run/remix/compare/remix@2.10.3...remix@2.11.0) - -## v2.10.3 - -Date: 2024-07-16 - -### Patch Changes - -- `@remix-run/architect` - Manually joining headers with semi-colons to avoid differences in Remix and node/undici Headers implementation ([#9664](https://github.com/remix-run/remix/pull/9664)) -- `@remix-run/react` - Log any errors encountered loading a route module prior to reloading the page ([#8932](https://github.com/remix-run/remix/pull/8932)) -- `@remix-run/react` - Single Fetch (unstable): Proxy `request.signal` through `dataStrategy` for `loader` calls to fix cancellation ([#9738](https://github.com/remix-run/remix/pull/9738)) -- `@remix-run/react` - Single Fetch (unstable): Adopt React Router's stabilized `future.v7_skipActionErrorRevalidation` under the hood ([#9706](https://github.com/remix-run/remix/pull/9706)) - - This stabilizes the `shouldRevalidate` parameter from `unstable_actionStatus` to `actionStatus` - - ⚠️ This might be a breaking change for your app if you have opted into single fetch and the `unstable_actionStatus` parameter - -### Updated Dependencies - -- [`react-router-dom@6.25.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.25.0) -- [`@remix-run/router@1.18.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1180) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/create-remix/CHANGELOG.md#2103) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-architect/CHANGELOG.md#2103) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-cloudflare/CHANGELOG.md#2103) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-cloudflare-pages/CHANGELOG.md#2103) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-cloudflare-workers/CHANGELOG.md#2103) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-css-bundle/CHANGELOG.md#2103) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-deno/CHANGELOG.md#2103) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-dev/CHANGELOG.md#2103) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-eslint-config/CHANGELOG.md#2103) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-express/CHANGELOG.md#2103) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-node/CHANGELOG.md#2103) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-react/CHANGELOG.md#2103) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-serve/CHANGELOG.md#2103) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-server-runtime/CHANGELOG.md#2103) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-testing/CHANGELOG.md#2103) - -**Full Changelog**: [`v2.10.2...v2.10.3`](https://github.com/remix-run/remix/compare/remix@2.10.2...remix@2.10.3) - -## v2.10.2 - -Date: 2024-07-04 - -### Patch Changes - -- `@remix-run/react` - Forward `ref` to `Form` ([`bdd04217`](https://github.com/remix-run/remix/commit/bdd04217713292307078a30dab9033926d48ede6)) -- `@remix-run/server-runtime` - Fix bug with `immutable` headers on raw native `fetch` responses returned from loaders ([#9693](https://github.com/remix-run/remix/pull/9693)) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/create-remix/CHANGELOG.md#2102) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-architect/CHANGELOG.md#2102) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-cloudflare/CHANGELOG.md#2102) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-cloudflare-pages/CHANGELOG.md#2102) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-cloudflare-workers/CHANGELOG.md#2102) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-css-bundle/CHANGELOG.md#2102) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-deno/CHANGELOG.md#2102) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-dev/CHANGELOG.md#2102) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-eslint-config/CHANGELOG.md#2102) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-express/CHANGELOG.md#2102) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-node/CHANGELOG.md#2102) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-react/CHANGELOG.md#2102) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-serve/CHANGELOG.md#2102) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-server-runtime/CHANGELOG.md#2102) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-testing/CHANGELOG.md#2102) - -**Full Changelog**: [`v2.10.1...v2.10.2`](https://github.com/remix-run/remix/compare/remix@2.10.1...remix@2.10.2) - -## v2.10.1 - -Date: 2024-07-03 - -### Patch Changes - -- `@remix-run/react` - Fog of War (unstable): Support route discovery from `` components ([#9665](https://github.com/remix-run/remix/pull/9665)) -- `@remix-run/react` - Fog of War (unstable): Don't discover links/forms with `reloadDocument` ([#9686](https://github.com/remix-run/remix/pull/9686)) - -### Updated Dependencies - -- [`react-router-dom@6.24.1`](https://github.com/remix-run/react-router/releases/tag/react-router%406.24.1) -- [`@remix-run/router@1.17.1`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1171) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/create-remix/CHANGELOG.md#2101) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/remix-architect/CHANGELOG.md#2101) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/remix-cloudflare/CHANGELOG.md#2101) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/remix-cloudflare-pages/CHANGELOG.md#2101) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/remix-cloudflare-workers/CHANGELOG.md#2101) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/remix-css-bundle/CHANGELOG.md#2101) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/remix-deno/CHANGELOG.md#2101) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/remix-dev/CHANGELOG.md#2101) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/remix-eslint-config/CHANGELOG.md#2101) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/remix-express/CHANGELOG.md#2101) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/remix-node/CHANGELOG.md#2101) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/remix-react/CHANGELOG.md#2101) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/remix-serve/CHANGELOG.md#2101) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/remix-server-runtime/CHANGELOG.md#2101) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.10.1/packages/remix-testing/CHANGELOG.md#2101) - -**Full Changelog**: [`v2.10.0...v2.10.1`](https://github.com/remix-run/remix/compare/remix@2.10.0...remix@2.10.1) - -## v2.10.0 - -Date: 2024-06-25 - -### What's Changed - -#### Lazy Route Discovery (a.k.a. "Fog of War") - -The "Fog of War" feature in Remix, now available through the `future.unstable_fogOfWar` flag, is an optimization to reduce the up front size of the Remix route manifest. In most scenarios the Remix route manifest isn't prohibitively large so as to impact initial perf metrics, but at scale we've found that some apps can generate large manifests that are expensive to download and execute on app startup. - -When Fog of War is enabled, Remix will only include the initially server-rendered routes in the manifest and then it will fetch manifest "patches" for outgoing links as the user navigates around. By default, to avoid waterfalls Remix fetches patches for all rendered links, so that in the ideal case they've already been patched in prior to being clicked. If a user clicks a link before this eager discovery completes, then a small waterfall will occur to first "discover" the route, and then navigate to the route. - -Enabling this flag should require no application code changes. For more information, please see the [documentation](https://remix.run/docs/guides/fog-of-war). - -### Minor Changes - -- Add support for Lazy Route Discovery (a.k.a. Fog of War) ([#9600](https://github.com/remix-run/remix/pull/9600), [#9619](https://github.com/remix-run/remix/pull/9619)) - -### Patch Changes - -- `@remix-run/{dev|express|serve}` - Upgrade `express` dependency to `^4.19.2` ([#9184](https://github.com/remix-run/remix/pull/9184)) -- `@remix-run/react` - Don't prefetch server `loader` data when `clientLoader` exists ([#9580](https://github.com/remix-run/remix/pull/9580)) -- `@remix-run/react` - Avoid hydration loops when `Layout`/`ErrorBoundary` renders also throw ([#9566](https://github.com/remix-run/remix/pull/9566)) -- `@remix-run/react` - Fix a hydration bug when using child routes and `HydrateFallback` components with a `basename` ([#9584](https://github.com/remix-run/remix/pull/9584)) -- `@remix-run/{server-runtime|react}` - Single Fetch: Update to `turbo-stream@2.2.0` ([#9562](https://github.com/remix-run/remix/pull/9562)) -- `@remix-run/server-runtime` - Single Fetch: Properly handle thrown 4xx/5xx response stubs ([#9501](https://github.com/remix-run/remix/pull/9501)) -- `@remix-run/server-runtime` - Single Fetch: Change redirects to use a 202 status to avoid automatic caching ([#9564](https://github.com/remix-run/remix/pull/9564)) -- `@remix-run/server-runtime` - Single Fetch: Fix issues with returning or throwing a response stub from a resource route in single fetch ([#9488](https://github.com/remix-run/remix/pull/9488)) -- `@remix-run/server-runtime` - Single Fetch: Fix error when returning `null` from a resource route ([#9488](https://github.com/remix-run/remix/pull/9488)) - -### Updated Dependencies - -- [`react-router-dom@6.24.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.24.0) -- [`@remix-run/router@1.17.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#117) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/create-remix/CHANGELOG.md#2100) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/remix-architect/CHANGELOG.md#2100) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/remix-cloudflare/CHANGELOG.md#2100) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/remix-cloudflare-pages/CHANGELOG.md#2100) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/remix-cloudflare-workers/CHANGELOG.md#2100) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/remix-css-bundle/CHANGELOG.md#2100) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/remix-deno/CHANGELOG.md#2100) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/remix-dev/CHANGELOG.md#2100) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/remix-eslint-config/CHANGELOG.md#2100) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/remix-express/CHANGELOG.md#2100) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/remix-node/CHANGELOG.md#2100) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/remix-react/CHANGELOG.md#2100) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/remix-serve/CHANGELOG.md#2100) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/remix-server-runtime/CHANGELOG.md#2100) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.10.0/packages/remix-testing/CHANGELOG.md#2100) - -**Full Changelog**: [`v2.9.2...v2.10.0`](https://github.com/remix-run/remix/compare/remix@2.9.2...remix@2.10.0) - -## v2.9.2 - -Date: 2024-05-10 - -### What's Changed - -#### Updated Type-Safety for Single Fetch - -In 2.9.2 we've enhanced the type-safety when opting into the `future.unstable_singleFetch` feature. Previously, we added the `response` stub to `LoaderFunctionArgs` and used type overrides for inference on `useLoaderData`, etc., but we found that it wasn't quite enough. - -With this release we're introducing new functions to assist the type-inference when using single fetch - `defineLoader`/`defineAction` and their client-side counterparts `defineClientLoader` and nd `defineClientAction`. These are identity functions; they don't modify your loader or action at runtime. Rather, they exist solely for type-safety by providing types for args and by ensuring valid return types. - -```ts -export const loader = defineLoader(({ request }) => { - // ^? Request - return { a: 1, b: () => 2 }; - // ^ type error: `b` is not serializable -}); -``` - -Note that `defineLoader` and `defineAction` are not technically necessary for defining loaders and actions if you aren't concerned with type-safety: - -```ts -// this totally works! and typechecking is happy too! -export const loader = () => { - return { a: 1 }; -}; -``` - -This means that you can opt-in to `defineLoader` incrementally, one loader at a time. - -Please see the [Single Fetch docs](https://remix.run/docs/en/main/guides/single-fetch) for more information. - -### Patch Changes - -- `@remix-run/dev` - Vite: Fix `dest already exists` error when running `remix vite:build` ([#9305](https://github.com/remix-run/remix/pull/9305)) -- `@remix-run/dev` - Vite: Fix issue resolving critical CSS during development when route files are located outside of the app directory ([#9194](https://github.com/remix-run/remix/pull/9194)) -- `@remix-run/dev` - Vite: Remove `@remix-run/node` from Vite plugin's `optimizeDeps.include` list since it was unnecessary and resulted in Vite warnings when not depending on this package ([#9287](https://github.com/remix-run/remix/pull/9287)) -- `@remix-run/dev` - Vite: Clean up redundant `?client-route=1` imports in development ([#9395](https://github.com/remix-run/remix/pull/9395)) -- `@remix-run/dev` - Vite: Ensure Babel config files are not referenced when applying the `react-refresh` Babel transform within the Remix Vite plugin ([#9241](https://github.com/remix-run/remix/pull/9241)) -- `@remix-run/react` - Type-safety for single-fetch: `defineLoader`, `defineClientLoader`, `defineAction`, `defineClientAction` ([#9372](https://github.com/remix-run/remix/pull/9372)) -- `@remix-run/react` - Single Fetch: Add `undefined` to `useActionData` type override ([#9322](https://github.com/remix-run/remix/pull/9322)) -- `@remix-run/react` - Single Fetch: Allow a `nonce` to be set on single fetch stream transfer inline scripts via `` ([#9364](https://github.com/remix-run/remix/pull/9364)) -- `@remix-run/server-runtime` - Single Fetch: Don't log thrown response stubs via `handleError` ([#9369](https://github.com/remix-run/remix/pull/9369)) -- `@remix-run/server-runtime` - Single Fetch: Automatically wrap resource route naked object returns in `json()` for back-compat in v2 (and log deprecation warning) ([#9349](https://github.com/remix-run/remix/pull/9349)) -- `@remix-run/server-runtime` - Single Fetch: Pass `response` stub to resource route handlers ([#9349](https://github.com/remix-run/remix/pull/9349)) - -### Updated Dependencies - -- [`react-router-dom@6.23.1`](https://github.com/remix-run/react-router/releases/tag/react-router%406.23.1) -- [`@remix-run/router@1.16.1`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1161) - -### Changes by Package - -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.9.2/packages/remix-cloudflare/CHANGELOG.md#292) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.9.2/packages/remix-cloudflare-pages/CHANGELOG.md#292) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.9.2/packages/remix-cloudflare-workers/CHANGELOG.md#292) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.9.2/packages/remix-css-bundle/CHANGELOG.md#292) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.9.2/packages/remix-deno/CHANGELOG.md#292) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.9.2/packages/remix-dev/CHANGELOG.md#292) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.9.2/packages/remix-eslint-config/CHANGELOG.md#292) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.9.2/packages/remix-express/CHANGELOG.md#292) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.9.2/packages/remix-node/CHANGELOG.md#292) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.9.2/packages/remix-react/CHANGELOG.md#292) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.9.2/packages/remix-serve/CHANGELOG.md#292) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.9.2/packages/remix-server-runtime/CHANGELOG.md#292) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.9.2/packages/remix-testing/CHANGELOG.md#292) - -**Full Changelog**: [`v2.9.1...v2.9.2`](https://github.com/remix-run/remix/compare/remix@2.9.1...remix@2.9.2) - -## v2.9.1 - -Date: 2024-04-24 - -### Patch Changes - -- `@remix-run/dev` - Fix issue where consumers who had added Remix packages to Vite's `ssr.noExternal` option were being overridden by the Remix Vite plugin adding Remix packages to Vite's `ssr.external` option ([#9301](https://github.com/remix-run/remix/pull/9301)) -- `@remix-run/react` - Ignore `future/*.d.ts` files from TS build ([#9299](https://github.com/remix-run/remix/pull/9299)) - -### Changes by Package - -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.9.1/packages/remix-dev/CHANGELOG.md#291) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.9.1/packages/remix-react/CHANGELOG.md#291) - -**Full Changelog**: [`v2.9.0...v2.9.1`](https://github.com/remix-run/remix/compare/remix@2.9.0...remix@2.9.1) - -## v2.9.0 - -Date: 2024-04-23 - -### What's Changed - -#### Single Fetch (unstable) - -`2.9.0` introduces a `future.unstable_singleFetch` flag to enable to Single Fetch behavior ([RFC](https://github.com/remix-run/remix/discussions/7640)) in your Remix application. Please refer to the [docs](https://remix.run/docs/en/main/guides/single-fetch) for the full detail but the high-level changes to be aware of include: - -- Naked objects returned from `loader`/`action` functions are no longer automatically serialized to JSON responses - - Instead, they'll be streamed as-is via [`turbo-stream`](https://github.com/jacob-ebey/turbo-stream) which allows direct serialization of more complex types such as `Promise`, `Date`, `Map` instances, and more - - You will need to modify your `tsconfig.json`'s `compilerOptions.types` array to infer types properly when using Single Fetch -- The `headers` export is no longer used when Single Fetch is enabled in favor of a new `response` stub passed to your `loader`/`action` functions -- The `json`/`defer`/`redirect` utilities are deprecated when using Single Fetch (but still work _mostly_ the same) -- Actions no longer automatically revalidate on `4xx`/`5xx` responses - you can return a `2xx` to opt-into revalidation or use `shouldRevalidate` - -> [!IMPORTANT] -> Single Fetch requires using `undici` as your fetch polyfill, or using the built-in fetch on Node 20+, because it relies on APIs available there but not in the `@remix-run/web-fetch` polyfill. Please refer to the [Undici](#undici) section below for more details. -> -> - If you are managing your own server and calling `installGlobals()`, you will need to call `installGlobals({ nativeFetch: true })` to avoid runtime errors when using Single Fetch -> - If you are using `remix-serve`, it will use `undici` automatically if Single Fetch is enabled - -#### Undici - -Remix `2.9.0` adds a new `installGlobals({ nativeFetch: true })` flag to opt into using [`undici`](https://github.com/nodejs/undici) for the [Web Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) polyfills instead of the [`@remix-run/web-*` packages](https://github.com/remix-run/web-std-io). This change has a few primary benefits: - -- It will allow us to stop maintaining our own [web-std-io fork](https://github.com/remix-run/web-std-io) in future versions of Remix -- It should bring us more in-line with spec compliance - - ⚠️ It is possible that some non-spec-compliant bugs in our fork will be "fixed" by moving to `undici`, so beware of "breaking bug fixes" and keep an eye on any advanced `fetch` API interactions you're performing in your app - - ⚠️ In some cases, `undici` may have different behavior by design -- most notably, `undici`'s garbage collection behavior differs and you are [required to consume all fetch response bodies](https://github.com/nodejs/undici?tab=readme-ov-file#garbage-collection) to avoid a memory leak in your app -- Because `undici` is the fetch implementation used by `node` internally, it should better prepare Remix apps to more smoothly drop the polyfill to use the built-in Node.js APIs on `node` 20+ - -### Minor Changes - -- New `future.unstable_singleFetch` flag ([#8773](https://github.com/remix-run/remix/pull/8773), [#9073](https://github.com/remix-run/remix/pull/9073), [#9084](https://github.com/remix-run/remix/pull/9084), [#9272](https://github.com/remix-run/remix/pull/9272)) -- `@remix-run/node` - Add a new `installGlobals({ nativeFetch: true })` flag to opt-into using [`undici`](https://github.com/nodejs/undici) as the fetch polyfill instead of `@remix-run/web-*` ([#9106](https://github.com/remix-run/remix/pull/9106), [#9111](https://github.com/remix-run/remix/pull/9111), [#9198](https://github.com/remix-run/remix/pull/9198)) -- `@remix-run/server-runtime` - Add `ResponseStub` header interface and deprecate the `headers` export when Single Fetch is enabled ([#9142](https://github.com/remix-run/remix/pull/9142)) - -### Patch Changes - -- `create-remix` - Allow `.` in repo name when using `--template` flag ([#9026](https://github.com/remix-run/remix/pull/9026)) -- `@remix-run/dev` - Improve `getDependenciesToBundle` resolution in monorepos ([#8848](https://github.com/remix-run/remix/pull/8848)) -- `@remix-run/dev` - Fix SPA mode when Single Fetch is enabled by using streaming `entry.server` ([#9063](https://github.com/remix-run/remix/pull/9063)) -- `@remix-run/dev` - Vite: added sourcemap support for transformed routes ([#8970](https://github.com/remix-run/remix/pull/8970)) -- `@remix-run/dev` - Update links printed to the console by the Remix CLI/Dev Server to point to updated docs locations ([#9176](https://github.com/remix-run/remix/pull/9176)) -- `@remix-run/server-runtime` - Handle redirects created by `handleDataRequest` ([#9104](https://github.com/remix-run/remix/pull/9104)) - -### Updated Dependencies - -- [`react-router-dom@6.23.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.23.0) -- [`@remix-run/router@1.16.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1160) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/create-remix/CHANGELOG.md#290) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/remix-architect/CHANGELOG.md#290) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/remix-cloudflare/CHANGELOG.md#290) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/remix-cloudflare-pages/CHANGELOG.md#290) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/remix-cloudflare-workers/CHANGELOG.md#290) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/remix-css-bundle/CHANGELOG.md#290) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/remix-deno/CHANGELOG.md#290) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/remix-dev/CHANGELOG.md#290) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/remix-eslint-config/CHANGELOG.md#290) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/remix-express/CHANGELOG.md#290) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/remix-node/CHANGELOG.md#290) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/remix-react/CHANGELOG.md#290) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/remix-serve/CHANGELOG.md#290) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/remix-server-runtime/CHANGELOG.md#290) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.9.0/packages/remix-testing/CHANGELOG.md#290) - -**Full Changelog**: [`v2.8.1...v2.9.0`](https://github.com/remix-run/remix/compare/remix@2.8.1...remix@2.9.0) - -## v2.8.1 - -Date: 2024-03-07 - -### Patch Changes - -- `@remix-run/dev` - Vite: Support reading from Vite config when running `remix reveal` and `remix routes` CLI commands ([#8916](https://github.com/remix-run/remix/pull/8916)) -- `@remix-run/dev` - Vite: Clean up redundant client route query strings on route JavaScript files in production builds ([#8969](https://github.com/remix-run/remix/pull/8969)) -- `@remix-run/dev` - Vite: Add vite commands to Remix CLI `--help` output ([#8939](https://github.com/remix-run/remix/pull/8939)) -- `@remix-run/dev` - Vite: Fix support for `build.sourcemap` option in Vite config ([#8965](https://github.com/remix-run/remix/pull/8965)) -- `@remix-run/dev` - Vite: Fix error when using Vite's `server.fs.allow` option without a client entry file ([#8966](https://github.com/remix-run/remix/pull/8966)) -- `@remix-run/react` - Strengthen the internal `LayoutComponent` type to accept limited children ([#8910](https://github.com/remix-run/remix/pull/8910)) - -### Updated Dependencies - -- [`react-router-dom@6.22.3`](https://github.com/remix-run/react-router/releases/tag/react-router%406.22.3) -- [`@remix-run/router@1.15.3`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1153) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/create-remix/CHANGELOG.md#281) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/remix-architect/CHANGELOG.md#281) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/remix-cloudflare/CHANGELOG.md#281) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/remix-cloudflare-pages/CHANGELOG.md#281) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/remix-cloudflare-workers/CHANGELOG.md#281) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/remix-css-bundle/CHANGELOG.md#281) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/remix-deno/CHANGELOG.md#281) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/remix-dev/CHANGELOG.md#281) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/remix-eslint-config/CHANGELOG.md#281) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/remix-express/CHANGELOG.md#281) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/remix-node/CHANGELOG.md#281) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/remix-react/CHANGELOG.md#281) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/remix-serve/CHANGELOG.md#281) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/remix-server-runtime/CHANGELOG.md#281) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.8.1/packages/remix-testing/CHANGELOG.md#281) - -**Full Changelog**: [`v2.8.0...v2.8.1`](https://github.com/remix-run/remix/compare/remix@2.8.0...remix@2.8.1) - -## v2.8.0 - -Date: 2024-02-28 - -### Minor Changes - -- `@remix-run/dev` - Vite: Pass resolved `viteConfig` to Remix Vite plugin's `buildEnd` hook ([#8885](https://github.com/remix-run/remix/pull/8885)) - -### Patch Changes - -- `@remix-run/dev` - Mark `Layout` as browser safe route export in `esbuild` compiler ([#8842](https://github.com/remix-run/remix/pull/8842)) -- `@remix-run/dev` - Vite: Silence build warnings when dependencies include `"use client"` directives ([#8897](https://github.com/remix-run/remix/pull/8897)) -- `@remix-run/dev` - Vite: Fix `serverBundles` issue where multiple browser manifests are generated ([#8864](https://github.com/remix-run/remix/pull/8864)) -- `@remix-run/dev` - Vite: Support custom `build.assetsDir` option ([#8843](https://github.com/remix-run/remix/pull/8843)) -- `@remix-run/react` - Fix the default root `ErrorBoundary` component so it leverages the user-provided `Layout` component ([#8859](https://github.com/remix-run/remix/pull/8859)) -- `@remix-run/react` - Fix the default root `HydrateFallback` component so it leverages any user-provided `Layout` component ([#8892](https://github.com/remix-run/remix/pull/8892)) - -### Updated Dependencies - -- [`react-router-dom@6.22.2`](https://github.com/remix-run/react-router/releases/tag/react-router%406.22.2) -- [`@remix-run/router@1.15.2`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1152) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/create-remix/CHANGELOG.md#280) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-architect/CHANGELOG.md#280) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-cloudflare/CHANGELOG.md#280) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-cloudflare-pages/CHANGELOG.md#280) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-cloudflare-workers/CHANGELOG.md#280) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-css-bundle/CHANGELOG.md#280) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-deno/CHANGELOG.md#280) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-dev/CHANGELOG.md#280) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-eslint-config/CHANGELOG.md#280) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-express/CHANGELOG.md#280) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-node/CHANGELOG.md#280) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-react/CHANGELOG.md#280) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-serve/CHANGELOG.md#280) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-server-runtime/CHANGELOG.md#280) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.8.0/packages/remix-testing/CHANGELOG.md#280) - -**Full Changelog**: [`v2.7.2...v2.8.0`](https://github.com/remix-run/remix/compare/remix@2.7.2...remix@2.8.0) - -## 2.7.2 - -Date: 2024-02-21 - -### Patch Changes - -- `@remix-run/dev` - Vite: Fix error when building projects with `.css?url` imports ([#8829](https://github.com/remix-run/remix/pull/8829)) - -## 2.7.1 - -Date: 2024-02-20 - -### Patch Changes - -- `@remix-run/cloudflare-pages` - Fix breaking change and restore Cloudflare event context fields in `getLoadContext` argument for backwards compatibility ([#8819](https://github.com/remix-run/remix/pull/8819)) - -## v2.7.0 - -Date: 2024-02-20 - -### What's Changed - -#### Stabilized Vite Plugin - -We're excited to announce that support for [Vite](https://vitejs.dev/) is now stable in Remix `2.7.0`! Ever since the [initial unstable release of Remix Vite](https://remix.run/blog/remix-heart-vite), we’ve been hard at work refining and extending it over the past few months with help from all of our early adopters and community contributors. This also means that Vite-only features such as [SPA Mode](https://remix.run/docs/en/main/future/spa-mode), [Server Bundles](https://remix.run/docs/future/server-bundles), and [`basename` support](https://remix.run/docs/en/dev/future/vite#basename) are now officially stable as well 😊. - -For more information, check out the [blog post](https://remix.run/blog/remix-vite-stable) and the [Vite docs](https://remix.run/docs/en/main/future/vite). - -#### New `Layout` Export - -We've found that it's _super_ common to create your own component in your root route to hold the shared layout/app shell between your `Component`/`ErrorBoundary`/`HydrateFallback`. This is so common (and can also cause some minor edge-case issues such as a FOUC on hydration) that we've incorporated this as a first-class API in `2.7.0`. - -You can now export an optional `Layout` component from your root route which will be provided your route component, ErrorBoundary, or HydrateFallback as it's `children`. For more information, please see the [`Layout` docs](https://remix.run/docs/en/dev/file-conventions/root#layout-export) and the [RFC](https://github.com/remix-run/remix/discussions/8702). - -#### Basename support - -React Router has long supported a [`basename`](https://reactrouter.com/v6/routers/create-browser-router#basename) config that allows you to serve your app within a subpath such as `http://localhost/myapp/*` without having to include the `/myapp` segment in all of your route paths. This was originally omitted from Remix because v1 nested folders file-convention made it pretty easy to put your route files in a `routes/myapp/` folder, giving you the same functionality. There has also been an [open proposal from the community](https://github.com/remix-run/remix/discussions/2891) to add this functionality. - -Two things have since changed that made us reconsider the lack of `basename` support: - -- We switched to a flat-file based convention in v2, and it gets far less ergonomic to have to prefix all of your route files with `myapp.` compared to the nested folder convention -- We moved to Vite which has it's own `base` config which is often (and easily) confused with the concept of a React Router `basename` (when in reality it's more aligned with the old Remix `publicPath` config) - -In `2.7.0` we've added support for a `basename` in the Vite plugin config. For more information, please check out the [`basename` docs](https://remix.run/docs/en/dev/future/vite#basename). - -_Note: This is a Vite-only feature and is not available via the `esbuild` compiler._ - -#### Cloudflare Proxy as a Vite Plugin - -⚠️ This is a breaking change for projects relying on Cloudflare support from the unstable Vite plugin - -The Cloudflare preset (`unstable_cloudflarePreset`) as been removed and replaced with a new Vite plugin: - -```diff - import { - unstable_vitePlugin as remix, -- unstable_cloudflarePreset as cloudflare, -+ cloudflareDevProxyVitePlugin as remixCloudflareDevProxy, - } from "@remix-run/dev"; - import { defineConfig } from "vite"; - - export default defineConfig({ - plugins: [ -+ remixCloudflareDevProxy(), -+ remix(), -- remix({ -- presets: [cloudflare()], -- }), - ], -- ssr: { -- resolve: { -- externalConditions: ["workerd", "worker"], -- }, -- }, - }); -``` - -A few notes on the new plugin: - -- `remixCloudflareDevProxy` must come _before_ the `remix` plugin so that it can override Vite's dev server middleware to be compatible with Cloudflare's proxied environment -- Because it is a Vite plugin, `remixCloudflareDevProxy` can set `ssr.resolve.externalConditions` to be `workerd`-compatible for you -- `remixCloudflareDevProxy` accepts a `getLoadContext` function that replaces the old `getRemixDevLoadContext` -- If you were using a `nightly` version that required `getBindingsProxy` or `getPlatformProxy`, that is no longer required -- Any options you were passing to `getBindingsProxy` or `getPlatformProxy` should now be passed to `remixCloudflareDevProxy` instead -- This API also better aligns with future plans to support Cloudflare with a framework-agnostic Vite plugin that makes use of Vite's (experimental) Runtime API. - -### Minor Changes - -- `@remix-run/react` - Allow an optional `Layout` export from the root route ([#8709](https://github.com/remix-run/remix/pull/8709)) -- `@remix-run/cloudflare-pages` - Make `getLoadContext` optional for Cloudflare Pages ([#8701](https://github.com/remix-run/remix/pull/8701)) - - Defaults to `(context) => ({ env: context })`, which is what we used to have in all the templates - - This gives parity with the Cloudflare preset for the Remix Vite plugin and keeps our templates leaner -- `@remix-run/dev` - Vite: Cloudflare Proxy as a Vite plugin ([#8749](https://github.com/remix-run/remix/pull/8749)) - - **⚠️ This is a breaking change for projects relying on Cloudflare support from the unstable Vite plugin** -- `@remix-run/dev` - Vite: Add a new `basename` option to the Vite plugin, allowing users to set the internal React Router [`basename`](https://reactrouter.com/v6/routers/create-browser-router#basename) in order to to serve their applications underneath a subpath ([#8145](https://github.com/remix-run/remix/pull/8145)) -- `@remix-run/dev` - Vite: Stabilize the Remix Vite plugin, Cloudflare preset, and all related types by removing all `unstable_` / `Unstable_` prefixes ([#8713](https://github.com/remix-run/remix/pull/8713)) - - While this is a breaking change for existing Remix Vite plugin consumers, now that the plugin has stabilized, there will no longer be any breaking changes outside of a major release. Thank you to all of our early adopters and community contributors for helping us get here! 🙏 -- `@remix-run/dev` - Vite: Stabilize "SPA Mode" by renaming the Remix vite plugin config from `unstable_ssr -> ssr` ([#8692](https://github.com/remix-run/remix/pull/8692)) - -### Patch Changes - -- `@remix-run/express` - Use `req.originalUrl` instead of `req.url` so that Remix sees the full URL ([#8145](https://github.com/remix-run/remix/pull/8145)) - - Remix relies on the knowing the full URL to ensure that server and client code can function together, and does not support URL rewriting prior to the Remix handler -- `@remix-run/react` - Fix a bug with SPA mode when the root route had no children ([#8747](https://github.com/remix-run/remix/pull/8747)) -- `@remix-run/server-runtime` - Add a more specific error if a user returns a `defer` response from a resource route ([#8726](https://github.com/remix-run/remix/pull/8726)) -- `@remix-run/dev` - Always prepend `DOCTYPE` in SPA mode `entry.server.tsx`, can opt out via remix reveal ([#8725](https://github.com/remix-run/remix/pull/8725)) -- `@remix-run/dev` - Fix build issue in SPA mode when using a `basename` ([#8720](https://github.com/remix-run/remix/pull/8720)) -- `@remix-run/dev` - Fix type error in Remix config for synchronous `routes` function ([#8745](https://github.com/remix-run/remix/pull/8745)) -- `@remix-run/dev` - Vite: Fix issue where client route file requests fail if search params have been parsed and serialized before reaching the Remix Vite plugin ([#8740](https://github.com/remix-run/remix/pull/8740)) -- `@remix-run/dev` - Vite: Validate that the MDX Rollup plugin, if present, is placed before Remix in Vite config ([#8690](https://github.com/remix-run/remix/pull/8690)) -- `@remix-run/dev` - Vite: Fix issue resolving critical CSS during development when the current working directory differs from the project root ([#8752](https://github.com/remix-run/remix/pull/8752)) -- `@remix-run/dev` - Vite: Require version `5.1.0` to support `.css?url` imports ([#8723](https://github.com/remix-run/remix/pull/8723)) -- `@remix-run/dev` - Vite: Support Vite `5.1.0`'s `.css?url` imports ([#8684](https://github.com/remix-run/remix/pull/8684)) -- `@remix-run/dev` - Vite: Enable use of [`vite preview`](https://main.vitejs.dev/guide/static-deploy.html#deploying-a-static-site) to preview Remix SPA applications ([#8624](https://github.com/remix-run/remix/pull/8624)) - - In the SPA template, `npm run start` has been renamed to `npm run preview` which uses `vite preview` instead of a standalone HTTP server such as `http-server` or `serv-cli` -- `@remix-run/dev` - Vite: Remove the ability to pass `publicPath` as an option to the Remix vite plugin ([#8145](https://github.com/remix-run/remix/pull/8145)) - - **⚠️ This is a breaking change for projects using the unstable Vite plugin with a `publicPath`** - - This is already handled in Vite via the [`base`](https://vitejs.dev/guide/build.html#public-base-path) config so we now set the Remix `publicPath` from the Vite `base` config -- `@remix-run/dev` - Vite: Enable HMR for `.md` and `.mdx` files ([#8711](https://github.com/remix-run/remix/pull/8711)) -- `@remix-run/dev` - Vite: reliably detect non-root routes in Windows ([#8806](https://github.com/remix-run/remix/pull/8806)) -- `@remix-run/dev` - Vite: Pass `remixUserConfig` to preset `remixConfig` hook ([#8797](https://github.com/remix-run/remix/pull/8797)) -- `@remix-run/dev` - Vite: Ensure CSS file URLs that are only referenced in the server build are available on the client ([#8796](https://github.com/remix-run/remix/pull/8796)) -- `@remix-run/dev` - Vite: fix server exports dead-code elimination for routes outside of app directory ([#8795](https://github.com/remix-run/remix/pull/8795)) - -### Updated Dependencies - -- [`react-router-dom@6.22.Y`](https://github.com/remix-run/react-router/releases/tag/react-router%406.22.1) -- [`@remix-run/router@1.15.Y`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1151) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/create-remix/CHANGELOG.md#270) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/remix-architect/CHANGELOG.md#270) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/remix-cloudflare/CHANGELOG.md#270) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/remix-cloudflare-pages/CHANGELOG.md#270) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/remix-cloudflare-workers/CHANGELOG.md#270) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/remix-css-bundle/CHANGELOG.md#270) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/remix-deno/CHANGELOG.md#270) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/remix-dev/CHANGELOG.md#270) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/remix-eslint-config/CHANGELOG.md#270) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/remix-express/CHANGELOG.md#270) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/remix-node/CHANGELOG.md#270) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/remix-react/CHANGELOG.md#270) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/remix-serve/CHANGELOG.md#270) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/remix-server-runtime/CHANGELOG.md#270) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.7.0/packages/remix-testing/CHANGELOG.md#270) - -**Full Changelog**: [`v2.6.0...v2.7.0`](https://github.com/remix-run/remix/compare/remix@2.6.0...remix@2.7.0) - -## v2.6.0 - -Date: 2024-02-01 - -### What's Changed - -#### Unstable Vite Plugin updates - -As we continue moving towards stabilizing the Vite plugin, we've introduced a few breaking changes to the unstable Vite plugin in this release. Please read the `@remix-run/dev` changes below closely and update your app accordingly if you've opted into using the Vite plugin. - -We've also removed the `unstable_` prefix from the `serverBundles` option as we're now confident in the API ([#8596](https://github.com/remix-run/remix/pull/8596)). - -🎉 And last, but certainly not least - we've added much anticipated Cloudflare support in [#8531](https://github.com/remix-run/remix/pull/8531)! To get started with Cloudflare, you can use the `unstable-vite-cloudflare` template: - -```shellscript nonumber -npx create-remix@latest --template remix-run/remix/templates/unstable-vite-cloudflare -``` - -For more information, please refer to the docs at [Future > Vite > Cloudflare](https://remix.run/docs/future/vite#cloudflare) and [Future > Vite > Migrating > Migrating Cloudflare Functions](https://remix.run/docs/future/vite#migrating-cloudflare-functions). - -### Minor Changes - -- `@remix-run/server-runtime` - Add `future.v3_throwAbortReason` flag to throw `request.signal.reason` when a request is aborted instead of an `Error` such as `new Error("query() call aborted: GET /path")` ([#8251](https://github.com/remix-run/remix/pull/8251)) - -### Patch Changes - -- `@remix-run/server-runtime` - Unwrap thrown `Response`'s from `entry.server` into `ErrorResponse`'s and preserve the status code ([#8577](https://github.com/remix-run/remix/pull/8577)) -- `@remix-run/dev` - Vite: Add `manifest` option to Vite plugin to enable writing a `.remix/manifest.json` file to the build directory ([#8575](https://github.com/remix-run/remix/pull/8575)) - - ⚠️ **This is a breaking change for consumers of the Vite plugin's "server bundles" feature** - - The `build/server/bundles.json` file has been superseded by the more general `build/.remix/manifest.json` - - While the old server bundles manifest was always written to disk when generating server bundles, the build manifest file must be explicitly enabled via the `manifest` option -- `@remix-run/dev` - Vite: Rely on Vite plugin ordering ([#8627](https://github.com/remix-run/remix/pull/8627)) - - - ⚠️ **This is a breaking change for projects using the unstable Vite plugin** - - The Remix plugin expects to process JavaScript or TypeScript files, so any transpilation from other languages must be done first. - - For example, that means putting the MDX plugin _before_ the Remix plugin: - - ```diff - import mdx from "@mdx-js/rollup"; - import { unstable_vitePlugin as remix } from "@remix-run/dev"; - import { defineConfig } from "vite"; - - export default defineConfig({ - plugins: [ - + mdx(), - remix() - - mdx(), - ], - }); - ``` - - - Previously, the Remix plugin misused `enforce: "post"` from Vite's plugin API to ensure that it ran last - - However, this caused other unforeseen issues - - Instead, we now rely on standard Vite semantics for plugin ordering - - The official [Vite React SWC plugin](https://github.com/vitejs/vite-plugin-react-swc/blob/main/src/index.ts#L97-L116) also relies on plugin ordering for MDX - -- `@remix-run/dev` - Vite: Remove interop with ``, rely on `` instead ([#8636](https://github.com/remix-run/remix/pull/8636)) - - - ⚠️ **This is a breaking change for projects using the unstable Vite plugin** - - Vite provides a robust client-side runtime for development features like HMR, making the `` component obsolete - - In fact, having a separate dev scripts component was causing issues with script execution order - - To work around this, the Remix Vite plugin used to override `` into a bespoke implementation that was compatible with Vite - - Instead of all this indirection, now the Remix Vite plugin instructs the `` component to automatically include Vite's client-side runtime and other dev-only scripts - - To adopt this change, you can remove the LiveReload component from your `root.tsx` component: - - ```diff - import { - - LiveReload, - Outlet, - Scripts, - } - - export default function App() { - return ( - - - - - - - - - - - ) - } - ``` - -- `@remix-run/dev` - Vite: Only write Vite manifest files if `build.manifest` is enabled within the Vite config ([#8599](https://github.com/remix-run/remix/pull/8599)) - - - ⚠️ **This is a breaking change for consumers of Vite's `manifest.json` files** - - To explicitly enable generation of Vite manifest files, you must set `build.manifest` to `true` in your Vite config: - - ```ts - export default defineConfig({ - build: { manifest: true }, - // ... - }); - ``` - -- `@remix-run/dev` - Vite: Add new `buildDirectory` option with a default value of `"build"` ([#8575](https://github.com/remix-run/remix/pull/8575)) - - - ⚠️ **This is a breaking change for consumers of the Vite plugin that were using the `assetsBuildDirectory` and `serverBuildDirectory` options** - - This replaces the old `assetsBuildDirectory` and `serverBuildDirectory` options which defaulted to `"build/client"` and `"build/server"` respectively - - The Remix Vite plugin now builds into a single directory containing `client` and `server` directories - - If you've customized your build output directories, you'll need to migrate to the new `buildDirectory` option, e.g.: - - ```diff - import { unstable_vitePlugin as remix } from "@remix-run/dev"; - import { defineConfig } from "vite"; - - export default defineConfig({ - plugins: [ - remix({ - - serverBuildDirectory: "dist/server", - - assetsBuildDirectory: "dist/client", - + buildDirectory: "dist", - }) - ], - }); - ``` - -- `@remix-run/dev` - Vite: Write Vite manifest files to `build/.vite` directory rather than being nested within `build/client` and `build/server` directories ([#8599](https://github.com/remix-run/remix/pull/8599)) - - ⚠️ **This is a breaking change for consumers of Vite's `manifest.json` files** - - Vite manifest files are now written to the Remix build directory - - Since all Vite manifests are now in the same directory, they're no longer named `manifest.json` - - Instead, they're named `build/.vite/client-manifest.json` and `build/.vite/server-manifest.json`, or `build/.vite/server-{BUNDLE_ID}-manifest.json` when using server bundles -- `@remix-run/dev` - Vite: Remove `unstable` prefix from `serverBundles` option ([#8596](https://github.com/remix-run/remix/pull/8596)) -- `@remix-run/dev` - Vite: Add `--sourcemapClient` and `--sourcemapServer` flags to `remix vite:build` ([#8613](https://github.com/remix-run/remix/pull/8613)) - - `--sourcemapClient`, `--sourcemapClient=inline`, or `--sourcemapClient=hidden` - - `--sourcemapServer`, `--sourcemapServer=inline`, or `--sourcemapServer=hidden` - - See https://vitejs.dev/config/build-options.html#build-sourcemap -- `@remix-run/dev` - Vite: Validate IDs returned from the `serverBundles` function to ensure they only contain alphanumeric characters, hyphens and underscores ([#8598](https://github.com/remix-run/remix/pull/8598)) -- `@remix-run/dev` - Vite: Fix "could not fast refresh" false alarm ([#8580](https://github.com/remix-run/remix/pull/8580)) - - HMR is already functioning correctly but was incorrectly logging that it "could not fast refresh" on internal client routes - - Now internal client routes correctly register Remix exports like `meta` for fast refresh, which removes the false alarm. -- `@remix-run/dev` - Vite: Cloudflare Pages support ([#8531](https://github.com/remix-run/remix/pull/8531)) -- `@remix-run/dev` - Vite: Add `getRemixDevLoadContext` option to Cloudflare preset ([#8649](https://github.com/remix-run/remix/pull/8649)) -- `@remix-run/dev` - Vite: Remove undocumented backwards compatibility layer for Vite v4 ([#8581](https://github.com/remix-run/remix/pull/8581)) -- `@remix-run/dev` - Vite: Add `presets` option to ease integration with different platforms and tools ([#8514](https://github.com/remix-run/remix/pull/8514)) -- `@remix-run/dev` - Vite: Add `buildEnd` hook ([#8620](https://github.com/remix-run/remix/pull/8620)) -- `@remix-run/dev` - Vite: Add `mode` field into generated server build ([#8539](https://github.com/remix-run/remix/pull/8539)) -- `@remix-run/dev` - Vite: Reduce network calls for route modules during HMR ([#8591](https://github.com/remix-run/remix/pull/8591)) -- `@remix-run/dev` - Vite: Export `Unstable_ServerBundlesFunction` and `Unstable_VitePluginConfig` types ([#8654](https://github.com/remix-run/remix/pull/8654)) - -### Updated Dependencies - -- [`react-router-dom@6.22.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.22.0) -- [`@remix-run/router@1.15.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1150) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/create-remix/CHANGELOG.md#260) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/remix-architect/CHANGELOG.md#260) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/remix-cloudflare/CHANGELOG.md#260) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/remix-cloudflare-pages/CHANGELOG.md#260) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/remix-cloudflare-workers/CHANGELOG.md#260) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/remix-css-bundle/CHANGELOG.md#260) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/remix-deno/CHANGELOG.md#260) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/remix-dev/CHANGELOG.md#260) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/remix-eslint-config/CHANGELOG.md#260) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/remix-express/CHANGELOG.md#260) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/remix-node/CHANGELOG.md#260) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/remix-react/CHANGELOG.md#260) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/remix-serve/CHANGELOG.md#260) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/remix-server-runtime/CHANGELOG.md#260) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.6.0/packages/remix-testing/CHANGELOG.md#260) - -**Full Changelog**: [`v2.5.1...v2.6.0`](https://github.com/remix-run/remix/compare/remix@2.5.1...remix@2.6.0) - -## v2.5.1 - -Date: 2024-01-18 - -### Patch Changes - -- `create-remix` - high-contrast fg/bg for header colors ([#8503](https://github.com/remix-run/remix/pull/8503)) - - `bgWhite` and `whiteBright` are the same color in many terminal colorthemes, which was causing it to render as illegible white-on-white -- `@remix-run/dev` - Add `isSpaMode` to `@remix-run/dev/server-build` virtual module ([#8492](https://github.com/remix-run/remix/pull/8492)) -- `@remix-run/dev` - SPA Mode: Automatically prepend `` if not present to fix quirks mode warnings for SPA template ([#8495](https://github.com/remix-run/remix/pull/8495)) -- `@remix-run/dev` - Vite: Errors for server-only code point to new docs ([#8488](https://github.com/remix-run/remix/pull/8488)) -- `@remix-run/dev` - Vite: Fix HMR race condition when reading changed file contents ([#8479](https://github.com/remix-run/remix/pull/8479)) -- `@remix-run/dev` - Vite: Tree-shake unused route exports in the client build ([#8468](https://github.com/remix-run/remix/pull/8468)) -- `@remix-run/dev` - Vite: Performance profiling ([#8493](https://github.com/remix-run/remix/pull/8493)) - - Run `remix vite:build --profile` to generate a `.cpuprofile` that can be shared or uploaded to speedscope.app - - In dev, press `p + enter` to start a new profiling session or stop the current session - - If you need to profile dev server startup, run `remix vite:dev --profile` to initialize the dev server with a running profiling session - - For more, see the new [Vite > Performance](https://remix.run/docs/future/vite#performance) docs -- `@remix-run/dev` - Vite: Improve performance of dev server requests by invalidating Remix's virtual modules on relevant file changes rather than on every request ([#8164](https://github.com/remix-run/remix/pull/8164)) -- `@remix-run/react` - Remove leftover `unstable_` prefix from `Blocker`/`BlockerFunction` types ([#8530](https://github.com/remix-run/remix/pull/8530)) -- `@remix-run/react` - Only use active matches in ``/`` in SPA mode ([#8538](https://github.com/remix-run/remix/pull/8538)) - -### Updated Dependencies - -- [`react-router-dom@6.21.3`](https://github.com/remix-run/react-router/releases/tag/react-router%406.21.3) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/create-remix/CHANGELOG.md#251) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/remix-architect/CHANGELOG.md#251) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/remix-cloudflare/CHANGELOG.md#251) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/remix-cloudflare-pages/CHANGELOG.md#251) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/remix-cloudflare-workers/CHANGELOG.md#251) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/remix-css-bundle/CHANGELOG.md#251) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/remix-deno/CHANGELOG.md#251) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/remix-dev/CHANGELOG.md#251) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/remix-eslint-config/CHANGELOG.md#251) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/remix-express/CHANGELOG.md#251) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/remix-node/CHANGELOG.md#251) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/remix-react/CHANGELOG.md#251) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/remix-serve/CHANGELOG.md#251) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/remix-server-runtime/CHANGELOG.md#251) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.5.1/packages/remix-testing/CHANGELOG.md#251) - -**Full Changelog**: [`v2.5.0...v2.5.1`](https://github.com/remix-run/remix/compare/remix@2.5.0...remix@2.5.1) - -## v2.5.0 - -Date: 2024-01-11 - -### What's Changed - -#### SPA Mode (unstable) - -SPA Mode ([RFC](https://github.com/remix-run/remix/discussions/7638)) allows you to generate your Remix app as a standalone SPA served from a static `index.html` file. You can opt into SPA Mode by setting `unstable_ssr: false` in your Remix Vite plugin config: - -```js -// vite.config.ts -import { unstable_vitePlugin as remix } from "@remix-run/dev"; -import { defineConfig } from "vite"; - -export default defineConfig({ - plugins: [remix({ unstable_ssr: false })], -}); -``` - -Development in SPA Mode is just like a normal Remix app, and still uses the Remix dev server for HMR/HDR: - -```sh -remix vite:dev -``` - -Building in SPA Mode will generate an `index.html` file in your client assets directory: - -```sh -remix vite:build -``` - -To run your SPA, you serve your client assets directory via an HTTP server: - -```sh -npx http-server build/client -``` - -For more information, please refer to the [SPA Mode docs](https://remix.run/future/spa-mode). - -#### Server Bundles (unstable) - -This is an advanced feature designed for hosting provider integrations where you may want to split server code into multiple request handlers. When compiling your app into multiple server bundles, there will need to be a custom routing layer in front of your app directing requests to the correct bundle. This feature is currently unstable and only designed to gather early feedback. - -You can control the server bundles generated by your Remix Vite build by setting the `unstable_serverBundles` option in your vite config: - -```ts -import { unstable_vitePlugin as remix } from "@remix-run/dev"; -import { defineConfig } from "vite"; - -export default defineConfig({ - plugins: [ - remix({ - unstable_serverBundles: ({ branch }) => { - const isAuthenticatedRoute = branch.some( - (route) => route.id === "routes/_authenticated" - ); - - return isAuthenticatedRoute ? "authenticated" : "unauthenticated"; - }, - }), - ], -}); -``` - -### Minor Changes - -- Add unstable support for "SPA Mode" ([#8457](https://github.com/remix-run/remix/pull/8457)) -- Add `unstable_serverBundles` option to Vite plugin to support splitting server code into multiple request handlers ([#8332](https://github.com/remix-run/remix/pull/8332)) - -### Patch Changes - -- `create-remix`: Only update `*` versions for Remix dependencies ([#8458](https://github.com/remix-run/remix/pull/8458)) -- `remix-serve`: Don't try to load sourcemaps if they don't exist on disk ([#8446](https://github.com/remix-run/remix/pull/8446)) -- `@remix-run/dev`: Fix issue with `isbot@4` released on 1/1/2024 ([#8415](https://github.com/remix-run/remix/pull/8415)) - - `remix dev` will now add `"isbot": "^4"` to `package.json` instead of using `latest` - - Update built-in `entry.server` files to work with both `isbot@3` and `isbot@4` for backwards-compatibility with Remix apps that have pinned `isbot@3` - - Templates are updated to use `isbot@4` moving forward via `create-remix` -- `@remix-run/dev`: Vite - Fix HMR issues when altering exports for non-rendered routes ([#8157](https://github.com/remix-run/remix/pull/8157)) -- `@remix-run/dev`: Vite - Default `NODE_ENV` to `"production"` when running `remix vite:build` command ([#8405](https://github.com/remix-run/remix/pull/8405)) -- `@remix-run/dev`: Vite - Remove Vite plugin config option `serverBuildPath` in favor of separate `serverBuildDirectory` and `serverBuildFile` options ([#8332](https://github.com/remix-run/remix/pull/8332)) -- `@remix-run/dev`: Vite - Loosen strict route exports restriction, reinstating support for non-Remix route exports ([#8420](https://github.com/remix-run/remix/pull/8420)) -- `@remix-run/react`: Vite - Fix type conflict with `import.meta.hot` from the existing Remix compiler ([#8459](https://github.com/remix-run/remix/pull/8459)) -- `@remix-run/server-runtime`: Updated `cookie` dependency to [`0.6.0`](https://github.com/jshttp/cookie/blob/master/HISTORY.md#060--2023-11-06) to inherit support for the [`Partitioned`](https://developer.mozilla.org/en-US/docs/Web/Privacy/Partitioned_cookies) attribute ([#8375](https://github.com/remix-run/remix/pull/8375)) - -### Updated Dependencies - -- [`react-router-dom@6.21.2`](https://github.com/remix-run/react-router/releases/tag/react-router%406.21.2) -- [`@remix-run/router@1.14.2`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1142) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/create-remix/CHANGELOG.md#250) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/remix-architect/CHANGELOG.md#250) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/remix-cloudflare/CHANGELOG.md#250) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/remix-cloudflare-pages/CHANGELOG.md#250) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/remix-cloudflare-workers/CHANGELOG.md#250) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/remix-css-bundle/CHANGELOG.md#250) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/remix-deno/CHANGELOG.md#250) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/remix-dev/CHANGELOG.md#250) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/remix-eslint-config/CHANGELOG.md#250) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/remix-express/CHANGELOG.md#250) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/remix-node/CHANGELOG.md#250) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/remix-react/CHANGELOG.md#250) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/remix-serve/CHANGELOG.md#250) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/remix-server-runtime/CHANGELOG.md#250) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.5.0/packages/remix-testing/CHANGELOG.md#250) - -**Full Changelog**: [`v2.4.1...v2.5.0`](https://github.com/remix-run/remix/compare/remix@2.4.1...remix@2.5.0) - -## v2.4.1 - -Date: 2023-12-22 - -### Patch Changes - -- `@remix-run/dev`: Vite - Remove `unstable_viteServerBuildModuleId` in favor of manually referencing virtual module name `"virtual:remix/server-build"` ([#8264](https://github.com/remix-run/remix/pull/8264)) - - - ⚠️ **This is a breaking change for projects using the unstable Vite plugin with a custom server** - - This change was made to avoid issues where `@remix-run/dev` could be inadvertently required in your server's production dependencies. - - Instead, you should manually write the virtual module name `"virtual:remix/server-build"` when calling `ssrLoadModule` in development. - - ```diff - -import { unstable_viteServerBuildModuleId } from "@remix-run/dev"; - - // ... - - app.all( - "*", - createRequestHandler({ - build: vite - - ? () => vite.ssrLoadModule(unstable_viteServerBuildModuleId) - + ? () => vite.ssrLoadModule("virtual:remix/server-build") - : await import("./build/server/index.js"), - }) - ); - ``` - -- `@remix-run/dev`: Vite - Add `vite:dev` and `vite:build` commands to the Remix CLI ([#8211](https://github.com/remix-run/remix/pull/8211)) - - - In order to handle upcoming Remix features where your plugin options can impact the number of Vite builds required, you should now run your Vite `dev` and `build` processes via the Remix CLI. - - ```diff - { - "scripts": { - - "dev": "vite dev", - - "build": "vite build && vite build --ssr" - + "dev": "remix vite:dev", - + "build": "remix vite:build" - } - } - ``` - -- `@remix-run/dev`: Vite - Error messages when `.server` files are referenced by client ([#8267](https://github.com/remix-run/remix/pull/8267)) - - Previously, referencing a `.server` module from client code resulted in an error message like: - - `The requested module '/app/models/answer.server.ts' does not provide an export named 'isDateType'` - - This was confusing because `answer.server.ts` _does_ provide the `isDateType` export, but Remix was replacing `.server` modules with empty modules (`export {}`) for the client build - - Now, Remix explicitly fails at compile time when a `.server` module is referenced from client code and includes dedicated error messages depending on whether the import occurs in a route or a non-route module - - The error messages also include links to relevant documentation -- `@remix-run/dev`: Vite - Preserve names for exports from `.client` modules ([#8200](https://github.com/remix-run/remix/pull/8200)) - - Unlike `.server` modules, the main idea is not to prevent code from leaking into the server build since the client build is already public - - Rather, the goal is to isolate the SSR render from client-only code - - Routes need to import code from `.client` modules without compilation failing and then rely on runtime checks or otherwise ensure that execution only happens within a client-only context (e.g. event handlers, `useEffect`) - - Replacing `.client` modules with empty modules would cause the build to fail as ESM named imports are statically analyzed - - So instead, we preserve the named export but replace each exported value with `undefined` - - That way, the import is valid at build time and standard runtime checks can be used to determine if the code is running on the server or client -- `@remix-run/dev`: Vite - Disable watch mode in Vite child compiler during build ([#8342](https://github.com/remix-run/remix/pull/8342)) -- `@remix-run/dev`: Vite - Show warning when source maps are enabled in production build ([#8222](https://github.com/remix-run/remix/pull/8222)) -- `@remix-run/react`: Propagate server `loader` errors through `serverLoader` in hydrating `clientLoader`'s ([#8304](https://github.com/remix-run/remix/pull/8304)) -- `@remix-run/react` Re-export `Response` helpers (`defer`/`json`/`redirect`/`redirectDocument`) through `@remix-run/react` for use in `clientLoader`/`clientAction` ([#8351](https://github.com/remix-run/remix/pull/8351)) -- `@remix-run/server-runtime`: Add optional `error` to `ServerRuntimeMetaArgs` type to align with `MetaArgs` ([#8238](https://github.com/remix-run/remix/pull/8238)) -- `create-remix`: Switch to using `@remix-run/web-fetch` instead of `node-fetch` inside the `create-remix` CLI ([#7345](https://github.com/remix-run/remix/pull/7345)) -- `remix-serve`: Use node `fileURLToPath` to convert source map URL to path ([#8321](https://github.com/remix-run/remix/pull/8321)) - -### Updated Dependencies - -- [`react-router-dom@6.21.1`](https://github.com/remix-run/react-router/releases/tag/react-router%406.21.1) -- [`@remix-run/router@1.14.1`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1141) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/create-remix/CHANGELOG.md#241) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/remix-architect/CHANGELOG.md#241) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/remix-cloudflare/CHANGELOG.md#241) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/remix-cloudflare-pages/CHANGELOG.md#241) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/remix-cloudflare-workers/CHANGELOG.md#241) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/remix-css-bundle/CHANGELOG.md#241) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/remix-deno/CHANGELOG.md#241) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/remix-dev/CHANGELOG.md#241) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/remix-eslint-config/CHANGELOG.md#241) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/remix-express/CHANGELOG.md#241) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/remix-node/CHANGELOG.md#241) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/remix-react/CHANGELOG.md#241) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/remix-serve/CHANGELOG.md#241) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/remix-server-runtime/CHANGELOG.md#241) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.4.1/packages/remix-testing/CHANGELOG.md#241) - -**Full Changelog**: [`v2.4.0...v2.4.1`](https://github.com/remix-run/remix/compare/remix@2.4.0...remix@2.4.1) - -## v2.4.0 - -Date: 2023-12-13 - -### What's Changed - -#### Client Data - -We're excited to land the [Client Data RFC](https://github.com/remix-run/remix/discussions/7634) in this release! The final API differs slightly from the RFC, so please check out the docs for use-cases and final APIs: - -- [Client Data Guide](https://remix.run/guides/client-data) -- [`clientLoader`](https://remix.run/route/client-loader) -- [`HydrateFallback`](https://remix.run/route/hydrate-fallback) -- [`clientAction`](https://remix.run/route/client-action) - -While we still recommend server loaders/actions for the majority of your data needs in a Remix app - these provide some levers you can pull for more advanced use-cases such as: - -- **Skip the Hop:** Query a data API directly from the browser, using loaders simply for SSR -- **Fullstack State:** Augment server data with client data for your full set of loader data -- **One or the Other:** Sometimes you use server loaders, sometimes you use client loaders, but not both on one route -- **Client Cache:** Cache server loader data in the client and avoid some server calls -- **Migration:** Ease your migration from React Router -> Remix SPA -> Remix SSR - -#### `future.v3_relativeSplatPath` - -We introduced a `future.v3_relativeSplatPath` flag to implement a breaking bug fix to relative routing when inside a splat route. For more information, please see the React Router [`6.21.0` Release Notes](https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#futurev7_relativesplatpath) and the [`useResolvedPath` docs](https://remix.run/hooks/use-resolved-path#splat-paths) - -#### Vite Updates (Unstable) - -Remix now excludes modules within `.server` directories from client build. - -Remix now enforces strict route exports, and will will throw an error if you have unsupported exports in your route modules. Previously, the Remix compiler would allow any export from routes. While this was convenient, it was also a common source of bugs that were hard to track down because they only surfaced at runtime. For more information, please see [the docs](https://remix.run/docs/en/main/future/vite#strict-route-exports). - -### Minor Changes - -- Add support for `clientLoader`/`clientAction`/`HydrateFallback` route exports ([#8173](https://github.com/remix-run/remix/pull/8173)) -- Add a new `future.v3_relativeSplatPath` flag to implement a breaking bug fix to relative routing when inside a splat route ([#8216](https://github.com/remix-run/remix/pull/8216)) -- Deprecate `DataFunctionArgs` in favor of `LoaderFunctionArgs`/`ActionFunctionArgs` ([#8173](https://github.com/remix-run/remix/pull/8173)) - - This is aimed at keeping the types aligned across server/client loaders/actions now that `clientLoader`/`clientActon` functions have `serverLoader`/`serverAction` parameters which differentiate `ClientLoaderFunctionArgs`/`ClientActionFunctionArgs` -- Vite: Exclude modules within `.server` directories from client build ([#8154](https://github.com/remix-run/remix/pull/8154)) -- Vite: Strict route exports ([#8171](https://github.com/remix-run/remix/pull/8171)) - -### Patch Changes - -- `@remix-run/server-runtime`: Fix flash of unstyled content for non-Express custom servers in Vite dev ([#8076](https://github.com/remix-run/remix/pull/8076)) -- `@remix-run/server-runtime`: Pass request handler errors to `vite.ssrFixStacktrace` in Vite dev to ensure stack traces correctly map to the original source code ([#8066](https://github.com/remix-run/remix/pull/8066)) -- `remix-serve`: Fix source map loading when file has `?t=timestamp` suffix (rebuilds) ([#8174](https://github.com/remix-run/remix/pull/8174)) -- `@remix-run/dev`: Change Vite build output paths to fix a conflict between how Vite and the Remix compiler each manage the `public` directory ([#8077](https://github.com/remix-run/remix/pull/8077)) - - ⚠️ **This is a breaking change for projects using the unstable Vite plugin** - - The server is now compiled into `build/server` rather than `build`, and the client is now compiled into `build/client` rather than `public` - - For more information on the changes and guidance on how to migrate your project, refer to the updated [Remix Vite documentation](https://remix.run/future/vite) -- `@remix-run/dev`: Upgrade Vite peer dependency range to v5 ([#8172](https://github.com/remix-run/remix/pull/8172)) -- `@remix-run/dev`: Support HMR for routes with `handle` export in Vite dev ([#8022](https://github.com/remix-run/remix/pull/8022)) -- `@remix-run/dev`: Fix flash of unstyled content for non-Express custom servers in Vite dev ([#8076](https://github.com/remix-run/remix/pull/8076)) -- `@remix-run/dev`: Bundle CSS imported in client entry file in Vite plugin ([#8143](https://github.com/remix-run/remix/pull/8143)) -- `@remix-run/dev`: Remove undocumented `legacyCssImports` option from Vite plugin due to issues with `?url` imports of CSS files not being processed correctly in Vite ([#8096](https://github.com/remix-run/remix/pull/8096)) -- `@remix-run/dev`: Vite: fix access to default `entry.{client,server}.tsx` within `pnpm` workspaces on Windows ([#8057](https://github.com/remix-run/remix/pull/8057)) -- `@remix-run/dev`: Remove `unstable_createViteServer` and `unstable_loadViteServerBuild` which were only minimal wrappers around Vite's `createServer` and `ssrLoadModule` functions when using a custom server ([#8120](https://github.com/remix-run/remix/pull/8120)) - - - ⚠️ **This is a breaking change for projects using the unstable Vite plugin with a custom server** - - Instead, we now provide `unstable_viteServerBuildModuleId` so that custom servers interact with Vite directly rather than via Remix APIs, for example: - - ```diff - -import { - - unstable_createViteServer, - - unstable_loadViteServerBuild, - -} from "@remix-run/dev"; - +import { unstable_viteServerBuildModuleId } from "@remix-run/dev"; - ``` - - Creating the Vite server in middleware mode: - - ```diff - const vite = - process.env.NODE_ENV === "production" - ? undefined - - : await unstable_createViteServer(); - + : await import("vite").then(({ createServer }) => - + createServer({ - + server: { - + middlewareMode: true, - + }, - + }) - + ); - ``` - - Loading the Vite server build in the request handler: - - ```diff - app.all( - "*", - createRequestHandler({ - build: vite - - ? () => unstable_loadViteServerBuild(vite) - + ? () => vite.ssrLoadModule(unstable_viteServerBuildModuleId) - : await import("./build/server/index.js"), - }) - ); - ``` - -- `@remix-run/dev`: Pass request handler errors to `vite.ssrFixStacktrace` in Vite dev to ensure stack traces correctly map to the original source code ([#8066](https://github.com/remix-run/remix/pull/8066)) -- `@remix-run/dev`: Vite: Preserve names for exports from `.client` imports ([#8200](https://github.com/remix-run/remix/pull/8200)) - - Unlike `.server` modules, the main idea is not to prevent code from leaking into the server build since the client build is already public - - Rather, the goal is to isolate the SSR render from client-only code - - Routes need to import code from `.client` modules without compilation failing and then rely on runtime checks to determine if the code is running on the server or client - - Replacing `.client` modules with empty modules would cause the build to fail as ESM named imports are statically analyzed - - So instead, we preserve the named export but replace each exported value with an empty object - - That way, the import is valid at build time and the standard runtime checks can be used to determine if then code is running on the server or client -- `@remix-run/dev`: Add `@remix-run/node` to Vite's `optimizeDeps.include` array ([#8177](https://github.com/remix-run/remix/pull/8177)) -- `@remix-run/dev`: Improve Vite plugin performance ([#8121](https://github.com/remix-run/remix/pull/8121)) - - Parallelize detection of route module exports - - Disable `server.preTransformRequests` in Vite child compiler since it's only used to process route modules -- `@remix-run/dev`: Remove automatic global Node polyfill installation from the built-in Vite dev server and instead allow explicit opt-in ([#8119](https://github.com/remix-run/remix/pull/8119)) - - - ⚠️ **This is a breaking change for projects using the unstable Vite plugin without a custom server** - - If you're not using a custom server, you should call `installGlobals` in your Vite config instead. - - ```diff - import { unstable_vitePlugin as remix } from "@remix-run/dev"; - +import { installGlobals } from "@remix-run/node"; - import { defineConfig } from "vite"; - - +installGlobals(); - - export default defineConfig({ - plugins: [remix()], - }); - ``` - -- `@remix-run/dev`: Vite: Errors at build-time when client imports .server default export ([#8184](https://github.com/remix-run/remix/pull/8184)) - - Remix already stripped .server file code before ensuring that server code never makes it into the client - - That results in errors when client code tries to import server code, which is exactly what we want! - - But those errors were happening at runtime for default imports - - A better experience is to have those errors happen at build-time so that you guarantee that your users won't hit them -- `@remix-run/dev`: Fix `request instanceof Request` checks when using Vite dev server ([#8062](https://github.com/remix-run/remix/pull/8062)) - -### Updated Dependencies - -- [`react-router-dom@6.21.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.21.0) -- [`@remix-run/router@1.14.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1140) -- [`@remix-run/web-fetch@4.4.2`](https://github.com/remix-run/web-std-io/releases/tag/%40remix-run%2Fweb-fetch%404.4.2) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/create-remix/CHANGELOG.md#240) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/remix-architect/CHANGELOG.md#240) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/remix-cloudflare/CHANGELOG.md#240) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/remix-cloudflare-pages/CHANGELOG.md#240) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/remix-cloudflare-workers/CHANGELOG.md#240) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/remix-css-bundle/CHANGELOG.md#240) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/remix-deno/CHANGELOG.md#240) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/remix-dev/CHANGELOG.md#240) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/remix-eslint-config/CHANGELOG.md#240) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/remix-express/CHANGELOG.md#240) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/remix-node/CHANGELOG.md#240) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/remix-react/CHANGELOG.md#240) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/remix-serve/CHANGELOG.md#240) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/remix-server-runtime/CHANGELOG.md#240) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.4.0/packages/remix-testing/CHANGELOG.md#240) - -**Full Changelog**: [`v2.3.1...v2.4.0`](https://github.com/remix-run/remix/compare/remix@2.3.1...remix@2.4.0) - -## v2.3.1 - -Date: 2023-11-22 - -### Patch Changes - -- `@remix-run/dev`: Support `nonce` prop on `LiveReload` component in Vite dev ([#8014](https://github.com/remix-run/remix/pull/8014)) -- `@remix-run/dev`: Ensure code-split JS files in the server build's assets directory aren't cleaned up after Vite build ([#8042](https://github.com/remix-run/remix/pull/8042)) -- `@remix-run/dev`: Fix redundant copying of assets from `public` directory in Vite build ([#8039](https://github.com/remix-run/remix/pull/8039)) - - This ensures that static assets aren't duplicated in the server build directory - - This also fixes an issue where the build would break if `assetsBuildDirectory` was deeply nested within the `public` directory - -### Updated Dependencies - -- [`react-router-dom@6.20.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.20.0) -- [`@remix-run/router@1.13.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1130) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/create-remix/CHANGELOG.md#231) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/remix-architect/CHANGELOG.md#231) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/remix-cloudflare/CHANGELOG.md#231) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/remix-cloudflare-pages/CHANGELOG.md#231) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/remix-cloudflare-workers/CHANGELOG.md#231) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/remix-css-bundle/CHANGELOG.md#231) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/remix-deno/CHANGELOG.md#231) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/remix-dev/CHANGELOG.md#231) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/remix-eslint-config/CHANGELOG.md#231) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/remix-express/CHANGELOG.md#231) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/remix-node/CHANGELOG.md#231) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/remix-react/CHANGELOG.md#231) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/remix-serve/CHANGELOG.md#231) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/remix-server-runtime/CHANGELOG.md#231) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.3.1/packages/remix-testing/CHANGELOG.md#231) - -**Full Changelog**: [`v2.3.0...v2.3.1`](https://github.com/remix-run/remix/compare/remix@2.3.0...remix@2.3.1) - -## v2.3.0 - -Date: 2023-11-16 - -### What's Changed - -#### Stabilized `useBlocker` - -We've removed the `unstable_` prefix from the [`useBlocker`](https://remix.run/hooks/use-blocker) hook as it's been in use for enough time that we are confident in the API. We do not plan to remove the prefix from [`unstable_usePrompt`](https://remix.run/hooks/use-prompt) due to differences in how browsers handle `window.confirm` that prevent React Router from guaranteeing consistent/correct behavior. - -#### `unstable_flushSync` API - -We've added a new `unstable_flushSync` option to the imperative APIs (`useSubmit`, `useNavigate`, `fetcher.submit`, `fetcher.load`) to let users opt-into synchronous DOM updates for pending/optimistic UI. - -```js -function handleClick() { - submit(data, { flushSync: true }); - // Everything is flushed to the DOM so you can focus/scroll to your pending/optimistic UI - setFocusAndOrScrollToNewlyAddedThing(); -} -``` - -### Minor Changes - -- Remove the `unstable_` prefix from the [`useBlocker`](https://reactrouter.com/v6/hooks/use-blocker) hook ([#7882](https://github.com/remix-run/remix/pull/7882)) -- Add `unstable_flushSync` option to `useNavigate`/`useSubmit`/`fetcher.load`/`fetcher.submit` to opt-out of `React.startTransition` and into `ReactDOM.flushSync` for state updates ([#7996](https://github.com/remix-run/remix/pull/7996)) - -### Patch Changes - -- `@remix-run/react`: Add missing `modulepreload` for the manifest ([#7684](https://github.com/remix-run/remix/pull/7684)) -- `@remix-run/server-runtime`: Updated `cookie` dependency from `0.4.1` to [`0.5.0`](https://github.com/jshttp/cookie/blob/v0.5.0/HISTORY.md#050--2022-04-11) to inherit support for `Priority` attribute in Chrome ([#6770](https://github.com/remix-run/remix/pull/6770)) -- `@remix-run/dev`: Fix `FutureConfig` type ([#7895](https://github.com/remix-run/remix/pull/7895)) -- _Lots_ of small fixes for the unstable `vite` compiler: - - Support optional rendering of the `LiveReload` component in Vite dev ([#7919](https://github.com/remix-run/remix/pull/7919)) - - Support rendering of the `LiveReload` component after `Scripts` in Vite dev ([#7919](https://github.com/remix-run/remix/pull/7919)) - - Fix `react-refresh/babel` resolution for custom server with `pnpm` ([#7904](https://github.com/remix-run/remix/pull/7904)) - - Support JSX usage in `.jsx` files without manual `React` import in Vite ([#7888](https://github.com/remix-run/remix/pull/7888)) - - Fix Vite production builds when plugins that have different local state between `development` and `production` modes are present (e.g. `@mdx-js/rollup`) ([#7911](https://github.com/remix-run/remix/pull/7911)) - - Cache resolution of Remix Vite plugin options ([#7908](https://github.com/remix-run/remix/pull/7908)) - - Support Vite 5 ([#7846](https://github.com/remix-run/remix/pull/7846)) - - Allow `process.env.NODE_ENV` values other than `"development"` in Vite dev ([#7980](https://github.com/remix-run/remix/pull/7980)) - - Attach CSS from shared chunks to routes in Vite build ([#7952](https://github.com/remix-run/remix/pull/7952)) - - Let Vite handle serving files outside of project root via `/@fs` ([#7913](https://github.com/remix-run/remix/pull/7913)) - - This fixes errors when using default client entry or server entry in a pnpm project where those files may be outside of the project root, but within the workspace root - - By default, Vite prevents access to files outside the workspace root (when using workspaces) or outside of the project root (when not using workspaces) unless user explicitly opts into it via Vite's `server.fs.allow` - - Improve performance of LiveReload proxy in Vite dev ([#7883](https://github.com/remix-run/remix/pull/7883)) - - Deduplicate `@remix-run/react` ([#7926](https://github.com/remix-run/remix/pull/7926)) - - Pre-bundle Remix dependencies to avoid Remix router duplicates - - Our `remix-react-proxy` plugin does not process default client and server entry files since those come from within `node_modules` - - That means that before Vite pre-bundles dependencies (e.g. first time dev server is run) mismatching Remix routers cause `Error: You must render this element inside a element` - - Fix React Fast Refresh error on load when using `defer` in Vite dev server ([#7842](https://github.com/remix-run/remix/pull/7842)) - - Handle multiple `Set-Cookie` headers in Vite dev server ([#7843](https://github.com/remix-run/remix/pull/7843)) - - Fix flash of unstyled content on initial page load in Vite dev when using a custom Express server ([#7937](https://github.com/remix-run/remix/pull/7937)) - - Populate `process.env` from `.env` files on the server in Vite dev ([#7958](https://github.com/remix-run/remix/pull/7958)) - - Emit assets that were only referenced in the server build into the client assets directory in Vite build ([#7892](https://github.com/remix-run/remix/pull/7892), cherry-picked in [`8cd31d65`](https://github.com/remix-run/remix/commit/8cd31d6543ef4c765220fc64dca9bcc9c61ee9eb)) - -### Updated Dependencies - -- [`react-router-dom@6.19.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.19.0) -- [`@remix-run/router@1.12.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1120) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/create-remix/CHANGELOG.md#230) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/remix-architect/CHANGELOG.md#230) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/remix-cloudflare/CHANGELOG.md#230) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/remix-cloudflare-pages/CHANGELOG.md#230) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/remix-cloudflare-workers/CHANGELOG.md#230) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/remix-css-bundle/CHANGELOG.md#230) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/remix-deno/CHANGELOG.md#230) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/remix-dev/CHANGELOG.md#230) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/remix-eslint-config/CHANGELOG.md#230) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/remix-express/CHANGELOG.md#230) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/remix-node/CHANGELOG.md#230) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/remix-react/CHANGELOG.md#230) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/remix-serve/CHANGELOG.md#230) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/remix-server-runtime/CHANGELOG.md#230) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.3.0/packages/remix-testing/CHANGELOG.md#230) - -**Full Changelog**: [`v2.2.0...v2.3.0`](https://github.com/remix-run/remix/compare/remix@2.2.0...remix@2.3.0) - -## v2.2.0 - -Date: 2023-10-31 - -### What's Changed - -#### Vite! - -Remix `2.2.0` adds unstable support for Vite for Node-based apps! See our [announcement blog post](https://remix.run/blog/remix-heart-vite) and the [_Future > Vite_ page in the Remix docs](https://remix.run/docs/en/2.2.0/future/vite) for more details. - -You can try it out today with two new (unstable) templates: - -```shellscript -# minimal server -npx create-remix@latest --template remix-run/remix/templates/unstable-vite - -# custom server (Express example) -npx create-remix@latest --template remix-run/remix/templates/unstable-vite-express -``` - -- **New APIs in `@remix-run/dev`** - - `unstable_vitePlugin`: The new Remix Vite plugin - - `unstable_createViteServer`: Creates a Vite server in middleware mode for interop with custom servers - - `unstable_loadViteServerBuild`: Allows your custom server to delegate SSR requests to Vite during development -- **Changed APIs** - - `createRequestHandler`: Now also allows the `build` argument to be a function that will be used to dynamically load new builds for each request during development -- **Other Runtimes** - - Deno support is untested, but should work through Deno's Node/`npm` interop - - CloudFlare support is not yet available - -#### New Fetcher APIs - -Per this [RFC](https://github.com/remix-run/remix/discussions/7698), we've introduced some new APIs that give you more granular control over your fetcher behaviors: - -- You may now specify your own fetcher identifier via `useFetcher({ key: string })`, which allows you to access the same fetcher instance from different components in your application without prop-drilling -- Fetcher keys are now exposed on the fetchers returned from `useFetchers` so that they can be looked up by `key` -- `Form` and `useSubmit` now support optional `navigate`/`fetcherKey` props/params to allow kicking off a fetcher submission under the hood with an optionally user-specified `key` - - `` - - `submit(data, { method: "post", navigate: false, fetcherKey: "my-key" })` - - Invoking a fetcher in this way is ephemeral and stateless - - If you need to access the state of one of these fetchers, you will need to leverage `useFetchers()` or `useFetcher({ key })` to look it up elsewhere - -#### Persistence Future Flag - -Per the same [RFC](https://github.com/remix-run/remix/discussions/7698) as above, we've introduced a new `future.v3_fetcherPersist` flag that allows you to opt-into the new fetcher persistence/cleanup behavior. Instead of being immediately cleaned up on unmount, fetchers will persist until they return to an `idle` state. This makes pending/optimistic UI _much_ easier in scenarios where the originating fetcher needs to unmount. - -- This is sort of a long-standing bug fix as the `useFetchers()` API was always supposed to only reflect **in-flight** fetcher information for pending/optimistic UI -- it was not intended to reflect fetcher data or hang onto fetchers after they returned to an `idle` state -- Keep an eye out for the following specific behavioral changes when opting into this flag and check your app for compatibility: - - Fetchers that complete _while still mounted_ will no longer appear in `useFetchers()` after completion - they served no purpose in there since you can access the data via `useFetcher().data` - - Fetchers that previously unmounted _while in-flight_ will not be immediately aborted and will instead be cleaned up once they return to an `idle` state - - They will remain exposed via `useFetchers` while in-flight so you can still access pending/optimistic data after unmount - - If a fetcher is no longer mounted when it completes, then it's result will not be post processed - e.g., redirects will not be followed and errors will not bubble up in the UI - - However, if a fetcher was re-mounted elsewhere in the tree using the same `key`, then it's result will be processed, even if the originating fetcher was unmounted - -### Minor Changes - -- Unstable `vite` support ([#7590](https://github.com/remix-run/remix/pull/7590)) -- New fetcher `key` APIs and `navigate`/`fetcherKey` params for navigational APIs ([#10960](https://github.com/remix-run/react-router/pull/10960)) -- New `future.v3_fetcherPersist` flag ([#10962](https://github.com/remix-run/react-router/pull/10962)) - -### Patch Changes - -- `@remix-run/express`: Allow the Express adapter to work behind a proxy when using `app.enable('trust proxy')` ([#7323](https://github.com/remix-run/remix/pull/7323)) - - Previously, this used `req.get('host')` to construct the Remix `Request`, but that does not respect `X-Forwarded-Host` - - This now uses `req.hostname` which will respect `X-Forwarded-Host` -- `@remix-run/react`: Fix warning that could be inadvertently logged when using route files with no `default` export ([#7745](https://github.com/remix-run/remix/pull/7745)) -- `create-remix`: Support local tarballs with a `.tgz` extension which allows direct support for [`pnpm pack` tarballs](https://pnpm.io/cli/pack) ([#7649](https://github.com/remix-run/remix/pull/7649)) -- `create-remix`: Default the Remix app version to the version of `create-remix` being used ([#7670](https://github.com/remix-run/remix/pull/7670)) - - This most notably enables easier usage of tags, e.g. `npm create remix@nightly` - -### Updated Dependencies - -- [`react-router-dom@6.18.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.18.0) -- [`@remix-run/router@1.11.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1110) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/create-remix/CHANGELOG.md#220) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/remix-architect/CHANGELOG.md#220) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/remix-cloudflare/CHANGELOG.md#220) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/remix-cloudflare-pages/CHANGELOG.md#220) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/remix-cloudflare-workers/CHANGELOG.md#220) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/remix-css-bundle/CHANGELOG.md#220) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/remix-deno/CHANGELOG.md#220) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/remix-dev/CHANGELOG.md#220) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/remix-eslint-config/CHANGELOG.md#220) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/remix-express/CHANGELOG.md#220) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/remix-node/CHANGELOG.md#220) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/remix-react/CHANGELOG.md#220) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/remix-serve/CHANGELOG.md#220) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/remix-server-runtime/CHANGELOG.md#220) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.2.0/packages/remix-testing/CHANGELOG.md#220) - -**Full Changelog**: [`v2.1.0...v2.2.0`](https://github.com/remix-run/remix/compare/remix@2.1.0...remix@2.2.0) - -## v2.1.0 - -Date: 2023-10-16 - -### What's Changed - -#### View Transitions - -We're excited to release experimental support for the the [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/ViewTransition) in Remix! You can now trigger navigational DOM updates to be wrapped in `document.startViewTransition` to enable CSS animated transitions on SPA navigations in your application. - -The simplest approach to enabling a View Transition in your Remix app is via the new [``](https://remix.run/docs/components/link#unstable_viewtransition) prop. This will cause the navigation DOM update to be wrapped in `document.startViewTransition` which will enable transitions for the DOM update. Without any additional CSS styles, you'll get a basic cross-fade animation for your page. - -If you need to apply more fine-grained styles for your animations, you can leverage the [`unstable_useViewTransitionState`](https://remix.run/docs/hooks/use-view-transition-state) hook which will tell you when a transition is in progress and you can use that to apply classes or styles: - -```jsx -function ImageLink(to, src, alt) { - const isTransitioning = unstable_useViewTransitionState(to); - return ( - - {alt} - - ); -} -``` - -You can also use the [``](https://remix.run/docs/components/nav-link#unstable_viewtransition) shorthand which will manage the hook usage for you and automatically add a `transitioning` class to the `` during the transition: - -```css -a.transitioning img { - view-transition-name: "image-expand"; -} -``` - -```jsx - - {alt} - -``` - -For an example usage of View Transitions, check out [our fork](https://github.com/brophdawg11/react-router-records) of the [Astro Records](https://github.com/Charca/astro-records) demo (which uses React Router but so does Remix 😉). - -For more information on using the View Transitions API, please refer to the [Smooth and simple transitions with the View Transitions API](https://developer.chrome.com/docs/web-platform/view-transitions/) guide from the Google Chrome team. - -#### Stable `createRemixStub` - -After real-world experience, we're confident in the [`createRemixStub`](https://remix.run/docs/utils/create-remix-stub) API and ready to commit to it, so in `2.1.0` we've removed the `unstable_` prefix. - -⚠️ Please note that this did involve 1 _small_ breaking change - the `` prop has been renamed to `` to decouple the `future` prop from a specific file location. - -### Minor Changes - -- Added unstable support for the View Transition API ([#10916](https://github.com/remix-run/react-router/pull/10916)) -- Stabilized the `@remix-run/testing` `createRemixStub` helper ([#7647](https://github.com/remix-run/remix/pull/7647)) - -### Patch Changes - -- Emulate types for `JSON.parse(JSON.stringify(x))` in `SerializeFrom` ([#7605](https://github.com/remix-run/remix/pull/7605)) - - Notably, type fields that are only assignable to `undefined` after serialization are now omitted since `JSON.stringify |> JSON.parse` will omit them. See test cases for examples - - This fixes type errors when upgrading to v2 from 1.19 -- Avoid mutating `meta` object when `tagName` is specified ([#7594](https://github.com/remix-run/remix/pull/7594)) -- Fix FOUC on subsequent client-side navigations to `route.lazy` routes ([#7576](https://github.com/remix-run/remix/pull/7576)) -- Export the proper Remix `useMatches` wrapper to fix `UIMatch` typings ([#7551](https://github.com/remix-run/remix/pull/7551)) -- `@remix-run/cloudflare` - sourcemap takes into account special chars in output file ([#7574](https://github.com/remix-run/remix/pull/7574)) -- `@remix-run/express` - Flush headers for `text/event-stream` responses ([#7619](https://github.com/remix-run/remix/pull/7619)) - -### Updated Dependencies - -- [`react-router-dom@6.17.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.17.0) -- [`@remix-run/router@1.10.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1100) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/create-remix/CHANGELOG.md#210) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/remix-architect/CHANGELOG.md#210) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/remix-cloudflare/CHANGELOG.md#210) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/remix-cloudflare-pages/CHANGELOG.md#210) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/remix-cloudflare-workers/CHANGELOG.md#210) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/remix-css-bundle/CHANGELOG.md#210) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/remix-deno/CHANGELOG.md#210) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/remix-dev/CHANGELOG.md#210) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/remix-eslint-config/CHANGELOG.md#210) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/remix-express/CHANGELOG.md#210) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/remix-node/CHANGELOG.md#210) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/remix-react/CHANGELOG.md#210) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/remix-serve/CHANGELOG.md#210) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/remix-server-runtime/CHANGELOG.md#210) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.1.0/packages/remix-testing/CHANGELOG.md#210) - -**Full Changelog**: [`v2.0.1...v2.1.0`](https://github.com/remix-run/remix/compare/remix@2.0.1...remix@2.1.0) - -## v2.0.1 - -Date: 2023-09-21 - -### Patch Changes - -- Fix types for MDX files when using pnpm ([#7491](https://github.com/remix-run/remix/pull/7491)) -- Update `getDependenciesToBundle` to handle ESM packages without main exports ([#7272](https://github.com/remix-run/remix/pull/7272)) - - Note that these packages must expose `package.json` in their `exports` field so that their path can be resolved -- Fix server builds where `serverBuildPath` extension is `.cjs` ([#7180](https://github.com/remix-run/remix/pull/7180)) -- Fix HMR for CJS projects using `remix-serve` and manual mode (`remix dev --manual`) ([#7487](https://github.com/remix-run/remix/pull/7487)) - - By explicitly busting the `require` cache, `remix-serve` now correctly re-imports new server changes in CJS - - ESM projects were already working correctly and are not affected by this. -- Fix error caused by partially written server build ([#7470](https://github.com/remix-run/remix/pull/7470)) - - Previously, it was possible to trigger a reimport of the app server code before the new server build had completely been written. Reimporting the partially written server build caused issues related to `build.assets` being undefined and crashing when reading `build.assets.version` -- Add second generic to `UIMatch` for `handle` field ([#7464](https://github.com/remix-run/remix/pull/7464)) -- Fix resource routes being loaded through `route.lazy` ([#7498](https://github.com/remix-run/remix/pull/7498)) -- Throw a semantically correct 405 `ErrorResponse` instead of just an `Error` when submitting to a route without an `action` ([#7423](https://github.com/remix-run/remix/pull/7423)) -- Update to latest version of `@remix-run/web-fetch` ([#7477](https://github.com/remix-run/remix/pull/7477)) -- Switch from `crypto.randomBytes` to `crypto.webcrypto.getRandomValues` for file session storage ID generation ([#7203](https://github.com/remix-run/remix/pull/7203)) -- Use native `Blob` class instead of polyfill ([#7217](https://github.com/remix-run/remix/pull/7217)) - -### Changes by Package 🔗 - -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.0.1/packages/remix-dev/CHANGELOG.md#201) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.0.1/packages/remix-node/CHANGELOG.md#201) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.0.1/packages/remix-react/CHANGELOG.md#201) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.0.1/packages/remix-serve/CHANGELOG.md#201) - -**Full Changelog**: [`v2.0.0...v2.0.1`](https://github.com/remix-run/remix/compare/remix@2.0.0...remix@2.0.1) - -## v2.0.0 - -Date: 2023-09-15 - -We're _**so**_ excited to release Remix v2 to you and we really hope this upgrade is one of the smoothest framework upgrades you've ever experienced! That was our primary goal with v2 - something we aimed to achieve through a heavy use of deprecation warnings and [Future Flags](https://remix.run/blog/future-flags) in Remix v1. - -If you are on the latest `1.x` version and you've enabled all future flags and addressed all console warnings, then our hope is that you are 90% of the way to being upgraded for v2. There are always going to be a few things that we _can't_ put behind a flag (like breaking type changes) or come up at the very last moment and don't have time to add as a warning or flag in `1.x`. - -If you're _not_ yet on the latest 1.x version we'd recommend first upgrading to that and resolving any flag/console warnings: - -```sh -> npx upgrade-remix 1.19.3 -``` - -### Breaking Changes - -Below is a _very concise_ list of the breaking changes in v2. - -- For the most thorough discussion of breaking changes, please read the [**Upgrading to v2**](https://remix.run/docs/en/main/start/v2) guide. This document provides a comprehensive walkthrough of the breaking changes that come along with v2 - and instructions on how to adapt your application to handle them -- For additional details, you can refer to the [Changes by Package](#changes-by-package) section below - -#### Upgraded Dependency Requirements - -Remix v2 has upgraded it's minimum version support for React and Node and now officially requires: - -- React 18 ([#7121](https://github.com/remix-run/remix/pull/7121)) - - For information on upgrading to React 18, please see the React [upgrade guide](https://react.dev/blog/2022/03/08/react-18-upgrade-guide) -- Node 18 or later ([#6939](https://github.com/remix-run/remix/pull/6939), [#7292](https://github.com/remix-run/remix/pull/7292)) - - For information on upgrading to Node 18, please see the Node [v18 announcement](https://nodejs.org/en/blog/announcements/v18-release-announce) - - Please refer to the [Remix documentation](https://remix.run/docs/en/main/other-api/node#version-support) for an overview of when we drop support for Node versions - -#### Removed Future Flags - -The following future flags were removed and their behavior is now the default - you can remove all of these from your `remix.config.js` file. - -- [`v2_dev`](https://remix.run/docs/en/main/start/v2#remix-dev) - New dev server with HMR+HDR ([#7002](https://github.com/remix-run/remix/pull/7002)) - - If you had configurations in `future.v2_dev` instead of just the boolean value (i.e., `future.v2_dev.port`), you can lift them into a root `dev` object in your `remix.config.js` -- [`v2_errorBoundary`](https://remix.run/docs/en/main/start/v2#catchboundary-and-errorboundary) - Removed `CatchBoundary` in favor of a singular `ErrorBoundary` ([#6906](https://github.com/remix-run/remix/pull/6906)) -- [`v2_headers`](https://remix.run/docs/en/main/start/v2#route-headers) - Altered the logic for `headers` in nested route scenarios ([#6979](https://github.com/remix-run/remix/pull/6979)) -- [`v2_meta`](https://remix.run/docs/en/main/start/v2#route-meta) - Altered the return format of `meta()` ([#6958](https://github.com/remix-run/remix/pull/6958)) -- [`v2_normalizeFormMethod`](https://remix.run/docs/en/main/start/v2#formmethod) - Normalize `formMethod` APIs to uppercase ([#6875](https://github.com/remix-run/remix/pull/6875)) -- [`v2_routeConvention`](https://remix.run/docs/en/main/start/v2#file-system-route-convention) - Routes use a flat route convention by default now ([#6969](https://github.com/remix-run/remix/pull/6969)) - -#### Breaking Changes/API Removals - -##### With deprecation warnings - -The following lists other breaking changes/API removals which had deprecation warnings in Remix v1. If you're on the latest `1.19.3` release without any console warnings, then you're probably good to go on all of these! - -- `remix.config.js` - - Renamed [`browserBuildDirectory`](https://remix.run/docs/en/main/start/v2#browserbuilddirectory) to `assetsBuildDirectory` ([#6900](https://github.com/remix-run/remix/pull/6900)) - - Removed [`devServerBroadcastDelay`](https://remix.run/docs/en/main/start/v2#devserverbroadcastdelay) ([#7063](https://github.com/remix-run/remix/pull/7063)) - - Renamed [`devServerPort`](https://remix.run/docs/en/main/start/v2#devserverport) to `dev.port` ([`000457e0`](https://github.com/remix-run/remix/commit/000457e0ae025d9b94e721af254c319e83438923)) - - Note that if you are opting into this in a `1.x` release, your config flag will be `future.v2_dev.port`, but on a stable `2.x` release it will be `dev.port` - - Changed the default [`serverModuleFormat`](https://remix.run/docs/en/main/start/v2#servermoduleformat) from `cjs` to `esm` ([#6949](https://github.com/remix-run/remix/pull/6949)) - - Removed [`serverBuildTarget`](https://remix.run/docs/en/main/start/v2#serverbuildtarget) ([#6896](https://github.com/remix-run/remix/pull/6896)) - - Changed [`serverBuildDirectory`](https://remix.run/docs/en/main/start/v2#serverbuilddirectory) to `serverBuildPath` ([#6897](https://github.com/remix-run/remix/pull/6897)) - - Node built-ins are no longer polyfilled on the server by default, you must opt-into polyfills via [`serverNodeBuiltinsPolyfill`](https://remix.run/docs/en/main/start/v2#servernodebuiltinspolyfill) ([#6911](https://github.com/remix-run/remix/pull/6911) -- `@remix-run/react` - - Removed [`useTransition`](https://remix.run/docs/en/main/start/v2#usetransition) ([#6870](https://github.com/remix-run/remix/pull/6870)) - - Removed [`fetcher.type`](https://remix.run/docs/en/main/start/v2#usefetcher) and flattened [`fetcher.submission`](https://remix.run/docs/en/main/start/v2#usefetcher) ([#6874](https://github.com/remix-run/remix/pull/6874)) - - `` is now more accurately categorized as `state:"loading"` instead of `state:"submitting"` to better align with the underlying GET request - - Require camelCased versions of [`imagesrcset`/`imagesizes`](https://remix.run/docs/en/main/start/v2#links-imagesizes-and-imagesrcset) ([#6936](https://github.com/remix-run/remix/pull/6936)) - -##### Without deprecation warnings - -Unfortunately, we didn't manage to get a deprecation warning on _every_ breaking change or API removal 🙃. Here's a list of remaining changes that you may need to look into to upgrade to v2: - -- `remix.config.js` - - Node built-ins are no longer polyfilled in the browser by default, you must opt-into polyfills via [`browserNodeBuiltinsPolyfill`](https://remix.run/docs/en/main/start/v2#browsernodebuiltinspolyfill) ([#7269](https://github.com/remix-run/remix/pull/7269)) - - PostCSS/Tailwind will be enabled by default if config files exist in your app, you may disable this via the [`postcss` and `tailwind`](https://remix.run/docs/en/main/start/v2#built-in-postcsstailwind-support) flags ([#6909](https://github.com/remix-run/remix/pull/6909)) -- `@remix-run/cloudflare` - - Remove `createCloudflareKVSessionStorage` ([#6898](https://github.com/remix-run/remix/pull/6898)) - - Drop `@cloudflare/workers-types` v2 & v3 support ([#6925](https://github.com/remix-run/remix/pull/6925)) -- `@remix-run/dev` - - Removed `REMIX_DEV_HTTP_ORIGIN` in favor of `REMIX_DEV_ORIGIN` ([#6963](https://github.com/remix-run/remix/pull/6963)) - - Removed `REMIX_DEV_SERVER_WS_PORT` in favor of `dev.port` or `--port` ([#6965](https://github.com/remix-run/remix/pull/6965)) - - Removed `--no-restart`/`restart` flag in favor of `--manual`/`manual` ([#6962](https://github.com/remix-run/remix/pull/6962)) - - Removed `--scheme`/`scheme` and `--host`/`host` in favor of `REMIX_DEV_ORIGIN` instead ([#6962](https://github.com/remix-run/remix/pull/6962)) - - Removed the `codemod` command ([#6918](https://github.com/remix-run/remix/pull/6918)) -- `@remix-run/eslint-config` - - Remove `@remix-run/eslint-config/jest` config ([#6903](https://github.com/remix-run/remix/pull/6903)) - - Remove magic imports ESLint warnings ([#6902](https://github.com/remix-run/remix/pull/6902)) -- `@remix-run/netlify` - - The [`@remix-run/netlify`](https://remix.run/docs/en/main/start/v2#netlify-adapter) adapter has been removed in favor of the Netlify official adapters ([#7058](https://github.com/remix-run/remix/pull/7058)) -- `@remix-run/node` - - `fetch` is no longer polyfilled by default - apps must call [`installGlobals()`](https://remix.run/docs/en/main/start/v2#installglobals) to install the polyfills ([#7009](https://github.com/remix-run/remix/pull/7009)) - - `fetch` and related APIs are no longer exported from `@remix-run/node` - apps should use the versions in the global namespace ([#7293](https://github.com/remix-run/remix/pull/7293)) - - Apps must call [`sourceMapSupport.install()`](https://remix.run/docs/en/main/start/v2#source-map-support) to setup source map support -- `@remix-run/react` - - Remove `unstable_shouldReload` in favor of `shouldRevalidate` ([#6865](https://github.com/remix-run/remix/pull/6865)) -- `@remix-run/serve` - - `remix-serve` picks an open port if 3000 is taken and `PORT` is not specified ([#7278](https://github.com/remix-run/remix/pull/7278)) - - Integrate `manual` mode ([#7231](https://github.com/remix-run/remix/pull/7231)) - - Remove undocumented `createApp` Node API ([#7229](https://github.com/remix-run/remix/pull/7229)) - - Preserve dynamic imports in remix-serve for external bundle ([#7173](https://github.com/remix-run/remix/pull/7173)) -- `@remix-run/vercel` - - The [`@remix-run/vercel`](https://remix.run/docs/en/main/start/v2#vercel-adapter) adapter has been removed in favor of out of the box functionality provided by Vercel ([#7035](https://github.com/remix-run/remix/pull/7035)) -- `create-remix` - - Stop passing `isTypeScript` to `remix.init` script ([#7099](https://github.com/remix-run/remix/pull/7099)) -- `remix` - - Removed magic exports ([#6895](https://github.com/remix-run/remix/pull/6895)) - -##### Breaking Type Changes - -- Removed `V2_` prefixes from `future.v2_meta` types as they are now the default behavior ([#6958](https://github.com/remix-run/remix/pull/6958)) - - `V2_MetaArgs` -> `MetaArgs` - - `V2_MetaDescriptor` -> `MetaDescriptor` - - `V2_MetaFunction` -> `MetaFunction` - - `V2_MetaMatch` -> `MetaMatch` - - `V2_MetaMatches` -> `MetaMatches` - - `V2_ServerRuntimeMetaArgs` -> `ServerRuntimeMetaArgs` - - `V2_ServerRuntimeMetaDescriptor` -> `ServerRuntimeMetaDescriptor` - - `V2_ServerRuntimeMetaFunction` -> `ServerRuntimeMetaFunction` - - `V2_ServerRuntimeMetaMatch` -> `ServerRuntimeMetaMatch` - - `V2_ServerRuntimeMetaMatches` -> `ServerRuntimeMetaMatches` -- The following types were adjusted to prefer `unknown` over `any` and to align with underlying React Router types ([#7319](https://github.com/remix-run/remix/pull/7319)): - - Renamed the `useMatches()` return type from `RouteMatch` to `UIMatch` - - Renamed `LoaderArgs`/`ActionArgs` to `LoaderFunctionArgs`/`ActionFunctionArgs` - - `AppData` changed from `any` to `unknown` - - `Location["state"]` (`useLocation.state`) changed from `any` to `unknown` - - `UIMatch["data"]` (`useMatches()[i].data`) changed from `any` to `unknown` - - `UIMatch["handle"]` (`useMatches()[i].handle`) changed from `{ [k: string]: any }` to `unknown` - - `Fetcher["data"]` (`useFetcher().data`) changed from `any` to `unknown` - - `MetaMatch.handle` (used in `meta()`) changed from `any` to `unknown` - - `AppData`/`RouteHandle` are no longer exported as they are just aliases for `unknown` - -### New Features - -- New [`create-remix`](https://remix.run/docs/en/main/other-api/create-remix) CLI ([#6887](https://github.com/remix-run/remix/pull/6887)) - - Most notably, this removes the dropdown to choose your template/stack in favor of the `--template` flag and our ever-growing list of [available templates](https://remix.run/docs/en/main/guides/templates) - - Adds a new `--overwrite` flag ([#7062](https://github.com/remix-run/remix/pull/7062)) - - Supports the `bun` package manager ([#7074](https://github.com/remix-run/remix/pull/7074)) -- Detect built mode via `build.mode` ([#6964](https://github.com/remix-run/remix/pull/6964)) -- Support polyfilling node globals via `serverNodeBuiltinsPolyfill.globals`/`browserNodeBuiltinsPolyfill.globals` ([#7269](https://github.com/remix-run/remix/pull/7269)) -- New `redirectDocument` utility to redirect via a fresh document load ([#7040](https://github.com/remix-run/remix/pull/7040), [#6842](https://github.com/remix-run/remix/pull/6842)) -- Add `error` to `meta` params so you can render error titles, etc. ([#7105](https://github.com/remix-run/remix/pull/7105)) -- `unstable_createRemixStub` now supports adding `meta`/`links` functions on stubbed Remix routes ([#7186](https://github.com/remix-run/remix/pull/7186)) - - `unstable_createRemixStub` no longer supports the `element`/`errorElement` properties on routes. You must use `Component`/`ErrorBoundary` to match what you would export from a Remix route module. - -### Other Notable Changes - -- Remix now uses React Router's `route.lazy` method internally to load route modules on navigations ([#7133](https://github.com/remix-run/remix/pull/7133)) -- Removed the `@remix-run/node` `atob`/`btoa` polyfills in favor of the built-in versions ([#7206](https://github.com/remix-run/remix/pull/7206)) -- Decouple the `@remix-run/dev` package from the contents of the `@remix-run/css-bundle` package ([#6982](https://github.com/remix-run/remix/pull/6982)) - - The contents of the `@remix-run/css-bundle` package are now entirely managed by the Remix compiler. Even though it's still recommended that your Remix dependencies all share the same version, this change ensures that there are no runtime errors when upgrading `@remix-run/dev` without upgrading `@remix-run/css-bundle`. -- `remix-serve` now picks an open port if 3000 is taken ([#7278](https://github.com/remix-run/remix/pull/7278)) - - If `PORT` env var is set, `remix-serve` will use that port - - Otherwise, `remix-serve` picks an open port (3000 unless that is already taken) - -### Updated Dependencies - -- [`react-router-dom@6.16.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.16.0) -- [`@remix-run/router@1.9.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#190) -- [`@remix-run/web-fetch@4.4.0`](https://github.com/remix-run/web-std-io/releases/tag/%40remix-run%2Fweb-fetch%404.4.0) -- [`@remix-run/web-file@3.1.0`](https://github.com/remix-run/web-std-io/releases/tag/%40remix-run%2Fweb-file%403.1.0) -- [`@remix-run/web-stream@1.1.0`](https://github.com/remix-run/web-std-io/releases/tag/%40remix-run%2Fweb-stream%401.1.0) - -### Changes by Package - -- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/create-remix/CHANGELOG.md#200) -- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/remix-architect/CHANGELOG.md#200) -- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/remix-cloudflare/CHANGELOG.md#200) -- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/remix-cloudflare-pages/CHANGELOG.md#200) -- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/remix-cloudflare-workers/CHANGELOG.md#200) -- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/remix-css-bundle/CHANGELOG.md#200) -- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/remix-deno/CHANGELOG.md#200) -- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/remix-dev/CHANGELOG.md#200) -- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/remix-eslint-config/CHANGELOG.md#200) -- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/remix-express/CHANGELOG.md#200) -- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/remix-node/CHANGELOG.md#200) -- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/remix-react/CHANGELOG.md#200) -- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/remix-serve/CHANGELOG.md#200) -- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/remix-server-runtime/CHANGELOG.md#200) -- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.0.0/packages/remix-testing/CHANGELOG.md#200) diff --git a/CLA.md b/CLA.md deleted file mode 100644 index ab2a7875410..00000000000 --- a/CLA.md +++ /dev/null @@ -1,23 +0,0 @@ -Remix Software, Inc. Individual Contributor License Agreement ("Agreement"), v2.0 - -You accept and agree to the following terms and conditions for Your present and future Contributions submitted to Remix Software, Inc. ("Remix"). Except for the license granted herein to Remix and recipients of software distributed by Remix, You reserve all right, title, and interest in and to Your Contributions. - -1. Definitions. - -"You" (or "Your") shall mean the copyright owner or legal entity authorized by the copyright owner that is making this Agreement with Remix. For legal entities, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"Contribution" shall mean any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You to Remix for inclusion in, or documentation of, any of the products owned or managed by Remix (the "Work"). For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to Remix or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, Remix for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution." - -2. Grant of Copyright License. Subject to the terms and conditions of this Agreement, You hereby grant to Remix and to recipients of software distributed by Remix a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such derivative works. - -3. Grant of Patent License. Subject to the terms and conditions of this Agreement, You hereby grant to Remix and to recipients of software distributed by Remix a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Work to which such Contribution(s) was submitted. If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that your Contribution, or the Work to which you have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Work shall terminate as of the date such litigation is filed. - -4. You represent that you are legally entitled to grant the above license. If your employer(s) has rights to intellectual property that you create that includes your Contributions, you represent that you have received permission to make Contributions on behalf of that employer, that your employer has waived such rights for your Contributions to Remix, or that your employer has executed a separate Corporate CLA with Remix. - -5. You represent that each of Your Contributions is Your original creation (see section 7 for submissions on behalf of others). You represent that Your Contribution submissions include complete details of any third-party license or other restriction (including, but not limited to, related patents and trademarks) of which you are personally aware and which are associated with any part of Your Contributions. - -6. You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON- INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. - -7. Should You wish to submit work that is not Your original creation, You may submit it to Remix separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the work as "Submitted on behalf of a third-party: [named here]". - -8. You agree to notify Remix of any facts or circumstances of which you become aware that would make these representations inaccurate in any respect. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index a01a74ebcfb..00000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,125 +0,0 @@ -# Code of Conduct - -tl;dr: Be excellent to each other! - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, religion, or sexual identity -and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -- Demonstrating empathy and kindness toward other people -- Being respectful of differing opinions, viewpoints, and experiences -- Giving and gracefully accepting constructive feedback -- Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -- Focusing on what is best not just for us as individuals, but for the - overall community - -Examples of unacceptable behavior include: - -- The use of sexualized language or imagery, and sexual attention or - advances of any kind -- Trolling, insulting or derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or email - address, without their explicit permission -- Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official e-mail address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at hello@remix.run. -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series -of actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or -permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within -the community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.0, available at -https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. - -Community Impact Guidelines were inspired by [Mozilla's code of conduct -enforcement ladder](https://github.com/mozilla/diversity). - -[homepage]: https://www.contributor-covenant.org diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 92c0b9925a8..00000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contributing - -Please see [our guide to contributing](docs/guides/contributing.md). diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md deleted file mode 100644 index 0f9710428fd..00000000000 --- a/DEVELOPMENT.md +++ /dev/null @@ -1,149 +0,0 @@ -# Remix Development - -All Remix development happens here on GitHub. There are two main branches in this -repository that you should be aware of: - -- `main` - This is the stable line. Code in this branch should always pass all - the tests. Hot fixes may be pushed directly to this branch without appearing in - `dev`. Docs on the website reflect this branch. -- `dev` - This is where most development happens. When hot fix commits land in - `main` they are merged into this branch. Feature branches are based on this - branch and are merged in as they are completed. - -## Workflow - -We currently use [pnpm](https://pnpm.io) to develop Remix. - -```bash -# install everything -pnpm install - -# run the build -pnpm build - -# run the unit tests -pnpm test:primary - -# run the unit tests for a specific package in watch mode -pnpm test:primary packages/remix-react --watch - -# run the playwright integration tests in Chromium -pnpm test:integration --project chromium - -# run specific playwright integration tests in Chromium -pnpm test:integration integration/client-data --project chromium -``` - -## Releases - -New releases should be created from release branches originating from the `dev` branch. When you are ready to begin the release process: - -- Make sure you've pulled all of the changes from GitHub for both `dev` and `main` branches -- Check out the `dev` branch -- If needed, bump the dependencies to the correct React Router release - - `./scripts/bump-router-versions.sh [pre|latest]` -- Create a new release branch with the `release-` prefix - - `git checkout -b release-next` - - **IMPORTANT:** The `release-` prefix is important, as this is what triggers our GitHub CI workflow that will ultimately publish the release -- Merge `main` into the release branch - -Changesets will do most of the heavy lifting for our releases. When changes are made to the codebase, an accompanying changeset file should be included to document the change. Those files will dictate how Changesets will version our packages and what shows up in the changelogs. - -### Starting a new pre-release - -- Ensure you are on the new `release-*` branch -- Enter Changesets pre-release mode using the `pre` tag: `pnpm changeset pre enter pre` -- Commit the change and push the `release-*` branch to GitHub -- Wait for the release workflow to finish - the Changesets action in the workflow will open a PR that will increment all versions and generate the changelogs -- Review the updated `CHANGELOG` files and make any adjustments necessary, then merge the PR into the `release-*` branch - - `find packages -name 'CHANGELOG.md' -mindepth 2 -maxdepth 2 -exec code {} \;` -- Once the PR is merged, the release workflow will publish the updated packages to npm -- At this point, you can begin crafting the release notes for the eventual stable release in the root `CHANGELOG.md` file in the repo - - Copy the template for a new release and update the version numbers and links accordingly - - Copy the relevant changelog entries from all packages into the release notes and adjust accordingly - - Commit these changes directly to the `release-*` branch - they will not trigger a new prerelease since they do not include a changeset - -### Iterating a pre-release - -You may need to make changes to a pre-release prior to publishing a final stable release. To do so: - -- Make whatever changes you need -- Create a new changeset: `pnpm changeset` - - **IMPORTANT:** This is required even if you ultimately don't want to include these changes in the logs - - Remember, changelogs can be edited prior to publishing, but the Changeset version script needs to see new changesets in order to create a new version -- Commit the changesets and push the `release-*` branch to GitHub -- Wait for the release workflow to finish and the Changesets action to open its PR that will increment all versions -- Review the PR, make any adjustments necessary, and merge it into the `release-*` branch -- Once the PR is merged, the release workflow will publish the updated packages to npm -- Make sure you copy over the new changeset contents into stable release notes in the root `CHANGELOG.md` file in the repo - -### Publishing the stable release - -- Exit Changesets pre-release mode: `pnpm changeset pre exit` -- Commit the edited `pre.json` file along with any unpublished changesets, and push the `release-*` branch to GitHub -- Wait for the release workflow to finish - the Changesets action in the workflow will open a PR that will increment all versions and generate the changelogs for the stable release -- Review the updated `CHANGELOG` files and make any adjustments necessary - - `find packages -name 'CHANGELOG.md' -mindepth 2 -maxdepth 2 -exec code {} \;` - - Our automated release process should have removed prerelease entries -- Finalize the release notes - - This should already be in pretty good shape in the root `CHANGELOG.md` file in the repo - - Do a quick double check that all iterated prerelease changesets got copied over -- Merge the PR into the `release-*` branch -- Once the PR is merged, the release workflow will publish the updated packages to npm -- Once the release is published: - - Pull the latest `release-*` branch containing the PR you just merged - - Merge the `release-*` branch into `main` **using a non-fast-forward merge** and push it up to GitHub - - `git checkout main; git merge --no-ff release-next` - - Merge the `release-*` branch into `dev` **using a non-fast-forward merge** and push it up to GitHub - - `git checkout dev; git merge --no-ff release-next` - - Convert the `remix@1.x.y` tag to a Release on GitHub with the name `v2.x.y` and add a deep-link to the release heading in `CHANGELOG.md` - -### Hotfix releases - -Hotfix releases follow the same process as standard releases above, but the `release-*` branch should be branched off latest `main` instead of `dev`. Once the stable hotfix is published, the `release-*` branch should be merged back into both `main` and `dev` just like a normal release. - -### Experimental releases - -Experimental releases use a [manually-triggered Github Actions workflow](./.github/workflows/release-experimental.yml) and can be built from any existing branch. to build and publish an experimental release: - -- Commit your changes to a branch -- Push the branch to github -- Go to the Github Actions UI for the [release-experimental.yml workflow](https://github.com/remix-run/remix/actions/workflows/release-experimental-dispatch.yml) -- Click the `Run workflow` dropdown -- Leave the `Use workflow from` dropdown as `main` -- Enter your feature branch in the `branch` input -- Click the `Run workflow` button - -### Nightly releases - -Nightly releases happen automatically at midnight PST via a [cron-driven workflow](./.github/workflows/nightly.yml) that is essentially the same as the experimental releases, but also performs some validations after the release. - -## Local Development Tips and Tricks - -### Environment Variables - -This repository supports handful of environment variables to streamline the local development/testing process. - -**`REMIX_DEBUG`** - -By default, the Remix `rollup` build will strip any `console.debug` calls to avoid cluttering up the console during application usage. These `console.debug` statements can be preserved by setting `REMIX_DEBUG=true` during your local build. - -```sh -REMIX_DEBUG=true pnpm watch -``` - -**`LOCAL_BUILD_DIRECTORY`** - -When developing Remix locally, you often need to go beyond unit/integration tests and test your changes in a local Remix application. The easiest way to do this is to run your local Remix build and use this environment variable to direct `rollup` to write the output files directly into the local Remix application's `node_modules` folder. Then you just need to restart your local Remix application server to pick up the changes. - -```sh -# Tab 1 - create and run a local remix application -npx create-remix -cd my-remix-app -npm run dev - -# Tab 2 - remix repository -LOCAL_BUILD_DIRECTORY=../my-remix-app pnpm watch -``` - -Now - any time you make changes in the Remix repository, they will be written out to the appropriate locations in `../my-remix-app/node_modules` and you can restart the `npm run dev` command to pick them up 🎉. diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index bc04961fbca..00000000000 --- a/LICENSE.md +++ /dev/null @@ -1,22 +0,0 @@ -MIT License - -Copyright (c) Remix Software Inc. 2020-2021 -Copyright (c) Shopify Inc. 2022-2024 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index cf414220bf7..a6db1074c06 100644 --- a/README.md +++ b/README.md @@ -1,33 +1 @@ # Welcome to Remix! - -> [!IMPORTANT] -> With the release of [React Router v7](https://remix.run/blog/react-router-v7) we are sun-setting continued development/maintenance on Remix v2. If you have not already [upgraded to React Router v7](https://reactrouter.com/upgrading/remix), we recommend you do so. We've tried to make the upgrade process as smooth as possible with our [Future Flags](https://remix.run/docs/en/main/start/future-flags). -> -> We plan to continue to address bugs that pose security concerns or prevent upgrading to React Router v7. If you have a bug in one of those categories, please open an issue in this repository and prefix the title with `(v2):`. -> -> For all other issues, ongoing maintenance will be happening in React Router v7, so please open issues (bugs) and/or discussions (feature requests) [in that repo](https://github.com/remix-run/react-router/issues/new?template=bug_report.yml). - -We are happy you're here! - -[Remix](https://remix.run) is a full stack web framework that lets you focus on the user interface and work back through web fundamentals to deliver a fast, slick, and resilient user experience that deploys to any Node.js server and even non-Node.js environments at the edge like Cloudflare Workers. - -Want to know more? Read the [Technical Explanation of Remix](https://remix.run/discussion/introduction). - -This repository contains the Remix source code. This repo is a work in progress, so we appreciate your patience as we figure things out. - -## Documentation - -For documentation about Remix, please visit [our website](https://remix.run/docs). - -Also, please [join our community on Discord](https://rmx.as/discord). - -The documentation is automatically generated on each release from the files in -[the `docs` directory](docs). - -## Contributing - -If you're interested in contributing code and/or documentation, please see [our guide to contributing](https://remix.run/guides/contributing). - -## Code of Conduct - -Please see our [code of conduct](CODE_OF_CONDUCT.md) for any questions about the kind of community we are trying to build here and what to do if you need help with someone who is not acting professionally. diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index 6470112c8c4..00000000000 --- a/babel.config.js +++ /dev/null @@ -1,27 +0,0 @@ -module.exports = { - presets: [ - [ - "@babel/preset-env", - { - targets: { - node: "18", - }, - }, - ], - "@babel/preset-react", - "@babel/preset-typescript", - ], - plugins: [ - "@babel/plugin-proposal-export-namespace-from", - "@babel/plugin-proposal-optional-chaining", - // Strip console.debug calls unless REMIX_DEBUG=true - ...(process.env.REMIX_DEBUG === "true" - ? [] - : [ - [ - "transform-remove-console", - { exclude: ["error", "warn", "log", "info"] }, - ], - ]), - ], -}; diff --git a/contributors.yml b/contributors.yml deleted file mode 100644 index 4a62d393672..00000000000 --- a/contributors.yml +++ /dev/null @@ -1,744 +0,0 @@ -- aaronadamsCA -- aaronpowell96 -- aaronshaf -- AbePlays -- abereghici -- abotsi -- accidentaldeveloper -- achinchen -- acusti -- adamwathan -- adicuco -- AdiRishi -- ahabhgk -- ahbruns -- AhmadMayo -- ahmedeldessouki -- ahuth -- aiji42 -- ainoya -- airjp73 -- airondumael -- aissa-bouguern -- ajtorres9 -- akamfoad -- alanhoskins -- Alarid -- alcpereira -- AlemTuzlak -- alex-ketch -- alexanderson1993 -- alexmgrant -- alextes -- alexuxui -- alireza-bonab -- alisd23 -- ally1002 -- alongdate -- AltanS -- alvinthen -- amanape -- amir-ziaei -- amorriscode -- andreiduca -- andrelandgraf -- AndreSilva1993 -- andrewbrey -- AndrewIngram -- anishpras -- anmolm96 -- anmonteiro -- AntoninBeaufort -- anubra266 -- apeltop -- appden -- Aprillion -- Ar1f007 -- arange -- archwebio -- arekmaz -- arganaphangquestian -- arifqys -- AriGunawan -- arjunyel -- armandabric -- arnaudambro -- arvigeus -- arvindell -- ascorbic -- ashleyryan -- ashocean -- asmadsen -- atesgoral -- athongsavath -- AustinGil -- avindra -- awthwathje -- axel-habermaier -- baby230211 -- barclayd -- BasixKOR -- beatinaniwa -- BenMcH -- benwis -- bgschiller -- binajmen -- bmac -- bmarvinb -- bmontalvo -- bobziroll -- bogas04 -- BogdanDevBst -- bolchowka -- bravo-kernel -- brenr -- brettscott -- brookslybrand -- brophdawg11 -- bruno-oliveira -- bsharrow -- bsides -- bustamantedev -- buzinas -- c43721 -- camiaei -- CanRau -- ccssmnn -- cephalization -- chaance -- chaukhoa97 -- chenc041 -- chenxsan -- chiangs -- chimame -- chipit24 -- chohner -- christianhg -- christophertrudel -- christophgockel -- clarkmitchell -- cliffordfajardo -- cloudy9101 -- cmd-johnson -- codymjarrett -- colinasquith -- colinhacks -- confix -- coryhouse -- courey -- courtyenn -- craigayre -- craigglennie -- crismali -- CSFlorin -- cysp -- cythrawll -- d4vsanchez -- dabdine -- daganomri -- damiensedgwick -- dan-gamble -- danielfgray -- danielshamburger -- danielweinmann -- dario-piotrowicz -- davecalnan -- davecranwell-vocovo -- david-crespo -- DavidHollins6 -- davongit -- dcramer -- Deanmv -- defjosiah -- denissb -- depsimon -- derekr -- derenge -- devbytyler -- devcamke -- developit -- devongovett -- dg1234uk -- dgurns -- dhargitai -- dhmacs -- dima-takoy -- dj-rabel -- dmarkow -- dmillar -- DNLHC -- dnsbty -- dogukanakkaya -- dokeet -- domluther -- donavon -- Drew-Daniels -- dschlabach -- Dueen -- dunglas -- dvargas92495 -- dwightwatson -- dwjohnston -- dwt47 -- dylanplayer -- eastlondoner -- eccentric-j -- EddyVinck -- edgesoft -- edmundhung -- edzis -- eeershov -- efkann -- eldarshamukhamedov -- eltociear -- emilbryggare -- emzoumpo -- enbonnet -- eps1lon -- eric-burel -- ericchernuka -- esamattis -- evanwinter -- everdimension -- exegeteio -- ezekeal -- F3n67u -- FAL-coffee -- fayez-nazzal -- fede -- federicoestevez -- feelixe -- fergusmeiklejohn -- fernandocanizo -- fernandojbf -- fgiuliani -- fifi98 -- fishel-feng -- francisudeji -- frandiox -- fredericoo -- freeman -- frontsideair -- furkanakkurt1335 -- fwang -- fx109138 -- gabimor -- garand -- gautamkrishnar -- gavriguy -- ghaagsma -- Gideon28 -- Gim3l -- Girish21 -- gkueny -- gmaliar -- gon250 -- goncy -- gonzoscript -- gotgenes -- GOWxx -- graham42 -- greg-hoarau -- GregBrimble -- GSt4r -- guatedude2 -- guerra08 -- gunners6518 -- gustavoguichard -- gustavopch -- gyx1000 -- hadimalikdev -- hadizz -- haines -- hardingmatt -- harmony7 -- harshmangalam -- helderburato -- HenryPereira -- HenryVogt -- hi-ogawa -- hicksy -- himorishige -- Hirochon -- hjonasson -- hkan -- hokaccha -- Holben888 -- hollandThomas -- Hopsken -- houmark -- hpnzm -- humphd -- huw -- huyb1991 -- hzhu -- IAmLuisJ -- iamzee -- ianduvall -- IgnusG -- ikarus-akhil -- illright -- imzivko -- imzshh -- infomiho -- ionut-botizan -- irsooti -- isaacrmoreno -- ishan-me -- IshanKBG -- itsMapleLeaf -- izznatsir -- jacargentina -- jack-r-warren -- jackhkmatthews -- jacob-ebey -- JacobParis -- jacobwgillespie -- jakeginnivan -- jakewtaylor -- james0r -- jamiebuilds -- janhoogeveen -- Jannis-Morgenstern -- jasonadelia -- jawkha -- jaydiablo -- jca41 -- jdeniau -- jeeyoungk -- JeffBeltran -- jenseng -- jeremyjfleming -- jeremylumanbailey -- jesse-deboer -- jesseflorig -- JesseKuntz -- jgarrow -- jiahao-c -- jimniels -- jinglesthula -- jkjustjoshing -- jkup -- jly36963 -- jmarbutt -- jmasson -- jmorel88 -- JNaftali -- jo-ninja -- joaosamouco -- jodygeraldo -- joelazar -- johannesbraeunig -- johnmberger -- johnpolacek -- johnson444 -- joms -- joonmo-you -- joshball -- JoshuaKGoldberg -- jplhomer -- jrf0110 -- jrubins -- jsbmg -- jsgv -- jsparkdev -- jssisodiya -- jstafman -- juhanakristian -- JulesBlm -- juliaqiuxy -- julienmonnard -- justinnoel -- justinsalasdev -- justinwaite -- justsml -- juwiragiye -- jveldridge -- jvnm-dev -- jwaltz -- jwnx -- kalch -- kamtugeza -- kandros -- kanermichael -- KarelVerschraegen -- karimsan -- KarllosSouza -- kauffmanes -- kayac-chang -- kbariotis -- KenanYusuf -- kentcdodds -- kevinrambaud -- kevlened -- kgregory -- kiancross -- kilian -- kiliman -- kimdontdoit -- KingSora -- kisaragi-hiu -- kishanhitk -- kiyadotdev -- klauspaiva -- klirium -- knisterpeter -- knowler -- konradkalemba -- krolebord -- krystof-k -- ksjogo -- kt3k -- kubaprzetakiewicz -- kuldar -- kumard3 -- lachlanjc -- larister -- lasseklovstad -- laughnan -- lawrencecchen -- ledniy -- leifarriens -- lensbart -- leo -- leon -- leothorp -- leovander -- leoweigand -- levippaul -- LewisArdern -- lfantone -- lifeiscontent -- lili21 -- lionotm -- liranm -- lkwr -- lordofthecactus -- lpsinger -- lswest -- lucasdibz -- lucasferreira -- luispagarcia -- luisrivas -- luistak -- luistorres -- luk-str -- lukahartwig -- lukasgerm -- LukeAskew -- lukeshiru -- m0nica -- m5r -- machour -- macklinu -- maferland -- manan30 -- manosim -- mantey-github -- manzano78 -- manzoorwanijk -- marbemac -- marceltn -- marcisbee -- marcomafessolli -- markdalgleish -- marshallwalker -- martensonbj -- marvinwu -- masious -- matchai -- mathieusteele -- matt-l-w -- mattcroat -- matthew-burfield -- Matthew-Mallimo -- MatthewAlbrecht -- matthova -- Mattinton -- mattkindy -- mattmazzola -- mattpocock -- mattstobbs -- maxprilutskiy -- maxrchung -- maxschwarzmueller -- mbarto -- mbuchoff -- mcansh -- mccuna -- mdoury -- medayz -- meetbryce -- mehulmpt -- memark -- mennopruijssers -- mic-sob -- michaeldebetaz -- michaeldeboey -- michaelfriedman -- michaelgmcd -- michaelhelvey -- michaseel -- michenly -- mikechabot -- mikeybinnswebdesign -- mirzafaizan -- mischah -- mitchelldirt -- mjackson -- mjangir -- mkrtchian -- mlane -- mochi-sann -- mohammadhosseinbagheri -- monitaure -- monsterdeveloper -- mootari -- morinokami -- mrkhosravian -- mrkstwrt -- mrm007 -- mskoroglu -- msutkowski -- mthenw -- mtt87 -- muhammadjalabi -- mush159 -- mustak -- n8agrin -- na2hiro -- nareshbhatia -- nathggns -- nauvalazhar -- naveed-fida -- navid-kalaei -- nexxeln -- ngbrown -- ngtrthinh169TPC -- ni554n -- nicholaschiang -- nickprinsloo -- NickRetallack -- nicksrandall -- nicksrandall -- nickytonline -- niconiahi -- nielsdb97 -- NikkiDelRosso -- ninjaPixel -- niwsa -- nobeeakon -- nordiauwu -- nornagon -- not-ivy -- npapagna -- nrako -- nurul3101 -- nvh95 -- nwalters512 -- octokatherine -- omamazainab -- oott123 -- orballo -- oscarnewman -- outofgamut -- ovi-ispas -- pacexy -- pandaiolo -- panteliselef -- pawelblaszczyk5 -- pcattori -- penspinner -- penx -- petetnt -- petrpacas -- philandstuff -- phishy -- plastic041 -- plondon -- pmbanugo -- Pouet-- -- prasook-jain -- pratikdevdas -- princerajroy -- prvnbist -- ptitFicus -- pwbriggs -- pyr0gan -- rachaelmcq -- ramiroazar -- RATIU5 -- raulfdm -- raulrpearson -- real34 -- realjokele -- redabacha -- reggie3 -- reichhartd -- remix-run-bot -- rhryansu -- richardhunghhw -- riencoertjens -- risv1 -- rkulinski -- rlfarman -- roachjc -- robbtraister -- robindrost -- roddds -- rogepi -- roj1512 -- RomanSavarin -- ronnylt -- rossipedia -- RossJHagan -- RossMcMillan92 -- roughee -- rowinbot -- rphlmr -- rtabulov -- ruisaraiva19 -- runmoore -- Runner-dev -- runofthemill -- rvlewerissa -- ryanflorence -- ryanjames1729 -- ryankshaw -- sambostock -- sandstone991 -- sandulat -- sarahse -- sathvik-k -- sbernheim4 -- schpet -- scott-erickson -- ScottDalessandro -- scottybrown -- sdavids -- sean-roberts -- SeanGroff -- SeanRoberts -- sebastien-comeau -- sebz -- selfish -- sergiocarneiro -- sergiodxa -- shairez -- shamsup -- shashankboosi -- shininglovestar -- shubhaguha -- shumuu -- sidkh -- sidv1905 -- signed -- silvenon -- simonepizzamiglio -- simonswiss -- sinhalite -- sitek94 -- sjparsons -- skube -- smathson -- smeijer -- sndrem -- soartec-lab -- sobrinho -- souredoutlook -- squidpunch -- staticWagomU -- staylor -- stephanerangaya -- stephenwade -- strackfeldt -- SufianBabri -- supachaidev -- syeef -- Synvox -- t-dub -- tagraves -- takagimeow -- tanerijun -- tascord -- TheRealAstoo -- therealflyingcoder -- thomasheyenbrock -- thomasrettig -- thomasverleye -- threepointone -- timkraut -- TimonVS -- tjefferson08 -- tmcw -- Tobbe -- tombiju -- tombohub -- tombyrer -- tomer-yechiel -- TomerAberbach -- tometo-dev -- TomVance -- TooTallNate -- toufiqnuur -- toyozaki -- TrySound -- Tsukina-7mochi -- ttsirkia -- turkerdev -- tvanantwerp -- twhitbeck -- tylerbrostrom -- udasitharani -- udohjeremiah -- uerkw -- uhoh-itsmaciek -- unhackit -- UsamaHameed -- valbaca -- ValentinH -- valerie-makes -- veritem -- VHall1 -- VictorPeralta -- vimutti77 -- vincecao -- visormatt -- viveleroi -- vkrol -- vlindhol -- vm -- vmosyaykin -- vorcigernix -- wahyubucil -- wangbinyq -- weavdale -- wilcoschoneveld -- willhack -- willin -- willowcheng -- willsmithte -- wizardlyhel -- wKovacs64 -- wladiston -- wtlin1228 -- wxh06 -- xanderberkein -- xdivby0 -- xHomu -- XiNiHa -- xstevenyung -- yasoob -- yauri-io -- yesmeck -- yomeshgupta -- yoshimatsu567 -- youbicode -- youngvform -- yudai-nkt -- yusuke99 -- zachdtaylor -- zainfathoni -- zayenz -- zhe -- zwhitchcox diff --git a/decisions/0001-use-npm-to-manage-npm-dependencies-for-deno-projects.md b/decisions/0001-use-npm-to-manage-npm-dependencies-for-deno-projects.md deleted file mode 100644 index 35a6ec0a363..00000000000 --- a/decisions/0001-use-npm-to-manage-npm-dependencies-for-deno-projects.md +++ /dev/null @@ -1,113 +0,0 @@ -# Use `npm` to manage NPM dependencies for Deno projects - -Date: 2022-05-10 - -Status: accepted - -## Context - -Deno has three ways to manage dependencies: - -1. Inlined URL imports: `import {...} from "https://deno.land/x/blah"` -2. [deps.ts](https://deno.land/manual/examples/manage_dependencies) -3. [Import maps](https://deno.land/manual/linking_to_external_code/import_maps) - -Additionally, NPM packages can be accessed as Deno modules via [Deno-friendly CDNs](https://deno.land/manual/node/cdns#deno-friendly-cdns) like https://esm.sh. - -Remix has some requirements around dependencies: - -- Remix treeshakes dependencies that are free of side-effects. -- Remix sets the environment (dev/prod/test) across all code, including dependencies, at runtime via the `NODE_ENV` environment variable. -- Remix depends on some NPM packages that should be specified as peer dependencies (notably, `react` and `react-dom`). - -### Treeshaking - -To optimize bundle size, Remix [treeshakes](https://esbuild.github.io/api/#tree-shaking) your app's code and dependencies. -This also helps to separate browser code and server code. - -Under the hood, the Remix compiler uses [esbuild](https://esbuild.github.io). -Like other bundlers, `esbuild` uses [`sideEffects` in `package.json` to determine when it is safe to eliminate unused imports](https://esbuild.github.io/api/#conditionally-injecting-a-file). - -Unfortunately, URL imports do not have a standard mechanism for marking packages as side-effect free. - -### Setting dev/prod/test environment - -Deno-friendly CDNs set the environment via a query parameter (e.g. `?dev`), not via an environment variable. -That means changing environment requires changing the URL import in the source code. -While you could use multiple import maps (`dev.json`, `prod.json`, etc...) to workaround this, import maps have other limitations: - -- standard tooling for managing import maps is not available -- import maps are not composeable, so any dependencies that use import maps must be manually accounted for - -### Specifying peer dependencies - -Even if import maps were perfected, CDNs compile each dependency in isolation. -That means that specifying peer dependencies becomes tedious and error-prone as the user needs to: - -- determine which dependencies themselves depend on `react` (or other similar peer dependency), even if indirectly. -- manually figure out which `react` version works across _all_ of these dependencies -- set that version for `react` as a query parameter in _all_ of the URLs for the identified dependencies - -If any dependencies change (added, removed, version change), -the user must repeat all of these steps again. - -## Decision - -### Use `npm` to manage NPM dependencies for Deno - -Do not use Deno-friendly CDNs for NPM dependencies in Remix projects using Deno. - -Use `npm` and `node_modules/` to manage NPM dependencies like `react` for Remix projects, even when using Deno with Remix. - -Deno module dependencies (e.g. from `https://deno.land`) can still be managed via URL imports. - -### Allow URL imports - -Remix will preserve any URL imports in the built bundles as external dependencies, -letting your browser runtime and server runtime handle them accordingly. -That means that you may: - -- use URL imports for the browser -- use URL imports for the server, if your server runtime supports it - -For example, Node will throw errors for URL imports, while Deno will resolve URL imports as normal. - -### Do not support import maps - -Remix will not yet support import maps. - -## Consequences - -- URL imports will not be treeshaken. -- Users can specify environment via the `NODE_ENV` environment variable at runtime. -- Users won't have to do error-prone, manual dependency resolution. - -### VS Code type hints - -Users may configure an import map for the [Deno extension for VS Code](denoland.vscode-deno) to enable type hints for NPM-managed dependencies within their Deno editor: - -`.vscode/resolve_npm_imports_in_deno.json` - -```json -{ - "// This import map is used solely for the denoland.vscode-deno extension.": "", - "// Remix does not support import maps.": "", - "// Dependency management is done through `npm` and `node_modules/` instead.": "", - "// Deno-only dependencies may be imported via URL imports (without using import maps).": "", - - "imports": { - "react": "https://esm.sh/react@18.0.0", - "react-dom": "https://esm.sh/react-dom@18.0.0", - "react-dom/server": "https://esm.sh/react-dom@18.0.0/server" - } -} -``` - -`.vscode/settings.json` - -```json -{ - "deno.enable": true, - "deno.importMap": "./.vscode/resolve_npm_imports_in_deno.json" -} -``` diff --git a/decisions/0002-do-not-clone-request.md b/decisions/0002-do-not-clone-request.md deleted file mode 100644 index 30f599f7f0f..00000000000 --- a/decisions/0002-do-not-clone-request.md +++ /dev/null @@ -1,19 +0,0 @@ -# Do not clone request - -Date: 2022-05-13 - -Status: accepted - -## Context - -To allow multiple loaders / actions to read the body of a request, we have been cloning the request before forwarding it to user-code. This is not the best thing to do as some runtimes will begin buffering the body to allow for multiple consumers. It also goes against "the platform" that states a request body should only be consumed once. - -## Decision - -Do not clone requests before they are passed to user-code (actions, handleDocumentRequest, handleDataRequest), and remove body from request passed to loaders. Loaders should be thought of as a "GET" / "HEAD" request handler. These request methods are not allowed to have a body, therefore you should not be reading it in your Remix loader function. - -## Consequences - -Loaders always receive a null body for the request. - -If you are reading the request body in both an action and handleDocumentRequest or handleDataRequest this will now fail as the body will have already been read. If you wish to continue reading the request body in multiple places for a single request against recommendations, consider using `.clone()` before reading it; just know this comes with tradeoffs. diff --git a/decisions/0003-infer-types-for-useloaderdata-and-useactiondata-from-loader-and-action-via-generics.md b/decisions/0003-infer-types-for-useloaderdata-and-useactiondata-from-loader-and-action-via-generics.md deleted file mode 100644 index 1959f161835..00000000000 --- a/decisions/0003-infer-types-for-useloaderdata-and-useactiondata-from-loader-and-action-via-generics.md +++ /dev/null @@ -1,230 +0,0 @@ -# Infer types for `useLoaderData` and `useActionData` from `loader` and `action` via generics - -Date: 2022-07-11 - -Status: accepted - -## Context - -Goal: End-to-end type safety for `useLoaderData` and `useActionData` with great Developer Experience (DX) - -Related discussions: - -- [remix-run/remix#1254](https://github.com/remix-run/remix/pull/1254) -- [remix-run/remix#3276](https://github.com/remix-run/remix/pull/3276) - ---- - -In Remix v1.6.4, types for both `useLoaderData` and `useActionData` are parameterized with a generic: - -```tsx -type MyLoaderData = { - /* ... */ -}; -type MyActionData = { - /* ... */ -}; - -export default function Route() { - const loaderData = useLoaderData(); - const actionData = useActionData(); - return
{/* ... */}
; -} -``` - -For end-to-end type safety, it is then the user's responsability to make sure that `loader` and `action` also use the same type in the `json` generic: - -```ts -export const loader: LoaderFunction = () => { - return json({ - /* ... */ - }); -}; - -export const action: ActionFunction = () => { - return json({ - /* ... */ - }); -}; -``` - -### Diving into `useLoaderData`'s and `useActionData`'s generics - -Tracing through the `@remix-run/react` source code (v1.6.4), you'll find that `useLoaderData` returns an `any` type that is implicitly type cast to whatever type gets passed into the `useLoaderData` generic: - -```ts -// https://github.com/remix-run/remix/blob/v1.6.4/packages/remix-react/components.tsx#L1370 -export function useLoaderData(): T { - return useRemixRouteContext().data; // -} - -// https://github.com/remix-run/remix/blob/v1.6.4/packages/remix-react/components.tsx#L73 -function useRemixRouteContext(): RemixRouteContextType { - /* ... */ -} - -// https://github.com/remix-run/remix/blob/v1.6.4/packages/remix-react/components.tsx#L56 -interface RemixRouteContextType { - data: AppData; - id: string; -} - -// https://github.com/remix-run/remix/blob/v1.6.4/packages/remix-react/data.ts#L4 -export type AppData = any; -``` - -Boiling this down, the code looks like: - -```ts -let data: any; - -// somewhere else, `loader` gets called an sets `data` to some value - -function useLoaderData(): T { - return data; // <-- Typescript casts this `any` to `T` -} -``` - -`useLoaderData` isn't basing its return type on how `data` was set (i.e. the return value of `loader`) nor is it validating the data. -It's just blindly casting `data` to whatever the user passed in for the generic `T`. - -### Issues with current approach - -The developer experience is subpar. -Users are required to write redundant code for the data types that could have been inferred from the arguments to `json`. -Changes to the data shape require changing _both_ the declared `type` or `interface` as well as the argument to `json`. - -Additionally, the current approach encourages users to pass the same type to `json` with the `loader` and to `useLoaderData`, but **this is a footgun**! -`json` can accept data types like `Date` that are JSON serializable, but `useLoaderData` will return the _serialized_ type: - -```ts -type MyLoaderData = { - birthday: Date; -}; - -export const loader: LoaderFunction = () => { - return json({ birthday: new Date("February 15, 1992") }); -}; - -export default function Route() { - const { birthday } = useLoaderData(); - // ^ `useLoaderData` tricks Typescript into thinking this is a `Date`, when in fact its a `string`! -} -``` - -Again, the same goes for `useActionData`. - -### Solution criteria - -- Return type of `useLoaderData` and `useActionData` should somehow be inferred from `loader` and `action`, not blindly type cast -- Return type of `loader` and `action` should be inferred - - Necessarily, return type of `json` should be inferred from its input -- No module side-effects (so higher-order functions like `makeLoader` is definitely a no). -- `json` should allow everything that `JSON.stringify` allows. -- `json` should allow only what `JSON.stringify` allows. -- `useLoaderData` should not return anything that `JSON.parse` can't return. - -### Key insight: `loader` and `action` are an _implicit_ inputs - -While there's been interest in inferring the types for `useLoaderData` based on `loader`, there was [hesitance to use a Typescript generic to do so](https://github.com/remix-run/remix/pull/3276#issuecomment-1164764821). -Typescript generics are apt for specifying or inferring types for _inputs_, not for blindly type casting output types. - -A key factor in the decision was identifying that `loader` and `action` are _implicit_ inputs of `useLoaderData` and `useActionData`. - -In other words, if `loader` and `useLoaderData` were guaranteed to run in the same process (and not cross the network), then we could write `useLoaderData(loader)`, specifying `loader` as an explicit input for `useLoaderData`. - -```ts -// _conceptually_ `loader` is an input for `useLoaderData` -function useLoaderData(loader: Loader) { - /*...*/ -} -``` - -Though `loader` and `useLoaderData` exist together in the same file at development-time, `loader` does not exist at runtime in the browser. -Without the `loader` argument to infer types from, `useLoaderData` needs a way to learn about `loader`'s type at compile-time. - -Additionally, `loader` and `useLoaderData` are both managed by Remix across the network. -While its true that Remix doesn't "own" the network in the strictest sense, having `useLoaderData` return data that does not correspond to its `loader` is an exceedingly rare edge-case. - -Same goes for `useActionData`. - ---- - -A similar case is how [Prisma](https://www.prisma.io/) infers types from database schemas available at runtime, even though there are (exceedingly rare) edge-cases where that database schema _could_ be mutated after compile-time but before run-time. - -## Decision - -Explicitly provide type of the implicit `loader` input for `useLoaderData` and then infer the return type for `useLoaderData`. -Do the same for `action` and `useActionData`. - -```ts -export const loader = async (args: LoaderArgs) => { - // ... - return json(/*...*/); -}; - -export default function Route() { - const data = useLoaderData(); - // ... -} -``` - -Additionally, the inferred return type for `useLoaderData` will only include serializable (JSON) types. - -### Return `unknown` when generic is omitted - -Omitting the generic for `useLoaderData` or `useActionData` results in `any` being returned. -This hides potential type errors from the user. -Instead, we'll change the return type to `unknown`. - -```ts -type MyLoaderData = { - /*...*/ -}; - -export default function Route() { - const data = useLoaderData(); - // ^? unknown -} -``` - -Note: Since this would be a breaking change, changing the return type to `unknown` will be slated for v2. - -### Deprecate non-inferred types via generics - -Passing in a non-inferred type for `useLoaderData` is hiding an unsafe type cast. -Using the `useLoaderData` in this way will be deprecated in favor of an explicit type cast that clearly communicates the assumptions being made: - -```ts -type MyLoaderData = { - /*...*/ -}; - -export default function Route() { - const dataGeneric = useLoaderData(); // <-- will be deprecated - const dataCast = useLoaderData() as MyLoaderData; // <- use this instead -} -``` - -## Consequences - -- Users can continue to provide non-inferred types by type casting the result of `useLoaderData` or `useActionData` -- Users can opt-in to inferred types by using `typeof loader` or `typeof action` at the generic for `useLoaderData` or `useActionData`. -- Return types for `loader` and `action` will be the sources-of-truth for the types inferred for `useLoaderData` and `useActionData`. -- Users do not need to write redundant code to align types across the network -- Return type of `useLoaderData` and `useActionData` will correspond to the JSON _serialized_ types from `json` calls in `loader` and `action`, eliminating a class of errors. -- `LoaderFunction` and `ActionFunction` should not be used when opting into type inference as they override the inferred return types.[^1] - -🚨 Users who opt-in to inferred types **MUST** return a `TypedResponse` from `json` and **MUST NOT** return a bare object: - -```ts -const loader = () => { - // NO - return { hello: "world" }; - - // YES - return json({ hello: "world" }); -}; -``` - -[^1]: The proposed `satisfies` operator for Typescript would let `LoaderFunction` and `ActionFunction` enforce function types while preserving the narrower inferred return type: https://github.com/microsoft/TypeScript/issues/47920 diff --git a/decisions/0004-streaming-apis.md b/decisions/0004-streaming-apis.md deleted file mode 100644 index 5677a48e362..00000000000 --- a/decisions/0004-streaming-apis.md +++ /dev/null @@ -1,193 +0,0 @@ ---- -title: Remix (and React Router) Streaming APIs ---- - -# Title - -Date: 2022-07-27 - -Status: accepted - -## Context - -Remix aims to provide first-class support for React 18's streaming capabilities. Throughout the development process we went through many iterations and naming schemes around the APIs we plan to build into Remix to support streaming, so this document aims to lay out the final names we chose and the reasons behind it. - -It's also worth nothing that even in a single-page-application without SSR-streaming, the same concepts still apply so these decisions were made with React Router 6.4.0 in mind as well - which will support the same Data APIs from Remix. - -## Decision - -Streaming in Remix can be thought of as having 3 touch points with corresponding APIs: - -1. _Initiating_ a streamed response in your `loader` can be done by returning a `defer(object)` call from your `loader` in which some of the keys on `object` are `Promise` instances -2. _Accessing_ a streamed response from `useLoaderData` - 1. No new APIs here - when you return a `defer()` response from your loader, you'll get `Promise` values inside your `useLoaderData` object 👌 -3. _Rendering_ a streamed value (with fallback and error handling) in your component - 1. You can render a `Promise` from `useLoaderData()` with the `` component - 2. `` accepts an `errorElement` prop to handle error UI - 3. `` should be wrapped with a `` component to handle your loading UI - -## Details - -In the spirit of `#useThePlatform` we've chosen to leverage the `Promise` API to represent these "eventually available" values. When Remix receives a `defer()` response back from a `loader`, it needs to serialize that `Promise` over the network to the client application (prompting Jacob to coin the phrase [_"promise teleportation over the network"_][promise teleportation] 🔥). - -### Initiating - -In order to initiate a streamed response in your `loader`, you can use the `defer()` utility which accepts a JSON object with `Promise` values from your `loader`. - -```tsx -export async function loader() { - return defer({ - // Await this, don't stream - critical: await fetchCriticalData(), - // Don't await this - stream it! - lazy: fetchLazyData(), - }); -} -``` - -By not using `await` on `fetchLazyData()` Remix knows that this value is not ready yet _but eventually will be_ and therefore Remix will leverage a streamed HTTP response allowing it to send up the resolved/rejected value when available. Essentially serializing/teleporting that Promise over the network via a streamed HTTP response. - -Just like `json()`, the `defer()` will accept a second optional `responseInit` param that lets you customize the resulting `Response` (i.e., in case you need to set custom headers). - -The name `defer` was settled on as a corollary to `" }; - expect(escapeHtml(JSON.stringify(evilObj))).toBe( - '{"evil":"\\u003cscript\\u003e\\u003c/script\\u003e"}' - ); - }); - - test("with angle brackets should parse back", () => { - let evilObj = { evil: "" }; - expect(JSON.parse(escapeHtml(JSON.stringify(evilObj)))).toMatchObject( - evilObj - ); - }); - - test("with ampersands should escape", () => { - let evilObj = { evil: "&" }; - expect(escapeHtml(JSON.stringify(evilObj))).toBe('{"evil":"\\u0026"}'); - }); - - test("with ampersands should parse back", () => { - let evilObj = { evil: "&" }; - expect(JSON.parse(escapeHtml(JSON.stringify(evilObj)))).toMatchObject( - evilObj - ); - }); - - test('with "LINE SEPARATOR" and "PARAGRAPH SEPARATOR" should escape', () => { - let evilObj = { evil: "\u2028\u2029" }; - expect(escapeHtml(JSON.stringify(evilObj))).toBe( - '{"evil":"\\u2028\\u2029"}' - ); - }); - - test('with "LINE SEPARATOR" and "PARAGRAPH SEPARATOR" should parse back', () => { - let evilObj = { evil: "\u2028\u2029" }; - expect(JSON.parse(escapeHtml(JSON.stringify(evilObj)))).toMatchObject( - evilObj - ); - }); - - test("escaped line terminators should work", () => { - expect(() => { - vm.runInNewContext( - "(" + escapeHtml(JSON.stringify({ evil: "\u2028\u2029" })) + ")" - ); - }).not.toThrow(); - }); -}); diff --git a/packages/remix-server-runtime/__tests__/responses-test.ts b/packages/remix-server-runtime/__tests__/responses-test.ts deleted file mode 100644 index 0506d28c965..00000000000 --- a/packages/remix-server-runtime/__tests__/responses-test.ts +++ /dev/null @@ -1,96 +0,0 @@ -import type { TypedResponse } from "../index"; -import { json, redirect } from "../index"; -import { isEqual } from "./utils"; - -describe("json", () => { - it("sets the Content-Type header", () => { - let response = json({}); - expect(response.headers.get("Content-Type")).toEqual( - "application/json; charset=utf-8" - ); - }); - - it("preserves existing headers, including Content-Type", () => { - let response = json( - {}, - { - headers: { - "Content-Type": "application/json; charset=iso-8859-1", - "X-Remix": "is awesome", - }, - } - ); - - expect(response.headers.get("Content-Type")).toEqual( - "application/json; charset=iso-8859-1" - ); - expect(response.headers.get("X-Remix")).toEqual("is awesome"); - }); - - it("encodes the response body", async () => { - let response = json({ hello: "remix" }); - expect(await response.json()).toEqual({ hello: "remix" }); - }); - - it("accepts status as a second parameter", () => { - let response = json({}, 201); - expect(response.status).toEqual(201); - }); - - it("infers input type", async () => { - let response = json({ hello: "remix" }); - isEqual>(true); - let result = await response.json(); - expect(result).toMatchObject({ hello: "remix" }); - }); - - it("disallows unmatched typed responses", async () => { - let response = json("hello"); - isEqual, typeof response>(false); - }); - - it("disallows unserializables", () => { - // @ts-expect-error - expect(() => json(124n)).toThrow(); - // @ts-expect-error - expect(() => json({ field: 124n })).toThrow(); - }); -}); - -describe("redirect", () => { - it("sets the status to 302 by default", () => { - let response = redirect("/login"); - expect(response.status).toEqual(302); - }); - - it("sets the status to 302 when only headers are given", () => { - let response = redirect("/login", { - headers: { - "X-Remix": "is awesome", - }, - }); - expect(response.status).toEqual(302); - }); - - it("sets the Location header", () => { - let response = redirect("/login"); - expect(response.headers.get("Location")).toEqual("/login"); - }); - - it("preserves existing headers, but not Location", () => { - let response = redirect("/login", { - headers: { - Location: "/", - "X-Remix": "is awesome", - }, - }); - - expect(response.headers.get("Location")).toEqual("/login"); - expect(response.headers.get("X-Remix")).toEqual("is awesome"); - }); - - it("accepts status as a second parameter", () => { - let response = redirect("/profile", 301); - expect(response.status).toEqual(301); - }); -}); diff --git a/packages/remix-server-runtime/__tests__/serialize-test.ts b/packages/remix-server-runtime/__tests__/serialize-test.ts deleted file mode 100644 index 7b5a38b35d1..00000000000 --- a/packages/remix-server-runtime/__tests__/serialize-test.ts +++ /dev/null @@ -1,54 +0,0 @@ -import type { SerializeFrom } from "../index"; -import { defer, json } from "../index"; -import { isEqual } from "./utils"; - -it("infers basic types", () => { - isEqual< - SerializeFrom<{ - hello?: string; - count: number | undefined; - date: Date | number; - isActive: boolean; - items: { name: string; price: number; orderedAt: Date }[]; - }>, - { - hello?: string; - count?: number; - date: string | number; - isActive: boolean; - items: { name: string; price: number; orderedAt: string }[]; - } - >(true); -}); - -it("infers deferred types", () => { - let get = (): Promise | undefined => { - if (Math.random() > 0.5) return Promise.resolve(new Date()); - return undefined; - }; - let loader = async () => - defer({ - critical: await Promise.resolve("hello"), - deferred: get(), - }); - isEqual< - SerializeFrom, - { - critical: string; - deferred: Promise | undefined; - } - >(true); -}); - -it("infers types from json", () => { - let loader = () => json({ data: "remix" }); - isEqual, { data: string }>(true); - - let asyncLoader = async () => json({ data: "remix" }); - isEqual, { data: string }>(true); -}); - -it("infers type from defer", () => { - let loader = async () => defer({ data: "remix" }); - isEqual, { data: string }>(true); -}); diff --git a/packages/remix-server-runtime/__tests__/server-test.ts b/packages/remix-server-runtime/__tests__/server-test.ts deleted file mode 100644 index eed236c1259..00000000000 --- a/packages/remix-server-runtime/__tests__/server-test.ts +++ /dev/null @@ -1,2334 +0,0 @@ -import type { StaticHandlerContext } from "@remix-run/router"; - -import { createRequestHandler } from ".."; -import { ServerMode } from "../mode"; -import type { ServerBuild } from "../build"; -import { mockServerBuild } from "./utils"; - -function spyConsole() { - // https://github.com/facebook/react/issues/7047 - let spy: any = {}; - - beforeAll(() => { - spy.console = jest.spyOn(console, "error").mockImplementation(() => {}); - }); - - afterAll(() => { - spy.console.mockRestore(); - }); - - return spy; -} - -describe("server", () => { - let routeId = "root"; - let build: ServerBuild = { - entry: { - module: { - default: async (request) => { - return new Response(`${request.method}, ${request.url} COMPONENT`); - }, - }, - }, - routes: { - [routeId]: { - id: routeId, - path: "", - module: { - action: ({ request }) => - new Response(`${request.method} ${request.url} ACTION`), - loader: ({ request }) => - new Response(`${request.method} ${request.url} LOADER`), - default: () => "COMPONENT", - }, - }, - }, - assets: { - routes: { - [routeId]: { - hasAction: true, - hasErrorBoundary: false, - hasLoader: true, - id: routeId, - module: routeId, - path: "", - }, - }, - }, - future: {}, - } as unknown as ServerBuild; - - describe("createRequestHandler", () => { - let spy = spyConsole(); - - beforeEach(() => { - spy.console.mockClear(); - }); - - let allowThrough = [ - ["GET", "/"], - ["GET", "/?_data=root"], - ["POST", "/"], - ["POST", "/?_data=root"], - ["PUT", "/"], - ["PUT", "/?_data=root"], - ["DELETE", "/"], - ["DELETE", "/?_data=root"], - ["PATCH", "/"], - ["PATCH", "/?_data=root"], - ]; - it.each(allowThrough)( - `allows through %s request to %s`, - async (method, to) => { - let handler = createRequestHandler(build); - let response = await handler( - new Request(`http://localhost:3000${to}`, { - method, - }) - ); - - expect(response.status).toBe(200); - let text = await response.text(); - expect(text).toContain(method); - let expected = !to.includes("?_data=root") - ? "COMPONENT" - : method === "GET" - ? "LOADER" - : "ACTION"; - expect(text).toContain(expected); - expect(spy.console).not.toHaveBeenCalled(); - } - ); - - it("strips body for HEAD requests", async () => { - let handler = createRequestHandler(build); - let response = await handler( - new Request("http://localhost:3000/", { - method: "HEAD", - }) - ); - - expect(await response.text()).toBe(""); - }); - }); -}); - -describe("shared server runtime", () => { - let spy = spyConsole(); - - beforeEach(() => { - spy.console.mockClear(); - }); - - let baseUrl = "http://test.com"; - - describe("resource routes", () => { - test("calls resource route loader", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let resourceLoader = jest.fn(() => { - return "resource"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/resource": { - loader: resourceLoader, - path: "resource", - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/resource`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(200); - expect(await result.json()).toBe("resource"); - expect(rootLoader.mock.calls.length).toBe(0); - expect(resourceLoader.mock.calls.length).toBe(1); - }); - - test("calls resource route loader throwing response with immutable headers", async () => { - let build = mockServerBuild({ - root: { - default: {}, - }, - "routes/resource": { - parentId: "root", - path: "resource", - loader() { - let headers = new Headers({ "x-test": "yes" }); - let headersProxy = new Proxy(headers, { - get(target, prop) { - if (prop === "set") { - throw new TypeError("immutable"); - } - return target[prop].bind(target); - }, - }); - // Mock a "response" that will pass the `isResponse` check - throw { - status: 400, - statusText: "Bad Request", - headers: headersProxy, - body: "text", - text: () => Promise.resolve("text"), - }; - }, - }, - }); - let handler = createRequestHandler(build, ServerMode.Development); - - let request = new Request(`${baseUrl}/resource`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(400); - expect(result.headers.get("x-test")).toBe("yes"); - expect(result.headers.get("X-Remix-Catch")).toBe("yes"); - expect(await result.text()).toBe("text"); - }); - - test("calls sub resource route loader", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let resourceLoader = jest.fn(() => { - return "resource"; - }); - let subResourceLoader = jest.fn(() => { - return "sub"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/resource": { - loader: resourceLoader, - path: "resource", - }, - "routes/resource.sub": { - loader: subResourceLoader, - path: "resource/sub", - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/resource/sub`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(200); - expect(await result.json()).toBe("sub"); - expect(rootLoader.mock.calls.length).toBe(0); - expect(resourceLoader.mock.calls.length).toBe(0); - expect(subResourceLoader.mock.calls.length).toBe(1); - }); - - test("resource route loader allows thrown responses", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let resourceLoader = jest.fn(() => { - throw new Response("resource"); - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/resource": { - loader: resourceLoader, - path: "resource", - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/resource`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(200); - expect(await result.text()).toBe("resource"); - expect(rootLoader.mock.calls.length).toBe(0); - expect(resourceLoader.mock.calls.length).toBe(1); - }); - - test("resource route loader responds with generic error when thrown", async () => { - let error = new Error("should be logged when resource loader throws"); - let loader = jest.fn(() => { - throw error; - }); - let build = mockServerBuild({ - "routes/resource": { - loader, - path: "resource", - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/resource`, { - method: "get", - }); - - let result = await handler(request); - expect(await result.text()).toBe( - "Unexpected Server Error\n\nError: should be logged when resource loader throws" - ); - }); - - test("resource route loader responds with detailed error when thrown in development", async () => { - let error = new Error("should be logged when resource loader throws"); - let loader = jest.fn(() => { - throw error; - }); - let build = mockServerBuild({ - "routes/resource": { - loader, - path: "resource", - }, - }); - let handler = createRequestHandler(build, ServerMode.Development); - - let request = new Request(`${baseUrl}/resource`, { - method: "get", - }); - - let result = await handler(request); - expect((await result.text()).includes(error.message)).toBe(true); - expect(spy.console.mock.calls.length).toBe(1); - }); - - test("calls resource route action", async () => { - let rootAction = jest.fn(() => { - return "root"; - }); - let resourceAction = jest.fn(() => { - return "resource"; - }); - let build = mockServerBuild({ - root: { - default: {}, - action: rootAction, - }, - "routes/resource": { - action: resourceAction, - path: "resource", - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/resource`, { - method: "post", - }); - - let result = await handler(request); - expect(result.status).toBe(200); - expect(await result.json()).toBe("resource"); - expect(rootAction.mock.calls.length).toBe(0); - expect(resourceAction.mock.calls.length).toBe(1); - }); - - test("calls sub resource route action", async () => { - let rootAction = jest.fn(() => { - return "root"; - }); - let resourceAction = jest.fn(() => { - return "resource"; - }); - let subResourceAction = jest.fn(() => { - return "sub"; - }); - let build = mockServerBuild({ - root: { - default: {}, - action: rootAction, - }, - "routes/resource": { - action: resourceAction, - path: "resource", - }, - "routes/resource.sub": { - action: subResourceAction, - path: "resource/sub", - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/resource/sub`, { - method: "post", - }); - - let result = await handler(request); - expect(result.status).toBe(200); - expect(await result.json()).toBe("sub"); - expect(rootAction.mock.calls.length).toBe(0); - expect(resourceAction.mock.calls.length).toBe(0); - expect(subResourceAction.mock.calls.length).toBe(1); - }); - - test("resource route action allows thrown responses", async () => { - let rootAction = jest.fn(() => { - return "root"; - }); - let resourceAction = jest.fn(() => { - throw new Response("resource"); - }); - let build = mockServerBuild({ - root: { - default: {}, - action: rootAction, - }, - "routes/resource": { - action: resourceAction, - path: "resource", - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/resource`, { - method: "post", - }); - - let result = await handler(request); - expect(result.status).toBe(200); - expect(await result.text()).toBe("resource"); - expect(rootAction.mock.calls.length).toBe(0); - expect(resourceAction.mock.calls.length).toBe(1); - }); - - test("resource route action responds with generic error when thrown", async () => { - let error = new Error("should be logged when resource loader throws"); - let action = jest.fn(() => { - throw error; - }); - let build = mockServerBuild({ - "routes/resource": { - action, - path: "resource", - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/resource`, { - method: "post", - }); - - let result = await handler(request); - expect(await result.text()).toBe( - "Unexpected Server Error\n\nError: should be logged when resource loader throws" - ); - }); - - test("resource route action responds with detailed error when thrown in development", async () => { - let message = "should be logged when resource loader throws"; - let action = jest.fn(() => { - throw new Error(message); - }); - let build = mockServerBuild({ - "routes/resource": { - action, - path: "resource", - }, - }); - let handler = createRequestHandler(build, ServerMode.Development); - - let request = new Request(`${baseUrl}/resource`, { - method: "post", - }); - - let result = await handler(request); - expect((await result.text()).includes(message)).toBe(true); - expect(spy.console.mock.calls.length).toBe(1); - }); - - test("aborts request", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let resourceLoader = jest.fn(async () => { - await new Promise((r) => setTimeout(r, 10)); - return "resource"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/resource": { - loader: resourceLoader, - path: "resource", - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let controller = new AbortController(); - let request = new Request(`${baseUrl}/resource`, { - method: "get", - signal: controller.signal, - }); - - let resultPromise = handler(request); - controller.abort(); - let result = await resultPromise; - expect(result.status).toBe(500); - expect(await result.text()).toMatchInlineSnapshot(` - "Unexpected Server Error - - Error: queryRoute() call aborted: GET http://test.com/resource" - `); - }); - - test("aborts request (v3_throwAbortReason)", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let resourceLoader = jest.fn(async () => { - await new Promise((r) => setTimeout(r, 10)); - return "resource"; - }); - let handleErrorSpy = jest.fn(); - let build = mockServerBuild( - { - root: { - default: {}, - loader: rootLoader, - }, - "routes/resource": { - loader: resourceLoader, - path: "resource", - }, - }, - { - future: { - v3_throwAbortReason: true, - }, - handleError: handleErrorSpy, - } - ); - let handler = createRequestHandler(build, ServerMode.Test); - - let controller = new AbortController(); - let request = new Request(`${baseUrl}/resource`, { - method: "get", - signal: controller.signal, - }); - - let resultPromise = handler(request); - controller.abort(); - let result = await resultPromise; - expect(result.status).toBe(500); - expect(await result.text()).toMatchInlineSnapshot(` - "Unexpected Server Error - - AbortError: This operation was aborted" - `); - expect(handleErrorSpy).toHaveBeenCalledTimes(1); - expect(handleErrorSpy.mock.calls[0][0] instanceof DOMException).toBe( - true - ); - expect(handleErrorSpy.mock.calls[0][0].name).toBe("AbortError"); - expect(handleErrorSpy.mock.calls[0][0].message).toBe( - "This operation was aborted" - ); - expect(handleErrorSpy.mock.calls[0][1].request.method).toBe("GET"); - expect(handleErrorSpy.mock.calls[0][1].request.url).toBe( - "http://test.com/resource" - ); - }); - }); - - describe("data requests", () => { - test("data request that does not match loader surfaces 400 error for boundary", async () => { - let build = mockServerBuild({ - root: { - default: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/?_data=routes/_index`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(400); - expect(result.headers.get("X-Remix-Error")).toBe("yes"); - expect((await result.json()).message).toBeTruthy(); - }); - - test("data request that does not match routeId surfaces 403 error for boundary", async () => { - let build = mockServerBuild({ - root: { - default: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - loader: () => null, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - // This bug wasn't that the router wasn't returning a 404 (it was), but - // that we weren't defensive when looking at match.params when we went - // to call handleDataRequest(), - and that threw it's own uncaught - // exception triggering a 500. We need to ensure that this build has a - // handleDataRequest implementation for this test to mean anything - expect(build.entry.module.handleDataRequest).toBeDefined(); - - let request = new Request(`${baseUrl}/?_data=routes/junk`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(403); - expect(result.headers.get("X-Remix-Error")).toBe("yes"); - expect((await result.json()).message).toBeTruthy(); - }); - - test("data request that does not match route surfaces 404 error for boundary", async () => { - let build = mockServerBuild({ - root: { - default: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - loader: () => null, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/junk?_data=routes/junk`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(404); - expect(result.headers.get("X-Remix-Error")).toBe("yes"); - expect((await result.json()).message).toBeTruthy(); - }); - - test("data request calls loader", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/_index": { - parentId: "root", - loader: indexLoader, - index: true, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/?_data=routes/_index`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(200); - expect(await result.json()).toBe("index"); - expect(rootLoader.mock.calls.length).toBe(0); - expect(indexLoader.mock.calls.length).toBe(1); - }); - - test("data request calls loader returning response with immutable headers", async () => { - let build = mockServerBuild({ - root: { - default: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - loader() { - let headers = new Headers({ "x-test": "yes" }); - let headersProxy = new Proxy(headers, { - get(target, prop) { - if (prop === "set") { - throw new TypeError("immutable"); - } - return target[prop].bind(target); - }, - }); - // Mock a "response" that will pass the `isResponse` check - return { - status: 200, - statusText: "OK", - headers: headersProxy, - body: "text", - text: () => Promise.resolve("text"), - }; - }, - }, - }); - let handler = createRequestHandler(build, ServerMode.Development); - - let request = new Request(`${baseUrl}/?_data=routes/_index`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(200); - expect(result.headers.get("x-test")).toBe("yes"); - expect(result.headers.get("X-Remix-Response")).toBe("yes"); - expect(await result.text()).toBe("text"); - }); - - test("data request calls loader throwing response with immutable headers", async () => { - let build = mockServerBuild({ - root: { - default: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - loader() { - let headers = new Headers({ "x-test": "yes" }); - let headersProxy = new Proxy(headers, { - get(target, prop) { - if (prop === "set") { - throw new TypeError("immutable"); - } - return target[prop].bind(target); - }, - }); - // Mock a "response" that will pass the `isResponse` check - throw { - status: 400, - statusText: "Bad Request", - headers: headersProxy, - body: "text", - text: () => Promise.resolve("text"), - }; - }, - }, - }); - let handler = createRequestHandler(build, ServerMode.Development); - - let request = new Request(`${baseUrl}/?_data=routes/_index`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(400); - expect(result.headers.get("x-test")).toBe("yes"); - expect(result.headers.get("X-Remix-Catch")).toBe("yes"); - expect(await result.text()).toBe("text"); - }); - - test("data request calls loader and responds with generic message and error header", async () => { - let rootLoader = jest.fn(() => { - throw new Error("test"); - }); - let testAction = jest.fn(() => { - return "root"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/test": { - parentId: "root", - action: testAction, - path: "test", - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/test?_data=root`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(500); - expect((await result.json()).message).toBe("Unexpected Server Error"); - expect(result.headers.get("X-Remix-Error")).toBe("yes"); - expect(rootLoader.mock.calls.length).toBe(1); - expect(testAction.mock.calls.length).toBe(0); - }); - - test("data request calls loader and responds with detailed info and error header in development mode", async () => { - let message = - "data request loader error logged to console once in dev mode"; - let rootLoader = jest.fn(() => { - throw new Error(message); - }); - let testAction = jest.fn(() => { - return "root"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/test": { - parentId: "root", - action: testAction, - path: "test", - }, - }); - let handler = createRequestHandler(build, ServerMode.Development); - - let request = new Request(`${baseUrl}/test?_data=root`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(500); - expect((await result.json()).message).toBe(message); - expect(result.headers.get("X-Remix-Error")).toBe("yes"); - expect(rootLoader.mock.calls.length).toBe(1); - expect(testAction.mock.calls.length).toBe(0); - expect(spy.console.mock.calls.length).toBe(1); - }); - - test("data request calls loader and responds with catch header", async () => { - let rootLoader = jest.fn(() => { - throw new Response("test", { status: 400 }); - }); - let testAction = jest.fn(() => { - return "root"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/test": { - parentId: "root", - action: testAction, - path: "test", - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/test?_data=root`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(400); - expect(await result.text()).toBe("test"); - expect(result.headers.get("X-Remix-Catch")).toBe("yes"); - expect(rootLoader.mock.calls.length).toBe(1); - expect(testAction.mock.calls.length).toBe(0); - }); - - test("data request calls action", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let testAction = jest.fn(() => { - return "test"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/test": { - parentId: "root", - action: testAction, - path: "test", - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/test?_data=routes/test`, { - method: "post", - }); - - let result = await handler(request); - expect(result.status).toBe(200); - expect(await result.json()).toBe("test"); - expect(rootLoader.mock.calls.length).toBe(0); - expect(testAction.mock.calls.length).toBe(1); - }); - - test("data request calls action and responds with generic message and error header", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let testAction = jest.fn(() => { - throw new Error("test"); - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/test": { - parentId: "root", - action: testAction, - path: "test", - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/test?_data=routes/test`, { - method: "post", - }); - - let result = await handler(request); - expect(result.status).toBe(500); - expect((await result.json()).message).toBe("Unexpected Server Error"); - expect(result.headers.get("X-Remix-Error")).toBe("yes"); - expect(rootLoader.mock.calls.length).toBe(0); - expect(testAction.mock.calls.length).toBe(1); - }); - - test("data request calls action and responds with detailed info and error header in development mode", async () => { - let message = - "data request action error logged to console once in dev mode"; - let rootLoader = jest.fn(() => { - return "root"; - }); - let testAction = jest.fn(() => { - throw new Error(message); - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/test": { - parentId: "root", - action: testAction, - path: "test", - }, - }); - let handler = createRequestHandler(build, ServerMode.Development); - - let request = new Request(`${baseUrl}/test?_data=routes/test`, { - method: "post", - }); - - let result = await handler(request); - expect(result.status).toBe(500); - expect((await result.json()).message).toBe(message); - expect(result.headers.get("X-Remix-Error")).toBe("yes"); - expect(rootLoader.mock.calls.length).toBe(0); - expect(testAction.mock.calls.length).toBe(1); - expect(spy.console.mock.calls.length).toBe(1); - }); - - test("data request calls action and responds with catch header", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let testAction = jest.fn(() => { - throw new Response("test", { status: 400 }); - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/test": { - parentId: "root", - action: testAction, - path: "test", - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/test?_data=routes/test`, { - method: "post", - }); - - let result = await handler(request); - expect(result.status).toBe(400); - expect(await result.text()).toBe("test"); - expect(result.headers.get("X-Remix-Catch")).toBe("yes"); - expect(rootLoader.mock.calls.length).toBe(0); - expect(testAction.mock.calls.length).toBe(1); - }); - - test("data request calls layout action", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let rootAction = jest.fn(() => { - return "root"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - action: rootAction, - }, - "routes/_index": { - parentId: "root", - index: true, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/?_data=root`, { - method: "post", - }); - - let result = await handler(request); - expect(result.status).toBe(200); - expect(await result.json()).toBe("root"); - expect(rootLoader.mock.calls.length).toBe(0); - expect(rootAction.mock.calls.length).toBe(1); - }); - - test("data request calls index action", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexAction = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/_index": { - parentId: "root", - action: indexAction, - index: true, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/?index&_data=routes/_index`, { - method: "post", - }); - - let result = await handler(request); - expect(result.status).toBe(200); - expect(await result.json()).toBe("index"); - expect(rootLoader.mock.calls.length).toBe(0); - expect(indexAction.mock.calls.length).toBe(1); - }); - - test("data request handleDataRequest redirects are handled", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/_index": { - parentId: "root", - loader: indexLoader, - index: true, - }, - }); - build.entry.module.handleDataRequest.mockImplementation(async () => { - return new Response(null, { - status: 302, - headers: { - Location: "/redirect", - }, - }); - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/?_data=routes/_index`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(204); - expect(result.headers.get("X-Remix-Redirect")).toBe("/redirect"); - expect(result.headers.get("X-Remix-Status")).toBe("302"); - expect(rootLoader.mock.calls.length).toBe(0); - expect(indexLoader.mock.calls.length).toBe(1); - }); - - test("aborts request", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - "routes/_index": { - parentId: "root", - loader: indexLoader, - index: true, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let controller = new AbortController(); - let request = new Request(`${baseUrl}/?_data=routes/_index`, { - method: "get", - signal: controller.signal, - }); - - let resultPromise = handler(request); - controller.abort(); - let result = await resultPromise; - expect(result.status).toBe(500); - expect(await result.text()).toMatchInlineSnapshot( - `"{"message":"Unexpected Server Error"}"` - ); - }); - - test("aborts request (v3_throwAbortReason)", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let handleErrorSpy = jest.fn(); - let build = mockServerBuild( - { - root: { - default: {}, - loader: rootLoader, - }, - "routes/_index": { - parentId: "root", - loader: indexLoader, - index: true, - }, - }, - { - future: { - v3_throwAbortReason: true, - }, - handleError: handleErrorSpy, - } - ); - let handler = createRequestHandler(build, ServerMode.Test); - - let controller = new AbortController(); - let request = new Request(`${baseUrl}/?_data=routes/_index`, { - method: "get", - signal: controller.signal, - }); - - let resultPromise = handler(request); - controller.abort(); - let result = await resultPromise; - expect(result.status).toBe(500); - let error = await result.json(); - expect(error.message).toBe("This operation was aborted"); - expect( - error.stack.startsWith("AbortError: This operation was aborted") - ).toBe(true); - expect(handleErrorSpy).toHaveBeenCalledTimes(1); - expect(handleErrorSpy.mock.calls[0][0] instanceof DOMException).toBe( - true - ); - expect(handleErrorSpy.mock.calls[0][0].name).toBe("AbortError"); - expect(handleErrorSpy.mock.calls[0][0].message).toBe( - "This operation was aborted" - ); - expect(handleErrorSpy.mock.calls[0][1].request.method).toBe("GET"); - expect(handleErrorSpy.mock.calls[0][1].request.url).toBe( - "http://test.com/?_data=routes/_index" - ); - }); - }); - - describe("document requests", () => { - test("not found document request for no matches and no ErrorBoundary", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/`, { - method: "get", - }); - - let result = await handler(request); - expect(result.status).toBe(404); - expect(rootLoader.mock.calls.length).toBe(0); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!.root.status).toBe(404); - }); - - test("sets root as catch boundary for not found document request", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/`, { method: "get" }); - - let result = await handler(request); - expect(result.status).toBe(404); - expect(rootLoader.mock.calls.length).toBe(0); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!.root.status).toBe(404); - expect(context.loaderData).toEqual({}); - }); - - test("thrown loader responses bubble up", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(() => { - throw new Response(null, { status: 400 }); - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - default: {}, - loader: indexLoader, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/`, { method: "get" }); - - let result = await handler(request); - expect(result.status).toBe(400); - expect(rootLoader.mock.calls.length).toBe(1); - expect(indexLoader.mock.calls.length).toBe(1); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!.root.status).toBe(400); - expect(context.loaderData).toEqual({ - root: "root", - }); - }); - - test("thrown loader responses catch deep", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(() => { - throw new Response(null, { status: 400 }); - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - default: {}, - loader: indexLoader, - ErrorBoundary: {}, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/`, { method: "get" }); - - let result = await handler(request); - expect(result.status).toBe(400); - expect(rootLoader.mock.calls.length).toBe(1); - expect(indexLoader.mock.calls.length).toBe(1); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!["routes/_index"].status).toBe(400); - expect(context.loaderData).toEqual({ - root: "root", - }); - }); - - test("thrown action responses bubble up", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let testAction = jest.fn(() => { - throw new Response(null, { status: 400 }); - }); - let testLoader = jest.fn(() => { - return "test"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/test": { - parentId: "root", - path: "test", - default: {}, - loader: testLoader, - action: testAction, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/test`, { method: "post" }); - - let result = await handler(request); - expect(result.status).toBe(400); - expect(testAction.mock.calls.length).toBe(1); - // Should not call root loader since it is the boundary route - expect(rootLoader.mock.calls.length).toBe(0); - expect(testLoader.mock.calls.length).toBe(0); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!.root.status).toBe(400); - expect(context.loaderData).toEqual({ - root: null, - "routes/test": null, - }); - }); - - test("thrown action responses bubble up for index routes", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexAction = jest.fn(() => { - throw new Response(null, { status: 400 }); - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - default: {}, - loader: indexLoader, - action: indexAction, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/?index`, { method: "post" }); - - let result = await handler(request); - expect(result.status).toBe(400); - expect(indexAction.mock.calls.length).toBe(1); - // Should not call root loader since it is the boundary route - expect(rootLoader.mock.calls.length).toBe(0); - expect(indexLoader.mock.calls.length).toBe(0); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!.root.status).toBe(400); - expect(context.loaderData).toEqual({ - root: null, - "routes/_index": null, - }); - }); - - test("thrown action responses catch deep", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let testAction = jest.fn(() => { - throw new Response(null, { status: 400 }); - }); - let testLoader = jest.fn(() => { - return "test"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/test": { - parentId: "root", - path: "test", - default: {}, - loader: testLoader, - action: testAction, - ErrorBoundary: {}, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/test`, { method: "post" }); - - let result = await handler(request); - expect(result.status).toBe(400); - expect(testAction.mock.calls.length).toBe(1); - expect(rootLoader.mock.calls.length).toBe(1); - expect(testLoader.mock.calls.length).toBe(0); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!["routes/test"].status).toBe(400); - expect(context.loaderData).toEqual({ - root: "root", - "routes/test": null, - }); - }); - - test("thrown action responses catch deep for index routes", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexAction = jest.fn(() => { - throw new Response(null, { status: 400 }); - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - default: {}, - loader: indexLoader, - action: indexAction, - ErrorBoundary: {}, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/?index`, { method: "post" }); - - let result = await handler(request); - expect(result.status).toBe(400); - expect(indexAction.mock.calls.length).toBe(1); - expect(rootLoader.mock.calls.length).toBe(1); - expect(indexLoader.mock.calls.length).toBe(0); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!["routes/_index"].status).toBe(400); - expect(context.loaderData).toEqual({ - root: "root", - "routes/_index": null, - }); - }); - - test("thrown loader response after thrown action response bubble up action throw to deepest loader boundary", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let layoutLoader = jest.fn(() => { - throw new Response("layout", { status: 401 }); - }); - let testAction = jest.fn(() => { - throw new Response("action", { status: 400 }); - }); - let testLoader = jest.fn(() => { - return "test"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/__layout": { - parentId: "root", - default: {}, - loader: layoutLoader, - ErrorBoundary: {}, - }, - "routes/__layout/test": { - parentId: "routes/__layout", - path: "test", - default: {}, - loader: testLoader, - action: testAction, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/test`, { method: "post" }); - - let result = await handler(request); - expect(result.status).toBe(400); - expect(testAction.mock.calls.length).toBe(1); - expect(rootLoader.mock.calls.length).toBe(1); - expect(testLoader.mock.calls.length).toBe(0); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!["routes/__layout"].data).toBe("action"); - expect(context.loaderData).toEqual({ - root: "root", - "routes/__layout": null, - "routes/__layout/test": null, - }); - }); - - test("thrown loader response after thrown index action response bubble up action throw to deepest loader boundary", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let layoutLoader = jest.fn(() => { - throw new Response("layout", { status: 401 }); - }); - let indexAction = jest.fn(() => { - throw new Response("action", { status: 400 }); - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/__layout": { - parentId: "root", - default: {}, - loader: layoutLoader, - ErrorBoundary: {}, - }, - "routes/__layout/index": { - parentId: "routes/__layout", - index: true, - default: {}, - loader: indexLoader, - action: indexAction, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/?index`, { method: "post" }); - - let result = await handler(request); - expect(result.status).toBe(400); - expect(indexAction.mock.calls.length).toBe(1); - expect(rootLoader.mock.calls.length).toBe(1); - expect(indexLoader.mock.calls.length).toBe(0); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!["routes/__layout"].data).toBe("action"); - expect(context.loaderData).toEqual({ - root: "root", - "routes/__layout": null, - "routes/__layout/index": null, - }); - }); - - test("loader errors bubble up", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(() => { - throw new Error("index"); - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - default: {}, - loader: indexLoader, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/`, { method: "get" }); - - let result = await handler(request); - expect(result.status).toBe(500); - expect(rootLoader.mock.calls.length).toBe(1); - expect(indexLoader.mock.calls.length).toBe(1); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!.root).toBeInstanceOf(Error); - expect(context.errors!.root.message).toBe("Unexpected Server Error"); - expect(context.errors!.root.stack).toBeUndefined(); - expect(context.loaderData).toEqual({ - root: "root", - }); - }); - - test("loader errors catch deep", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(() => { - throw new Error("index"); - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - default: {}, - loader: indexLoader, - ErrorBoundary: {}, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/`, { method: "get" }); - - let result = await handler(request); - expect(result.status).toBe(500); - expect(rootLoader.mock.calls.length).toBe(1); - expect(indexLoader.mock.calls.length).toBe(1); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!["routes/_index"]).toBeInstanceOf(Error); - expect(context.errors!["routes/_index"].message).toBe( - "Unexpected Server Error" - ); - expect(context.errors!["routes/_index"].stack).toBeUndefined(); - expect(context.loaderData).toEqual({ - root: "root", - }); - }); - - test("action errors bubble up", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let testAction = jest.fn(() => { - throw new Error("test"); - }); - let testLoader = jest.fn(() => { - return "test"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/test": { - parentId: "root", - path: "test", - default: {}, - loader: testLoader, - action: testAction, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/test`, { method: "post" }); - - let result = await handler(request); - expect(result.status).toBe(500); - expect(testAction.mock.calls.length).toBe(1); - // Should not call root loader since it is the boundary route - expect(rootLoader.mock.calls.length).toBe(0); - expect(testLoader.mock.calls.length).toBe(0); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!.root).toBeInstanceOf(Error); - expect(context.errors!.root.message).toBe("Unexpected Server Error"); - expect(context.errors!.root.stack).toBeUndefined(); - expect(context.loaderData).toEqual({ - root: null, - "routes/test": null, - }); - }); - - test("action errors bubble up for index routes", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexAction = jest.fn(() => { - throw new Error("index"); - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - default: {}, - loader: indexLoader, - action: indexAction, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/?index`, { method: "post" }); - - let result = await handler(request); - expect(result.status).toBe(500); - expect(indexAction.mock.calls.length).toBe(1); - // Should not call root loader since it is the boundary route - expect(rootLoader.mock.calls.length).toBe(0); - expect(indexLoader.mock.calls.length).toBe(0); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!.root).toBeInstanceOf(Error); - expect(context.errors!.root.message).toBe("Unexpected Server Error"); - expect(context.errors!.root.stack).toBeUndefined(); - expect(context.loaderData).toEqual({ - root: null, - "routes/_index": null, - }); - }); - - test("action errors catch deep", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let testAction = jest.fn(() => { - throw new Error("test"); - }); - let testLoader = jest.fn(() => { - return "test"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/test": { - parentId: "root", - path: "test", - default: {}, - loader: testLoader, - action: testAction, - ErrorBoundary: {}, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/test`, { method: "post" }); - - let result = await handler(request); - expect(result.status).toBe(500); - expect(testAction.mock.calls.length).toBe(1); - expect(rootLoader.mock.calls.length).toBe(1); - expect(testLoader.mock.calls.length).toBe(0); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!["routes/test"]).toBeInstanceOf(Error); - expect(context.errors!["routes/test"].message).toBe( - "Unexpected Server Error" - ); - expect(context.errors!["routes/test"].stack).toBeUndefined(); - expect(context.loaderData).toEqual({ - root: "root", - "routes/test": null, - }); - }); - - test("action errors catch deep for index routes", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexAction = jest.fn(() => { - throw new Error("index"); - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - default: {}, - loader: indexLoader, - action: indexAction, - ErrorBoundary: {}, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/?index`, { method: "post" }); - - let result = await handler(request); - expect(result.status).toBe(500); - expect(indexAction.mock.calls.length).toBe(1); - expect(rootLoader.mock.calls.length).toBe(1); - expect(indexLoader.mock.calls.length).toBe(0); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!["routes/_index"]).toBeInstanceOf(Error); - expect(context.errors!["routes/_index"].message).toBe( - "Unexpected Server Error" - ); - expect(context.errors!["routes/_index"].stack).toBeUndefined(); - expect(context.loaderData).toEqual({ - root: "root", - "routes/_index": null, - }); - }); - - test("loader errors after action error bubble up action error to deepest loader boundary", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let layoutLoader = jest.fn(() => { - throw new Error("layout"); - }); - let testAction = jest.fn(() => { - throw new Error("action"); - }); - let testLoader = jest.fn(() => { - return "test"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/__layout": { - parentId: "root", - default: {}, - loader: layoutLoader, - ErrorBoundary: {}, - }, - "routes/__layout/test": { - parentId: "routes/__layout", - path: "test", - default: {}, - loader: testLoader, - action: testAction, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/test`, { method: "post" }); - - let result = await handler(request); - expect(result.status).toBe(500); - expect(testAction.mock.calls.length).toBe(1); - expect(rootLoader.mock.calls.length).toBe(1); - expect(testLoader.mock.calls.length).toBe(0); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!["routes/__layout"]).toBeInstanceOf(Error); - expect(context.errors!["routes/__layout"].message).toBe( - "Unexpected Server Error" - ); - expect(context.errors!["routes/__layout"].stack).toBeUndefined(); - expect(context.loaderData).toEqual({ - root: "root", - "routes/__layout": null, - "routes/__layout/test": null, - }); - }); - - test("loader errors after index action error bubble up action error to deepest loader boundary", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let layoutLoader = jest.fn(() => { - throw new Error("layout"); - }); - let indexAction = jest.fn(() => { - throw new Error("action"); - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/__layout": { - parentId: "root", - default: {}, - loader: layoutLoader, - ErrorBoundary: {}, - }, - "routes/__layout/index": { - parentId: "routes/__layout", - index: true, - default: {}, - loader: indexLoader, - action: indexAction, - }, - }); - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/?index`, { method: "post" }); - - let result = await handler(request); - expect(result.status).toBe(500); - expect(indexAction.mock.calls.length).toBe(1); - expect(rootLoader.mock.calls.length).toBe(1); - expect(indexLoader.mock.calls.length).toBe(0); - expect(build.entry.module.default.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(1); - let context = calls[0][3].staticHandlerContext as StaticHandlerContext; - expect(context.errors).toBeTruthy(); - expect(context.errors!["routes/__layout"]).toBeInstanceOf(Error); - expect(context.errors!["routes/__layout"].message).toBe( - "Unexpected Server Error" - ); - expect(context.errors!["routes/__layout"].stack).toBeUndefined(); - expect(context.loaderData).toEqual({ - root: "root", - "routes/__layout": null, - "routes/__layout/index": null, - }); - }); - - test("calls handleDocumentRequest again with new error when handleDocumentRequest throws", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - default: {}, - loader: indexLoader, - }, - }); - let calledBefore = false; - let ogHandleDocumentRequest = build.entry.module.default; - build.entry.module.default = jest.fn(function () { - if (!calledBefore) { - throw new Error("thrown"); - } - calledBefore = true; - return ogHandleDocumentRequest.call(null, ...arguments); - }) as any; - let handler = createRequestHandler(build, ServerMode.Development); - - let request = new Request(`${baseUrl}/404`, { method: "get" }); - - let result = await handler(request); - expect(result.status).toBe(500); - expect(rootLoader.mock.calls.length).toBe(0); - expect(indexLoader.mock.calls.length).toBe(0); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(2); - let context = calls[1][3].staticHandlerContext; - expect(context.errors.root).toBeTruthy(); - expect(context.errors!.root.message).toBe("thrown"); - expect(context.loaderData).toEqual({}); - }); - - test("unwraps responses thrown from handleDocumentRequest", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - default: {}, - loader: indexLoader, - }, - }); - let ogHandleDocumentRequest = build.entry.module.default; - build.entry.module.default = function ( - _: Request, - responseStatusCode: number - ) { - if (responseStatusCode === 200) { - throw new Response("Uh oh!", { - status: 400, - statusText: "Bad Request", - }); - } - return ogHandleDocumentRequest.call(null, ...arguments); - } as any; - let handler = createRequestHandler(build, ServerMode.Development); - - let request = new Request(`${baseUrl}/`, { method: "get" }); - - let result = await handler(request); - expect(result.status).toBe(400); - }); - - test("returns generic message if handleDocumentRequest throws a second time", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/_index": { - parentId: "root", - default: {}, - loader: indexLoader, - }, - }); - let lastThrownError; - build.entry.module.default = jest.fn(function () { - lastThrownError = new Error("rofl"); - throw lastThrownError; - }) as any; - let handler = createRequestHandler(build, ServerMode.Test); - - let request = new Request(`${baseUrl}/`, { method: "get" }); - - let result = await handler(request); - expect(result.status).toBe(500); - expect(await result.text()).toBe( - "Unexpected Server Error\n\nError: rofl" - ); - expect(rootLoader.mock.calls.length).toBe(0); - expect(indexLoader.mock.calls.length).toBe(0); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(2); - }); - - test("returns more detailed message if handleDocumentRequest throws a second time in development mode", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - path: "/", - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/_index": { - parentId: "root", - index: true, - default: {}, - loader: indexLoader, - }, - }); - let errorMessage = - "thrown from handleDocumentRequest and expected to be logged in console only once"; - let lastThrownError; - build.entry.module.default = jest.fn(function () { - lastThrownError = new Error(errorMessage); - errorMessage = "second error thrown from handleDocumentRequest"; - throw lastThrownError; - }) as any; - let handler = createRequestHandler(build, ServerMode.Development); - - let request = new Request(`${baseUrl}/`); - - let result = await handler(request); - expect(result.status).toBe(500); - expect((await result.text()).includes(errorMessage)).toBe(true); - expect(rootLoader.mock.calls.length).toBe(1); - expect(indexLoader.mock.calls.length).toBe(1); - - let calls = build.entry.module.default.mock.calls; - expect(calls.length).toBe(2); - expect(spy.console.mock.calls).toEqual([ - [ - new Error( - "thrown from handleDocumentRequest and expected to be logged in console only once" - ), - ], - [new Error("second error thrown from handleDocumentRequest")], - ]); - }); - - test("aborts request", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(async () => { - await new Promise((r) => setTimeout(r, 10)); - return "index"; - }); - let handleErrorSpy = jest.fn(); - let build = mockServerBuild( - { - root: { - default() {}, - loader: rootLoader, - }, - "routes/_index": { - loader: indexLoader, - index: true, - default: {}, - }, - }, - { - handleError: handleErrorSpy, - } - ); - let handler = createRequestHandler(build, ServerMode.Test); - - let controller = new AbortController(); - let request = new Request(`${baseUrl}/`, { - method: "get", - signal: controller.signal, - }); - - let resultPromise = handler(request); - controller.abort(); - let result = await resultPromise; - expect(result.status).toBe(500); - expect(build.entry.module.default.mock.calls.length).toBe(0); - - expect(handleErrorSpy).toHaveBeenCalledTimes(1); - expect(handleErrorSpy.mock.calls[0][0] instanceof Error).toBe(true); - expect(handleErrorSpy.mock.calls[0][0].name).toBe("Error"); - expect(handleErrorSpy.mock.calls[0][0].message).toBe( - "query() call aborted: GET http://test.com/" - ); - }); - - test("aborts request (v3_throwAbortReason)", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(async () => { - await new Promise((r) => setTimeout(r, 10)); - return "index"; - }); - let handleErrorSpy = jest.fn(); - let build = mockServerBuild( - { - root: { - default: {}, - loader: rootLoader, - }, - "routes/resource": { - loader: indexLoader, - index: true, - default: {}, - }, - }, - { - future: { - v3_throwAbortReason: true, - }, - handleError: handleErrorSpy, - } - ); - let handler = createRequestHandler(build, ServerMode.Test); - - let controller = new AbortController(); - let request = new Request(`${baseUrl}/`, { - method: "get", - signal: controller.signal, - }); - - let resultPromise = handler(request); - controller.abort(); - let result = await resultPromise; - expect(result.status).toBe(500); - expect(build.entry.module.default.mock.calls.length).toBe(0); - - expect(handleErrorSpy).toHaveBeenCalledTimes(1); - expect(handleErrorSpy.mock.calls[0][0] instanceof DOMException).toBe( - true - ); - expect(handleErrorSpy.mock.calls[0][0].name).toBe("AbortError"); - expect(handleErrorSpy.mock.calls[0][0].message).toBe( - "This operation was aborted" - ); - expect(handleErrorSpy.mock.calls[0][1].request.method).toBe("GET"); - expect(handleErrorSpy.mock.calls[0][1].request.url).toBe( - "http://test.com/" - ); - }); - }); - - test("provides load context to server entrypoint", async () => { - let rootLoader = jest.fn(() => { - return "root"; - }); - let indexLoader = jest.fn(() => { - return "index"; - }); - let build = mockServerBuild({ - root: { - default: {}, - loader: rootLoader, - ErrorBoundary: {}, - }, - "routes/_index": { - parentId: "root", - default: {}, - loader: indexLoader, - }, - }); - - build.entry.module.default = jest.fn( - async ( - request, - responseStatusCode, - responseHeaders, - entryContext, - loadContext - ) => - new Response(JSON.stringify(loadContext), { - status: responseStatusCode, - headers: responseHeaders, - }) - ); - - let handler = createRequestHandler(build, ServerMode.Development); - let request = new Request(`${baseUrl}/`, { method: "get" }); - let loadContext = { "load-context": "load-value" }; - - let result = await handler(request, loadContext); - expect(await result.text()).toBe(JSON.stringify(loadContext)); - }); -}); diff --git a/packages/remix-server-runtime/__tests__/sessions-test.ts b/packages/remix-server-runtime/__tests__/sessions-test.ts deleted file mode 100644 index 041b5deb75c..00000000000 --- a/packages/remix-server-runtime/__tests__/sessions-test.ts +++ /dev/null @@ -1,356 +0,0 @@ -import { createCookieFactory } from "../cookies"; -import type { SignFunction, UnsignFunction } from "../crypto"; -import { - createSession, - createSessionStorageFactory, - isSession, -} from "../sessions"; -import { createCookieSessionStorageFactory } from "../sessions/cookieStorage"; -import { createMemorySessionStorageFactory } from "../sessions/memoryStorage"; - -function getCookieFromSetCookie(setCookie: string): string { - return setCookie.split(/;\s*/)[0]; -} - -const sign: SignFunction = async (value, secret) => { - return JSON.stringify({ value, secret }); -}; -const unsign: UnsignFunction = async (signed, secret) => { - try { - let unsigned = JSON.parse(signed); - if (unsigned.secret !== secret) return false; - return unsigned.value; - } catch (e: unknown) { - return false; - } -}; -const createCookie = createCookieFactory({ sign, unsign }); -const createCookieSessionStorage = - createCookieSessionStorageFactory(createCookie); -const createSessionStorage = createSessionStorageFactory(createCookie); -const createMemorySessionStorage = - createMemorySessionStorageFactory(createSessionStorage); - -describe("Session", () => { - it("has an empty id by default", () => { - expect(createSession().id).toEqual(""); - }); - - it("correctly stores and retrieves values", () => { - let session = createSession(); - - session.set("user", "mjackson"); - session.flash("error", "boom"); - - expect(session.has("user")).toBe(true); - expect(session.get("user")).toBe("mjackson"); - // Normal values should remain in the session after get() - expect(session.has("user")).toBe(true); - expect(session.get("user")).toBe("mjackson"); - - expect(session.has("error")).toBe(true); - expect(session.get("error")).toBe("boom"); - // Flash values disappear after the first get() - expect(session.has("error")).toBe(false); - expect(session.get("error")).toBeUndefined(); - - session.unset("user"); - - expect(session.has("user")).toBe(false); - expect(session.get("user")).toBeUndefined(); - }); -}); - -describe("isSession", () => { - it("returns `true` for Session objects", () => { - expect(isSession(createSession())).toBe(true); - }); - - it("returns `false` for non-Session objects", () => { - expect(isSession({})).toBe(false); - expect(isSession([])).toBe(false); - expect(isSession("")).toBe(false); - expect(isSession(true)).toBe(false); - }); -}); - -describe("In-memory session storage", () => { - it("persists session data across requests", async () => { - let { getSession, commitSession } = createMemorySessionStorage({ - cookie: { secrets: ["secret1"] }, - }); - let session = await getSession(); - session.set("user", "mjackson"); - let setCookie = await commitSession(session); - session = await getSession(getCookieFromSetCookie(setCookie)); - - expect(session.get("user")).toEqual("mjackson"); - }); - - it("uses random hash keys as session ids", async () => { - let { getSession, commitSession } = createMemorySessionStorage({ - cookie: { secrets: ["secret1"] }, - }); - let session = await getSession(); - session.set("user", "mjackson"); - let setCookie = await commitSession(session); - session = await getSession(getCookieFromSetCookie(setCookie)); - expect(session.id).toMatch(/^[a-z0-9]{8}$/); - }); -}); - -describe("Cookie session storage", () => { - it("persists session data across requests", async () => { - let { getSession, commitSession } = createCookieSessionStorage({ - cookie: { secrets: ["secret1"] }, - }); - let session = await getSession(); - session.set("user", "mjackson"); - let setCookie = await commitSession(session); - session = await getSession(getCookieFromSetCookie(setCookie)); - - expect(session.get("user")).toEqual("mjackson"); - }); - - it("returns an empty session for cookies that are not signed properly", async () => { - let { getSession, commitSession } = createCookieSessionStorage({ - cookie: { secrets: ["secret1"] }, - }); - let session = await getSession(); - session.set("user", "mjackson"); - - expect(session.get("user")).toEqual("mjackson"); - - let setCookie = await commitSession(session); - session = await getSession( - // Tamper with the session cookie... - getCookieFromSetCookie(setCookie).slice(0, -1) - ); - - expect(session.get("user")).toBeUndefined(); - }); - - it('"makes the default path of cookies to be /', async () => { - let { getSession, commitSession } = createCookieSessionStorage({ - cookie: { secrets: ["secret1"] }, - }); - let session = await getSession(); - session.set("user", "mjackson"); - let setCookie = await commitSession(session); - expect(setCookie).toContain("Path=/"); - }); - - it("throws an error when the cookie size exceeds 4096 bytes", async () => { - let { getSession, commitSession } = createCookieSessionStorage({ - cookie: { secrets: ["secret1"] }, - }); - let session = await getSession(); - let longString = new Array(4097).fill("a").join(""); - session.set("over4096bytes", longString); - await expect(() => commitSession(session)).rejects.toThrow(); - }); - - it("destroys sessions using a past date", async () => { - let spy = jest.spyOn(console, "warn").mockImplementation(() => {}); - let { getSession, destroySession } = createCookieSessionStorage({ - cookie: { - secrets: ["secret1"], - }, - }); - let session = await getSession(); - let setCookie = await destroySession(session); - expect(setCookie).toMatchInlineSnapshot( - `"__session=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax"` - ); - spy.mockRestore(); - }); - - it("destroys sessions that leverage maxAge", async () => { - let spy = jest.spyOn(console, "warn").mockImplementation(() => {}); - let { getSession, destroySession } = createCookieSessionStorage({ - cookie: { - maxAge: 60 * 60, // 1 hour - secrets: ["secret1"], - }, - }); - let session = await getSession(); - let setCookie = await destroySession(session); - expect(setCookie).toMatchInlineSnapshot( - `"__session=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax"` - ); - spy.mockRestore(); - }); - - describe("warnings when providing options you may not want to", () => { - let spy = spyConsole(); - - it("warns against using `expires` when creating the session", async () => { - createCookieSessionStorage({ - cookie: { - secrets: ["secret1"], - expires: new Date(Date.now() + 60_000), - }, - }); - - expect(spy.console).toHaveBeenCalledTimes(1); - expect(spy.console).toHaveBeenCalledWith( - 'The "__session" cookie has an "expires" property set. This will cause the expires value to not be updated when the session is committed. Instead, you should set the expires value when serializing the cookie. You can use `commitSession(session, { expires })` if using a session storage object, or `cookie.serialize("value", { expires })` if you\'re using the cookie directly.' - ); - }); - - it("warns when not passing secrets when creating the session", async () => { - createCookieSessionStorage({ cookie: {} }); - - expect(spy.console).toHaveBeenCalledTimes(1); - expect(spy.console).toHaveBeenCalledWith( - 'The "__session" cookie is not signed, but session cookies should be signed to prevent tampering on the client before they are sent back to the server. See https://remix.run/utils/cookies#signing-cookies for more information.' - ); - }); - }); - - describe("when a new secret shows up in the rotation", () => { - it("unsigns old session cookies using the old secret and encodes new cookies using the new secret", async () => { - let { getSession, commitSession } = createCookieSessionStorage({ - cookie: { secrets: ["secret1"] }, - }); - let session = await getSession(); - session.set("user", "mjackson"); - let setCookie = await commitSession(session); - session = await getSession(getCookieFromSetCookie(setCookie)); - - expect(session.get("user")).toEqual("mjackson"); - - // A new secret enters the rotation... - let storage = createCookieSessionStorage({ - cookie: { secrets: ["secret2", "secret1"] }, - }); - getSession = storage.getSession; - commitSession = storage.commitSession; - - // Old cookies should still work with the old secret. - session = await storage.getSession(getCookieFromSetCookie(setCookie)); - expect(session.get("user")).toEqual("mjackson"); - - // New cookies should be signed using the new secret. - let setCookie2 = await storage.commitSession(session); - expect(setCookie2).not.toEqual(setCookie); - }); - }); -}); - -describe("Custom cookie-backed session storage", () => { - let memoryBacking = {}; - let createCookieBackedSessionStorage = - createSessionStorageFactory(createCookie); - let implementation = { - createData(data) { - let id = Math.random().toString(36).substring(2, 10); - memoryBacking[id] = data; - return Promise.resolve(id); - }, - readData(id) { - return Promise.resolve(memoryBacking[id] || null); - }, - updateData(id, data) { - memoryBacking[id] = data; - return Promise.resolve(); - }, - deleteData(id) { - memoryBacking[id] = null; - return Promise.resolve(memoryBacking[id]); - }, - }; - - it("persists session data across requests", async () => { - let { getSession, commitSession } = createCookieBackedSessionStorage({ - ...implementation, - cookie: createCookie("test", { secrets: ["test"] }), - }); - let session = await getSession(); - session.set("user", "mjackson"); - let setCookie = await commitSession(session); - session = await getSession(getCookieFromSetCookie(setCookie)); - - expect(session.get("user")).toEqual("mjackson"); - }); - - it("returns an empty session for cookies that are not signed properly", async () => { - let { getSession, commitSession } = createCookieBackedSessionStorage({ - ...implementation, - cookie: createCookie("test", { secrets: ["test"] }), - }); - let session = await getSession(); - session.set("user", "mjackson"); - - expect(session.get("user")).toEqual("mjackson"); - - let setCookie = await commitSession(session); - session = await getSession( - // Tamper with the session cookie... - getCookieFromSetCookie(setCookie).slice(0, -1) - ); - - expect(session.get("user")).toBeUndefined(); - }); - - it('"makes the default path of cookies to be /', async () => { - let { getSession, commitSession } = createCookieBackedSessionStorage({ - ...implementation, - cookie: createCookie("test", { secrets: ["test"] }), - }); - let session = await getSession(); - session.set("user", "mjackson"); - let setCookie = await commitSession(session); - expect(setCookie).toContain("Path=/"); - }); - - it("destroys sessions using a past date", async () => { - let spy = jest.spyOn(console, "warn").mockImplementation(() => {}); - let { getSession, destroySession } = createCookieBackedSessionStorage({ - ...implementation, - cookie: createCookie("test", { secrets: ["test"] }), - }); - let session = await getSession(); - let setCookie = await destroySession(session); - expect(setCookie).toMatchInlineSnapshot( - `"test=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax"` - ); - spy.mockRestore(); - }); - - it("destroys sessions that leverage maxAge", async () => { - let spy = jest.spyOn(console, "warn").mockImplementation(() => {}); - let { getSession, destroySession } = createCookieBackedSessionStorage({ - ...implementation, - cookie: createCookie("test", { - maxAge: 60 * 60, // 1 hour - secrets: ["test"], - }), - }); - let session = await getSession(); - let setCookie = await destroySession(session); - expect(setCookie).toMatchInlineSnapshot( - `"test=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax"` - ); - spy.mockRestore(); - }); -}); - -function spyConsole() { - // https://github.com/facebook/react/issues/7047 - let spy: any = {}; - - beforeAll(() => { - spy.console = jest.spyOn(console, "warn").mockImplementation(() => {}); - }); - - beforeEach(() => { - spy.console.mockClear(); - }); - - afterAll(() => { - spy.console.mockRestore(); - }); - - return spy; -} diff --git a/packages/remix-server-runtime/__tests__/setup.ts b/packages/remix-server-runtime/__tests__/setup.ts deleted file mode 100644 index 2752bf1a72d..00000000000 --- a/packages/remix-server-runtime/__tests__/setup.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { installGlobals } from "@remix-run/node"; - -installGlobals({ nativeFetch: true }); diff --git a/packages/remix-server-runtime/__tests__/utils.ts b/packages/remix-server-runtime/__tests__/utils.ts deleted file mode 100644 index dccade4a4f3..00000000000 --- a/packages/remix-server-runtime/__tests__/utils.ts +++ /dev/null @@ -1,109 +0,0 @@ -import prettier from "prettier"; - -import type { - ActionFunction, - HandleErrorFunction, - HeadersFunction, - LoaderFunction, -} from "../"; -import type { FutureConfig } from "../entry"; -import type { EntryRoute, ServerRoute, ServerRouteManifest } from "../routes"; - -export function mockServerBuild( - routes: Record< - string, - { - parentId?: string; - index?: true; - path?: string; - default?: any; - ErrorBoundary?: any; - action?: ActionFunction; - headers?: HeadersFunction; - loader?: LoaderFunction; - } - >, - opts: { - future?: Partial; - handleError?: HandleErrorFunction; - } = {} -) { - return { - future: { - ...opts.future, - }, - assets: { - entry: { - imports: [""], - module: "", - }, - routes: Object.entries(routes).reduce((p, [id, config]) => { - let route: EntryRoute = { - hasAction: !!config.action, - hasErrorBoundary: !!config.ErrorBoundary, - hasLoader: !!config.loader, - id, - module: "", - index: config.index, - path: config.path, - parentId: config.parentId, - }; - return { - ...p, - [id]: route, - }; - }, {}), - url: "", - version: "", - }, - entry: { - module: { - default: jest.fn( - async ( - request, - responseStatusCode, - responseHeaders, - entryContext, - loadContext - ) => - new Response(null, { - status: responseStatusCode, - headers: responseHeaders, - }) - ), - handleDataRequest: jest.fn(async (response) => response), - handleError: opts.handleError, - }, - }, - routes: Object.entries(routes).reduce( - (p, [id, config]) => { - let route: Omit = { - id, - index: config.index, - path: config.path, - parentId: config.parentId, - module: { - default: config.default, - ErrorBoundary: config.ErrorBoundary, - action: config.action, - headers: config.headers, - loader: config.loader, - }, - }; - return { - ...p, - [id]: route, - }; - }, - {} - ), - }; -} - -export function prettyHtml(source: string): string { - return prettier.format(source, { parser: "html" }); -} - -export function isEqual( - arg: A extends B ? (B extends A ? true : false) : false -): void {} diff --git a/packages/remix-server-runtime/build.ts b/packages/remix-server-runtime/build.ts deleted file mode 100644 index 859e306e3a3..00000000000 --- a/packages/remix-server-runtime/build.ts +++ /dev/null @@ -1,58 +0,0 @@ -import type { ActionFunctionArgs, LoaderFunctionArgs } from "./routeModules"; -import type { AssetsManifest, EntryContext, FutureConfig } from "./entry"; -import type { ServerRouteManifest } from "./routes"; -import type { AppLoadContext } from "./data"; - -// NOTE: IF you modify `ServerBuild`, be sure to modify the -// `remix-dev/server-build.ts` file to reflect the new field as well - -/** - * The output of the compiler for the server build. - */ -export interface ServerBuild { - // v3 TODO: - // - Deprecate when we deprecate the old compiler - // - Remove in v3 - mode: string; - entry: { - module: ServerEntryModule; - }; - routes: ServerRouteManifest; - assets: AssetsManifest; - basename?: string; - publicPath: string; - assetsBuildDirectory: string; - future: FutureConfig; - isSpaMode: boolean; -} - -export interface HandleDocumentRequestFunction { - ( - request: Request, - responseStatusCode: number, - responseHeaders: Headers, - context: EntryContext, - loadContext: AppLoadContext - ): Promise | Response; -} - -export interface HandleDataRequestFunction { - (response: Response, args: LoaderFunctionArgs | ActionFunctionArgs): - | Promise - | Response; -} - -export interface HandleErrorFunction { - (error: unknown, args: LoaderFunctionArgs | ActionFunctionArgs): void; -} - -/** - * A module that serves as the entry point for a Remix app during server - * rendering. - */ -export interface ServerEntryModule { - default: HandleDocumentRequestFunction; - handleDataRequest?: HandleDataRequestFunction; - handleError?: HandleErrorFunction; - streamTimeout?: number; -} diff --git a/packages/remix-server-runtime/cookies.ts b/packages/remix-server-runtime/cookies.ts deleted file mode 100644 index 80884fa8fc2..00000000000 --- a/packages/remix-server-runtime/cookies.ts +++ /dev/null @@ -1,261 +0,0 @@ -import type { CookieParseOptions, CookieSerializeOptions } from "cookie"; -import { parse, serialize } from "cookie"; - -import type { SignFunction, UnsignFunction } from "./crypto"; -import { warnOnce } from "./warnings"; - -export type { CookieParseOptions, CookieSerializeOptions }; - -export interface CookieSignatureOptions { - /** - * An array of secrets that may be used to sign/unsign the value of a cookie. - * - * The array makes it easy to rotate secrets. New secrets should be added to - * the beginning of the array. `cookie.serialize()` will always use the first - * value in the array, but `cookie.parse()` may use any of them so that - * cookies that were signed with older secrets still work. - */ - secrets?: string[]; -} - -export type CookieOptions = CookieParseOptions & - CookieSerializeOptions & - CookieSignatureOptions; - -/** - * A HTTP cookie. - * - * A Cookie is a logical container for metadata about a HTTP cookie; its name - * and options. But it doesn't contain a value. Instead, it has `parse()` and - * `serialize()` methods that allow a single instance to be reused for - * parsing/encoding multiple different values. - * - * @see https://remix.run/utils/cookies#cookie-api - */ -export interface Cookie { - /** - * The name of the cookie, used in the `Cookie` and `Set-Cookie` headers. - */ - readonly name: string; - - /** - * True if this cookie uses one or more secrets for verification. - */ - readonly isSigned: boolean; - - /** - * The Date this cookie expires. - * - * Note: This is calculated at access time using `maxAge` when no `expires` - * option is provided to `createCookie()`. - */ - readonly expires?: Date; - - /** - * Parses a raw `Cookie` header and returns the value of this cookie or - * `null` if it's not present. - */ - parse( - cookieHeader: string | null, - options?: CookieParseOptions - ): Promise; - - /** - * Serializes the given value to a string and returns the `Set-Cookie` - * header. - */ - serialize(value: any, options?: CookieSerializeOptions): Promise; -} - -export type CreateCookieFunction = ( - name: string, - cookieOptions?: CookieOptions -) => Cookie; - -/** - * Creates a logical container for managing a browser cookie from the server. - * - * @see https://remix.run/utils/cookies#createcookie - */ -export const createCookieFactory = - ({ - sign, - unsign, - }: { - sign: SignFunction; - unsign: UnsignFunction; - }): CreateCookieFunction => - (name, cookieOptions = {}) => { - let { secrets = [], ...options } = { - path: "/", - sameSite: "lax" as const, - ...cookieOptions, - }; - - warnOnceAboutExpiresCookie(name, options.expires); - - return { - get name() { - return name; - }, - get isSigned() { - return secrets.length > 0; - }, - get expires() { - // Max-Age takes precedence over Expires - return typeof options.maxAge !== "undefined" - ? new Date(Date.now() + options.maxAge * 1000) - : options.expires; - }, - async parse(cookieHeader, parseOptions) { - if (!cookieHeader) return null; - let cookies = parse(cookieHeader, { ...options, ...parseOptions }); - return name in cookies - ? cookies[name] === "" - ? "" - : await decodeCookieValue(unsign, cookies[name], secrets) - : null; - }, - async serialize(value, serializeOptions) { - return serialize( - name, - value === "" ? "" : await encodeCookieValue(sign, value, secrets), - { - ...options, - ...serializeOptions, - } - ); - }, - }; - }; - -export type IsCookieFunction = (object: any) => object is Cookie; - -/** - * Returns true if an object is a Remix cookie container. - * - * @see https://remix.run/utils/cookies#iscookie - */ -export const isCookie: IsCookieFunction = (object): object is Cookie => { - return ( - object != null && - typeof object.name === "string" && - typeof object.isSigned === "boolean" && - typeof object.parse === "function" && - typeof object.serialize === "function" - ); -}; - -async function encodeCookieValue( - sign: SignFunction, - value: any, - secrets: string[] -): Promise { - let encoded = encodeData(value); - - if (secrets.length > 0) { - encoded = await sign(encoded, secrets[0]); - } - - return encoded; -} - -async function decodeCookieValue( - unsign: UnsignFunction, - value: string, - secrets: string[] -): Promise { - if (secrets.length > 0) { - for (let secret of secrets) { - let unsignedValue = await unsign(value, secret); - if (unsignedValue !== false) { - return decodeData(unsignedValue); - } - } - - return null; - } - - return decodeData(value); -} - -function encodeData(value: any): string { - return btoa(myUnescape(encodeURIComponent(JSON.stringify(value)))); -} - -function decodeData(value: string): any { - try { - return JSON.parse(decodeURIComponent(myEscape(atob(value)))); - } catch (error: unknown) { - return {}; - } -} - -// See: https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.escape.js -function myEscape(value: string): string { - let str = value.toString(); - let result = ""; - let index = 0; - let chr, code; - while (index < str.length) { - chr = str.charAt(index++); - if (/[\w*+\-./@]/.exec(chr)) { - result += chr; - } else { - code = chr.charCodeAt(0); - if (code < 256) { - result += "%" + hex(code, 2); - } else { - result += "%u" + hex(code, 4).toUpperCase(); - } - } - } - return result; -} - -function hex(code: number, length: number): string { - let result = code.toString(16); - while (result.length < length) result = "0" + result; - return result; -} - -// See: https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.unescape.js -function myUnescape(value: string): string { - let str = value.toString(); - let result = ""; - let index = 0; - let chr, part; - while (index < str.length) { - chr = str.charAt(index++); - if (chr === "%") { - if (str.charAt(index) === "u") { - part = str.slice(index + 1, index + 5); - if (/^[\da-f]{4}$/i.exec(part)) { - result += String.fromCharCode(parseInt(part, 16)); - index += 5; - continue; - } - } else { - part = str.slice(index, index + 2); - if (/^[\da-f]{2}$/i.exec(part)) { - result += String.fromCharCode(parseInt(part, 16)); - index += 2; - continue; - } - } - } - result += chr; - } - return result; -} - -function warnOnceAboutExpiresCookie(name: string, expires?: Date) { - warnOnce( - !expires, - `The "${name}" cookie has an "expires" property set. ` + - `This will cause the expires value to not be updated when the session is committed. ` + - `Instead, you should set the expires value when serializing the cookie. ` + - `You can use \`commitSession(session, { expires })\` if using a session storage object, ` + - `or \`cookie.serialize("value", { expires })\` if you're using the cookie directly.` - ); -} diff --git a/packages/remix-server-runtime/crypto.ts b/packages/remix-server-runtime/crypto.ts deleted file mode 100644 index daedea742bf..00000000000 --- a/packages/remix-server-runtime/crypto.ts +++ /dev/null @@ -1,64 +0,0 @@ -export type SignFunction = (value: string, secret: string) => Promise; - -export type UnsignFunction = ( - cookie: string, - secret: string -) => Promise; - -// TODO: Once Node v19 is supported we should use the globally provided -// Web Crypto API's and re-enable this code-path in "./cookies.ts" -// instead of referencing the `sign` and `unsign` globals. - -// const encoder = new TextEncoder(); - -// export const sign: SignFunction = async ( -// value: string, -// secret: string -// ): Promise => { -// let data = encoder.encode(value); -// let key = await createKey(secret, ["sign"]); -// let signature = await crypto.subtle.sign("HMAC", key, data); -// let hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace( -// /=+$/, -// "" -// ); - -// return value + "." + hash; -// }; - -// export const unsign: UnsignFunction = async ( -// cookie: string, -// secret: string -// ): Promise => { -// let value = cookie.slice(0, cookie.lastIndexOf(".")); -// let hash = cookie.slice(cookie.lastIndexOf(".") + 1); - -// let data = encoder.encode(value); -// let key = await createKey(secret, ["verify"]); -// let signature = byteStringToUint8Array(atob(hash)); -// let valid = await crypto.subtle.verify("HMAC", key, signature, data); - -// return valid ? value : false; -// }; - -// const createKey = async ( -// secret: string, -// usages: CryptoKey["usages"] -// ): Promise => -// crypto.subtle.importKey( -// "raw", -// encoder.encode(secret), -// { name: "HMAC", hash: "SHA-256" }, -// false, -// usages -// ); - -// const byteStringToUint8Array = (byteString: string): Uint8Array => { -// let array = new Uint8Array(byteString.length); - -// for (let i = 0; i < byteString.length; i++) { -// array[i] = byteString.charCodeAt(i); -// } - -// return array; -// }; diff --git a/packages/remix-server-runtime/data.ts b/packages/remix-server-runtime/data.ts deleted file mode 100644 index afdda2ac145..00000000000 --- a/packages/remix-server-runtime/data.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { - redirect, - json, - isDeferredData, - isResponse, - isRedirectStatusCode, -} from "./responses"; -import type { - ActionFunction, - ActionFunctionArgs, - LoaderFunction, - LoaderFunctionArgs, -} from "./routeModules"; - -/** - * An object of unknown type for route loaders and actions provided by the - * server's `getLoadContext()` function. This is defined as an empty interface - * specifically so apps can leverage declaration merging to augment this type - * globally: https://www.typescriptlang.org/docs/handbook/declaration-merging.html - */ -export interface AppLoadContext { - [key: string]: unknown; -} - -/** - * Data for a route that was returned from a `loader()`. - */ -export type AppData = unknown; - -export async function callRouteAction({ - loadContext, - action, - params, - request, - routeId, - singleFetch, -}: { - request: Request; - action: ActionFunction; - params: ActionFunctionArgs["params"]; - loadContext: AppLoadContext; - routeId: string; - singleFetch: boolean; -}) { - let result = await action({ - request: singleFetch - ? stripRoutesParam(stripIndexParam(request)) - : stripDataParam(stripIndexParam(request)), - context: loadContext, - params, - }); - - if (result === undefined) { - throw new Error( - `You defined an action for route "${routeId}" but didn't return ` + - `anything from your \`action\` function. Please return a value or \`null\`.` - ); - } - - // Allow naked object returns when single fetch is enabled - if (singleFetch) { - return result; - } - - return isResponse(result) ? result : json(result); -} - -export async function callRouteLoader({ - loadContext, - loader, - params, - request, - routeId, - singleFetch, -}: { - request: Request; - loader: LoaderFunction; - params: LoaderFunctionArgs["params"]; - loadContext: AppLoadContext; - routeId: string; - singleFetch: boolean; -}) { - let result = await loader({ - request: singleFetch - ? stripRoutesParam(stripIndexParam(request)) - : stripDataParam(stripIndexParam(request)), - context: loadContext, - params, - }); - - if (result === undefined) { - throw new Error( - `You defined a loader for route "${routeId}" but didn't return ` + - `anything from your \`loader\` function. Please return a value or \`null\`.` - ); - } - - if (isDeferredData(result)) { - if (result.init && isRedirectStatusCode(result.init.status || 200)) { - return redirect( - new Headers(result.init.headers).get("Location")!, - result.init - ); - } - return result; - } - - // Allow naked object returns when single fetch is enabled - if (singleFetch) { - return result; - } - - return isResponse(result) ? result : json(result); -} - -// TODO: Document these search params better -// and stop stripping these in V2. These break -// support for running in a SW and also expose -// valuable info to data funcs that is being asked -// for such as "is this a data request?". -function stripIndexParam(request: Request) { - let url = new URL(request.url); - let indexValues = url.searchParams.getAll("index"); - url.searchParams.delete("index"); - let indexValuesToKeep = []; - for (let indexValue of indexValues) { - if (indexValue) { - indexValuesToKeep.push(indexValue); - } - } - for (let toKeep of indexValuesToKeep) { - url.searchParams.append("index", toKeep); - } - - let init: RequestInit = { - method: request.method, - body: request.body, - headers: request.headers, - signal: request.signal, - }; - - if (init.body) { - (init as { duplex: "half" }).duplex = "half"; - } - - return new Request(url.href, init); -} - -function stripDataParam(request: Request) { - let url = new URL(request.url); - url.searchParams.delete("_data"); - let init: RequestInit = { - method: request.method, - body: request.body, - headers: request.headers, - signal: request.signal, - }; - - if (init.body) { - (init as { duplex: "half" }).duplex = "half"; - } - - return new Request(url.href, init); -} - -function stripRoutesParam(request: Request) { - let url = new URL(request.url); - url.searchParams.delete("_routes"); - let init: RequestInit = { - method: request.method, - body: request.body, - headers: request.headers, - signal: request.signal, - }; - - if (init.body) { - (init as { duplex: "half" }).duplex = "half"; - } - - return new Request(url.href, init); -} diff --git a/packages/remix-server-runtime/deprecations.ts b/packages/remix-server-runtime/deprecations.ts deleted file mode 100644 index 1ccf4d384a2..00000000000 --- a/packages/remix-server-runtime/deprecations.ts +++ /dev/null @@ -1,13 +0,0 @@ -export function resourceRouteJsonWarning( - type: "loader" | "action", - routeId: string -) { - return ( - "⚠️ REMIX FUTURE CHANGE: Externally-accessed resource routes will no longer be " + - "able to return raw JavaScript objects or `null` in React Router v7 when " + - "Single Fetch becomes the default. You can prepare for this change at your " + - `convenience by wrapping the data returned from your \`${type}\` function in ` + - `the \`${routeId}\` route with \`json()\`. For instructions on making this ` + - "change, see https://remix.run/docs/en/v2.13.1/guides/single-fetch#resource-routes" - ); -} diff --git a/packages/remix-server-runtime/dev.ts b/packages/remix-server-runtime/dev.ts deleted file mode 100644 index 712389a1c1f..00000000000 --- a/packages/remix-server-runtime/dev.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { ServerBuild } from "./build"; - -export async function broadcastDevReady(build: ServerBuild, origin?: string) { - origin ??= process.env.REMIX_DEV_ORIGIN; - if (!origin) throw Error("Dev server origin not set"); - let url = new URL(origin); - url.pathname = "ping"; - - let response = await fetch(url.href, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ buildHash: build.assets.version }), - }).catch((error) => { - console.error(`Could not reach Remix dev server at ${url}`); - throw error; - }); - if (!response.ok) { - console.error( - `Could not reach Remix dev server at ${url} (${response.status})` - ); - throw Error(await response.text()); - } -} - -export function logDevReady(build: ServerBuild) { - console.log(`[REMIX DEV] ${build.assets.version} ready`); -} - -type DevServerHooks = { - getCriticalCss?: ( - build: ServerBuild, - pathname: string - ) => Promise; - processRequestError?: (error: unknown) => void; -}; - -const globalDevServerHooksKey = "__remix_devServerHooks"; - -export function setDevServerHooks(devServerHooks: DevServerHooks) { - // @ts-expect-error - globalThis[globalDevServerHooksKey] = devServerHooks; -} - -export function getDevServerHooks(): DevServerHooks | undefined { - // @ts-expect-error - return globalThis[globalDevServerHooksKey]; -} diff --git a/packages/remix-server-runtime/entry.ts b/packages/remix-server-runtime/entry.ts deleted file mode 100644 index 8283e720d56..00000000000 --- a/packages/remix-server-runtime/entry.ts +++ /dev/null @@ -1,58 +0,0 @@ -import type { StaticHandlerContext } from "@remix-run/router"; - -import type { SerializedError } from "./errors"; -import type { RouteManifest, ServerRouteManifest, EntryRoute } from "./routes"; -import type { RouteModules, EntryRouteModule } from "./routeModules"; - -export interface EntryContext { - manifest: AssetsManifest; - routeModules: RouteModules; - criticalCss?: string; - serverHandoffString?: string; - serverHandoffStream?: ReadableStream; - renderMeta?: { - didRenderScripts?: boolean; - streamCache?: Record< - number, - Promise & { - result?: { - done: boolean; - value: string; - }; - error?: unknown; - } - >; - }; - staticHandlerContext: StaticHandlerContext; - future: FutureConfig; - isSpaMode: boolean; - serializeError(error: Error): SerializedError; -} - -export interface FutureConfig { - v3_fetcherPersist: boolean; - v3_relativeSplatPath: boolean; - v3_throwAbortReason: boolean; - v3_lazyRouteDiscovery: boolean; - v3_singleFetch: boolean; -} - -export interface AssetsManifest { - entry: { - imports: string[]; - module: string; - }; - routes: RouteManifest; - url: string; - version: string; - hmrRuntime?: string; -} - -export function createEntryRouteModules( - manifest: ServerRouteManifest -): RouteModules { - return Object.keys(manifest).reduce((memo, routeId) => { - memo[routeId] = manifest[routeId].module; - return memo; - }, {} as RouteModules); -} diff --git a/packages/remix-server-runtime/errors.ts b/packages/remix-server-runtime/errors.ts deleted file mode 100644 index 8e0934e3fde..00000000000 --- a/packages/remix-server-runtime/errors.ts +++ /dev/null @@ -1,117 +0,0 @@ -import type { StaticHandlerContext } from "@remix-run/router"; -import { isRouteErrorResponse } from "@remix-run/router"; - -import { ServerMode } from "./mode"; - -/** - * This thing probably warrants some explanation. - * - * The whole point here is to emulate componentDidCatch for server rendering and - * data loading. It can get tricky. React can do this on component boundaries - * but doesn't support it for server rendering or data loading. We know enough - * with nested routes to be able to emulate the behavior (because we know them - * statically before rendering.) - * - * Each route can export an `ErrorBoundary`. - * - * - When rendering throws an error, the nearest error boundary will render - * (normal react componentDidCatch). This will be the route's own boundary, but - * if none is provided, it will bubble up to the parents. - * - When data loading throws an error, the nearest error boundary will render - * - When performing an action, the nearest error boundary for the action's - * route tree will render (no redirect happens) - * - * During normal react rendering, we do nothing special, just normal - * componentDidCatch. - * - * For server rendering, we mutate `renderBoundaryRouteId` to know the last - * layout that has an error boundary that tried to render. This emulates which - * layout would catch a thrown error. If the rendering fails, we catch the error - * on the server, and go again a second time with the emulator holding on to the - * information it needs to render the same error boundary as a dynamically - * thrown render error. - * - * When data loading, server or client side, we use the emulator to likewise - * hang on to the error and re-render at the appropriate layout (where a thrown - * error would have been caught by cDC). - * - * When actions throw, it all works the same. There's an edge case to be aware - * of though. Actions normally are required to redirect, but in the case of - * errors, we render the action's route with the emulator holding on to the - * error. If during this render a parent route/loader throws we ignore that new - * error and render the action's original error as deeply as possible. In other - * words, we simply ignore the new error and use the action's error in place - * because it came first, and that just wouldn't be fair to let errors cut in - * line. - */ - -export function sanitizeError(error: T, serverMode: ServerMode) { - if (error instanceof Error && serverMode !== ServerMode.Development) { - let sanitized = new Error("Unexpected Server Error"); - sanitized.stack = undefined; - return sanitized; - } - return error; -} - -export function sanitizeErrors( - errors: NonNullable, - serverMode: ServerMode -) { - return Object.entries(errors).reduce((acc, [routeId, error]) => { - return Object.assign(acc, { [routeId]: sanitizeError(error, serverMode) }); - }, {}); -} - -// must be type alias due to inference issues on interfaces -// https://github.com/microsoft/TypeScript/issues/15300 -export type SerializedError = { - message: string; - stack?: string; -}; - -export function serializeError( - error: Error, - serverMode: ServerMode -): SerializedError { - let sanitized = sanitizeError(error, serverMode); - return { - message: sanitized.message, - stack: sanitized.stack, - }; -} - -export function serializeErrors( - errors: StaticHandlerContext["errors"], - serverMode: ServerMode -): StaticHandlerContext["errors"] { - if (!errors) return null; - let entries = Object.entries(errors); - let serialized: StaticHandlerContext["errors"] = {}; - for (let [key, val] of entries) { - // Hey you! If you change this, please change the corresponding logic in - // deserializeErrors in remix-react/errors.ts :) - if (isRouteErrorResponse(val)) { - serialized[key] = { ...val, __type: "RouteErrorResponse" }; - } else if (val instanceof Error) { - let sanitized = sanitizeError(val, serverMode); - serialized[key] = { - message: sanitized.message, - stack: sanitized.stack, - __type: "Error", - // If this is a subclass (i.e., ReferenceError), send up the type so we - // can re-create the same type during hydration. This will only apply - // in dev mode since all production errors are sanitized to normal - // Error instances - ...(sanitized.name !== "Error" - ? { - __subType: sanitized.name, - } - : {}), - }; - } else { - serialized[key] = val; - } - } - return serialized; -} diff --git a/packages/remix-server-runtime/formData.ts b/packages/remix-server-runtime/formData.ts deleted file mode 100644 index 710cec273d2..00000000000 --- a/packages/remix-server-runtime/formData.ts +++ /dev/null @@ -1,67 +0,0 @@ -// @ts-ignore -import { streamMultipart } from "@web3-storage/multipart-parser"; - -export type UploadHandlerPart = { - name: string; - filename?: string; - contentType: string; - data: AsyncIterable; -}; - -export type UploadHandler = ( - part: UploadHandlerPart -) => Promise; - -export function composeUploadHandlers( - ...handlers: UploadHandler[] -): UploadHandler { - return async (part) => { - for (let handler of handlers) { - let value = await handler(part); - if (typeof value !== "undefined" && value !== null) { - return value; - } - } - - return undefined; - }; -} - -/** - * Allows you to handle multipart forms (file uploads) for your app. - * - * TODO: Update this comment - * @see https://remix.run/utils/parse-multipart-form-data - */ -export async function parseMultipartFormData( - request: Request, - uploadHandler: UploadHandler -): Promise { - let contentType = request.headers.get("Content-Type") || ""; - let [type, boundary] = contentType.split(/\s*;\s*boundary=/); - - if (!request.body || !boundary || type !== "multipart/form-data") { - throw new TypeError("Could not parse content as FormData."); - } - - let formData = new FormData(); - let parts: AsyncIterable = - streamMultipart(request.body, boundary); - - for await (let part of parts) { - if (part.done) break; - - if (typeof part.filename === "string") { - // only pass basename as the multipart/form-data spec recommends - // https://datatracker.ietf.org/doc/html/rfc7578#section-4.2 - part.filename = part.filename.split(/[/\\]/).pop(); - } - - let value = await uploadHandler(part); - if (typeof value !== "undefined" && value !== null) { - formData.append(part.name, value as any); - } - } - - return formData; -} diff --git a/packages/remix-server-runtime/future.ts b/packages/remix-server-runtime/future.ts deleted file mode 100644 index 3dd46a2bce1..00000000000 --- a/packages/remix-server-runtime/future.ts +++ /dev/null @@ -1 +0,0 @@ -export interface Future {} diff --git a/packages/remix-server-runtime/headers.ts b/packages/remix-server-runtime/headers.ts deleted file mode 100644 index 99d1fe014b7..00000000000 --- a/packages/remix-server-runtime/headers.ts +++ /dev/null @@ -1,103 +0,0 @@ -import type { StaticHandlerContext } from "@remix-run/router"; -import { splitCookiesString } from "set-cookie-parser"; - -import type { ServerBuild } from "./build"; - -export function getDocumentHeaders( - build: ServerBuild, - context: StaticHandlerContext -): Headers { - let boundaryIdx = context.errors - ? context.matches.findIndex((m) => context.errors![m.route.id]) - : -1; - let matches = - boundaryIdx >= 0 - ? context.matches.slice(0, boundaryIdx + 1) - : context.matches; - - let errorHeaders: Headers | undefined; - - if (boundaryIdx >= 0) { - // Look for any errorHeaders from the boundary route down, which can be - // identified by the presence of headers but no data - let { actionHeaders, actionData, loaderHeaders, loaderData } = context; - context.matches.slice(boundaryIdx).some((match) => { - let id = match.route.id; - if (actionHeaders[id] && (!actionData || actionData[id] === undefined)) { - errorHeaders = actionHeaders[id]; - } else if (loaderHeaders[id] && loaderData[id] === undefined) { - errorHeaders = loaderHeaders[id]; - } - return errorHeaders != null; - }); - } - - return matches.reduce((parentHeaders, match, idx) => { - let { id } = match.route; - let routeModule = build.routes[id].module; - let loaderHeaders = context.loaderHeaders[id] || new Headers(); - let actionHeaders = context.actionHeaders[id] || new Headers(); - - // Only expose errorHeaders to the leaf headers() function to - // avoid duplication via parentHeaders - let includeErrorHeaders = - errorHeaders != undefined && idx === matches.length - 1; - // Only prepend cookies from errorHeaders at the leaf renderable route - // when it's not the same as loaderHeaders/actionHeaders to avoid - // duplicate cookies - let includeErrorCookies = - includeErrorHeaders && - errorHeaders !== loaderHeaders && - errorHeaders !== actionHeaders; - - // Use the parent headers for any route without a `headers` export - if (routeModule.headers == null) { - let headers = new Headers(parentHeaders); - if (includeErrorCookies) { - prependCookies(errorHeaders!, headers); - } - prependCookies(actionHeaders, headers); - prependCookies(loaderHeaders, headers); - return headers; - } - - let headers = new Headers( - routeModule.headers - ? typeof routeModule.headers === "function" - ? routeModule.headers({ - loaderHeaders, - parentHeaders, - actionHeaders, - errorHeaders: includeErrorHeaders ? errorHeaders : undefined, - }) - : routeModule.headers - : undefined - ); - - // Automatically preserve Set-Cookie headers from bubbled responses, - // loaders, errors, and parent routes - if (includeErrorCookies) { - prependCookies(errorHeaders!, headers); - } - prependCookies(actionHeaders, headers); - prependCookies(loaderHeaders, headers); - prependCookies(parentHeaders, headers); - - return headers; - }, new Headers()); -} - -function prependCookies(parentHeaders: Headers, childHeaders: Headers): void { - let parentSetCookieString = parentHeaders.get("Set-Cookie"); - - if (parentSetCookieString) { - let cookies = splitCookiesString(parentSetCookieString); - // @ts-expect-error This is not available in the polyfill or Node 18 and below - let childCookies = new Set(childHeaders.getSetCookie?.()); - cookies.forEach((cookie) => { - if (!childCookies.has(cookie)) { - childHeaders.append("Set-Cookie", cookie); - } - }); - } -} diff --git a/packages/remix-server-runtime/index.ts b/packages/remix-server-runtime/index.ts deleted file mode 100644 index 58ea5e3c6c1..00000000000 --- a/packages/remix-server-runtime/index.ts +++ /dev/null @@ -1,94 +0,0 @@ -// Default implementations for the Remix server runtime interface -export { createCookieFactory, isCookie } from "./cookies"; -export { - composeUploadHandlers as unstable_composeUploadHandlers, - parseMultipartFormData as unstable_parseMultipartFormData, -} from "./formData"; -export { defer, json, redirect, redirectDocument, replace } from "./responses"; - -export { - SingleFetchRedirectSymbol as UNSAFE_SingleFetchRedirectSymbol, - data, -} from "./single-fetch"; -export type { - SingleFetchResult as UNSAFE_SingleFetchResult, - SingleFetchResults as UNSAFE_SingleFetchResults, -} from "./single-fetch"; - -export { createRequestHandler } from "./server"; -export { - createSession, - createSessionStorageFactory, - isSession, -} from "./sessions"; -export { createCookieSessionStorageFactory } from "./sessions/cookieStorage"; -export { createMemorySessionStorageFactory } from "./sessions/memoryStorage"; -export { createMemoryUploadHandler as unstable_createMemoryUploadHandler } from "./upload/memoryUploadHandler"; -export { MaxPartSizeExceededError } from "./upload/errors"; -export { - broadcastDevReady, - logDevReady, - setDevServerHooks as unstable_setDevServerHooks, -} from "./dev"; - -// Types for the Remix server runtime interface -export type { - CreateCookieFunction, - CreateCookieSessionStorageFunction, - CreateMemorySessionStorageFunction, - CreateRequestHandlerFunction, - CreateSessionFunction, - CreateSessionStorageFunction, - IsCookieFunction, - IsSessionFunction, - JsonFunction, - RedirectFunction, -} from "./interface"; - -export type { Future } from "./future"; - -// Remix server runtime packages should re-export these types -export type { - ActionFunction, - ActionFunctionArgs, - AppLoadContext, - Cookie, - CookieOptions, - CookieParseOptions, - CookieSerializeOptions, - CookieSignatureOptions, - DataFunctionArgs, - EntryContext, - ErrorResponse, - FlashSessionData, - HandleDataRequestFunction, - HandleDocumentRequestFunction, - HeadersArgs, - HeadersFunction, - HtmlLinkDescriptor, - LinkDescriptor, - LinksFunction, - LoaderFunction, - LoaderFunctionArgs, - MemoryUploadHandlerFilterArgs, - MemoryUploadHandlerOptions, - HandleErrorFunction, - PageLinkDescriptor, - RequestHandler, - SerializeFrom, - ServerBuild, - ServerEntryModule, - ServerRuntimeMetaArgs, - ServerRuntimeMetaDescriptor, - ServerRuntimeMetaFunction, - Session, - SessionData, - SessionIdStorageStrategy, - SessionStorage, - SignFunction, - TypedDeferredData, - TypedResponse, - UnsignFunction, - UploadHandler, - UploadHandlerPart, -} from "./reexport"; diff --git a/packages/remix-server-runtime/interface.ts b/packages/remix-server-runtime/interface.ts deleted file mode 100644 index be54c937c35..00000000000 --- a/packages/remix-server-runtime/interface.ts +++ /dev/null @@ -1,10 +0,0 @@ -export type { CreateCookieFunction, IsCookieFunction } from "./cookies"; -export type { JsonFunction, RedirectFunction } from "./responses"; -export type { CreateRequestHandlerFunction } from "./server"; -export type { - CreateSessionFunction, - CreateSessionStorageFunction, - IsSessionFunction, -} from "./sessions"; -export type { CreateCookieSessionStorageFunction } from "./sessions/cookieStorage"; -export type { CreateMemorySessionStorageFunction } from "./sessions/memoryStorage"; diff --git a/packages/remix-server-runtime/invariant.ts b/packages/remix-server-runtime/invariant.ts deleted file mode 100644 index 123cc25cb41..00000000000 --- a/packages/remix-server-runtime/invariant.ts +++ /dev/null @@ -1,16 +0,0 @@ -export default function invariant( - value: boolean, - message?: string -): asserts value; -export default function invariant( - value: T | null | undefined, - message?: string -): asserts value is T; -export default function invariant(value: any, message?: string) { - if (value === false || value === null || typeof value === "undefined") { - console.error( - "The following error is a bug in Remix; please open an issue! https://github.com/remix-run/remix/issues/new" - ); - throw new Error(message); - } -} diff --git a/packages/remix-server-runtime/jest.config.js b/packages/remix-server-runtime/jest.config.js deleted file mode 100644 index 92a3431fdc5..00000000000 --- a/packages/remix-server-runtime/jest.config.js +++ /dev/null @@ -1,5 +0,0 @@ -/** @type {import('jest').Config} */ -module.exports = { - ...require("../../jest/jest.config.shared"), - displayName: "server-runtime", -}; diff --git a/packages/remix-server-runtime/jsonify.ts b/packages/remix-server-runtime/jsonify.ts deleted file mode 100644 index 80e524ff573..00000000000 --- a/packages/remix-server-runtime/jsonify.ts +++ /dev/null @@ -1,261 +0,0 @@ -import { - expectType, - type Equal, - type Expect, - type MutualExtends, -} from "./typecheck"; - -// prettier-ignore -// `Jsonify` emulates `let y = JSON.parse(JSON.stringify(x))`, but for types -// so that we can infer the shape of the data sent over the network. -export type Jsonify = - // any - IsAny extends true ? any : - - // toJSON - T extends { toJSON(): infer U } ? (U extends JsonValue ? U : unknown) : - - // primitives - T extends JsonPrimitive ? T : - T extends String ? string : - T extends Number ? number : - T extends Boolean ? boolean : - - // Promises JSON.stringify to an empty object - T extends Promise ? EmptyObject : - - // Map & Set - T extends Map ? EmptyObject : - T extends Set ? EmptyObject : - - // TypedArray - T extends TypedArray ? Record : - - // Not JSON serializable - T extends NotJson ? never : - - // tuple & array - T extends [] ? [] : - T extends readonly [infer F, ...infer R] ? [NeverToNull>, ...Jsonify] : - T extends readonly unknown[] ? Array>>: - - // object - T extends Record ? JsonifyObject : - - // unknown - unknown extends T ? unknown : - - never - -// value is always not JSON => true -// value is always JSON => false -// value is somtimes JSON, sometimes not JSON => boolean -// note: cannot be inlined as logic requires union distribution -type ValueIsNotJson = T extends NotJson ? true : false; - -// note: remove optionality so that produced values are never `undefined`, -// only `true`, `false`, or `boolean` -type IsNotJson = { [K in keyof T]-?: ValueIsNotJson }; - -type JsonifyValues = { [K in keyof T]: Jsonify }; - -// prettier-ignore -type JsonifyObject> = - // required - { [K in keyof T as - unknown extends T[K] ? never : - IsNotJson[K] extends false ? K : - never - ]: JsonifyValues[K] } & - // optional - { [K in keyof T as - unknown extends T[K] ? K : - // if the value is always JSON, then it's not optional - IsNotJson[K] extends false ? never : - // if the value is always not JSON, omit it entirely - IsNotJson[K] extends true ? never : - // if the value is mixed, then it's optional - K - ]? : JsonifyValues[K]} - -// types ------------------------------------------------------------ - -type JsonPrimitive = string | number | boolean | null; - -type JsonArray = JsonValue[] | readonly JsonValue[]; - -// prettier-ignore -type JsonObject = - { [K in string]: JsonValue } & - { [K in string]?: JsonValue } - -type JsonValue = JsonPrimitive | JsonObject | JsonArray; - -type NotJson = undefined | symbol | AnyFunction; - -type TypedArray = - | Int8Array - | Uint8Array - | Uint8ClampedArray - | Int16Array - | Uint16Array - | Int32Array - | Uint32Array - | Float32Array - | Float64Array - | BigInt64Array - | BigUint64Array; - -// tests ------------------------------------------------------------ - -// prettier-ignore -// eslint-disable-next-line @typescript-eslint/no-unused-vars -type _tests = [ - // any - Expect, any>>, - - // primitives - Expect, string>>, - Expect, number>>, - Expect, boolean>>, - Expect, null>>, - Expect, string>>, - Expect, number>>, - Expect, boolean>>, - Expect>, EmptyObject>>, - - // Map & Set - Expect>, EmptyObject>>, - Expect>, EmptyObject>>, - - // TypedArray - Expect, Record>>, - Expect, Record>>, - Expect, Record>>, - Expect, Record>>, - Expect, Record>>, - Expect, Record>>, - Expect, Record>>, - Expect, Record>>, - Expect, Record>>, - Expect, Record>>, - Expect, Record>>, - - // Not Json - Expect, never>>, - Expect, never>>, - Expect void>, never>>, - Expect, never>>, - - // toJson - Expect, "stuff">>, - Expect, string>>, - Expect, unknown>>, - Expect, unknown>>, - Expect, string>>, - - - // tuple & array - Expect, []>>, - Expect, [1, 'two', string, null, false]>>, - Expect, (string | number)[]>>, - Expect, null[]>>, - Expect, [1,2,3]>>, - - // object - Expect>, {}>>, - Expect>, {a: string}>>, - Expect>, {a?: string}>>, - Expect>, {a?: string}>>, - Expect>, {a: string, b?: string}>>, - Expect>, {}>>, - Expect>>, Record>>, - Expect>>, Record>>, - Expect}>, { payload: Record}>>, - Expect any); - optionalFunctionUnion?: string | (() => any); - optionalFunctionUnionUndefined: string | (() => any) | undefined; - - // Should be omitted - requiredFunction: () => any; - optionalFunction?: () => any; - optionalFunctionUndefined: (() => any) | undefined; - }>>, { - requiredString: string - requiredUnion: number | boolean - - optionalString?: string; - optionalUnion?: number | string; - optionalStringUndefined?: string | undefined; - optionalUnionUndefined?: number | string | undefined; - requiredFunctionUnion?: string - optionalFunctionUnion?: string; - optionalFunctionUnionUndefined?: string - }>>, - - // unknown - Expect, unknown>>, - Expect, unknown[]>>, - Expect, [unknown, 1]>>, - Expect>, {a?: unknown}>>, - Expect>, {a?: unknown, b: 'hello'}>>, - - // never - Expect, never>>, - Expect>, {a: never}>>, - Expect>, {a: never, b:string}>>, - Expect>, {a: never, b: string} | {a: string, b: never}>>, - - // class - Expect>, {a: string}>>, -]; - -class MyClass { - a: string; - b: () => string; - - constructor() { - this.a = "hello"; - this.b = () => "world"; - } -} - -// real-world example: `InvoiceLineItem` from `stripe` -type Recursive = { - a: Date; - recur?: Recursive; -}; -declare const recursive: Jsonify; -expectType<{ a: string; recur?: Jsonify }>( - recursive.recur!.recur!.recur! -); - -// real-world example: `Temporal` from `@js-temporal/polyfill` -interface BooleanWithToJson extends Boolean { - toJSON(): string; -} - -// utils ------------------------------------------------------------ - -type Pretty = { [K in keyof T]: T[K] }; - -type AnyFunction = (...args: any[]) => unknown; - -type NeverToNull = [T] extends [never] ? null : T; - -// adapted from https://github.com/sindresorhus/type-fest/blob/main/source/empty-object.d.ts -declare const emptyObjectSymbol: unique symbol; -export type EmptyObject = { [emptyObjectSymbol]?: never }; - -// adapted from https://github.com/type-challenges/type-challenges/blob/main/utils/index.d.ts -type IsAny = 0 extends 1 & T ? true : false; diff --git a/packages/remix-server-runtime/links.ts b/packages/remix-server-runtime/links.ts deleted file mode 100644 index 4cfab9f0f05..00000000000 --- a/packages/remix-server-runtime/links.ts +++ /dev/null @@ -1,192 +0,0 @@ -type Primitive = null | undefined | string | number | boolean | symbol | bigint; - -type LiteralUnion = - | LiteralType - | (BaseType & Record); - -interface HtmlLinkProps { - /** - * Address of the hyperlink - */ - href?: string; - - /** - * How the element handles crossorigin requests - */ - crossOrigin?: "anonymous" | "use-credentials"; - - /** - * Relationship between the document containing the hyperlink and the destination resource - */ - rel: LiteralUnion< - | "alternate" - | "dns-prefetch" - | "icon" - | "manifest" - | "modulepreload" - | "next" - | "pingback" - | "preconnect" - | "prefetch" - | "preload" - | "prerender" - | "search" - | "stylesheet", - string - >; - - /** - * Applicable media: "screen", "print", "(max-width: 764px)" - */ - media?: string; - - /** - * Integrity metadata used in Subresource Integrity checks - */ - integrity?: string; - - /** - * Language of the linked resource - */ - hrefLang?: string; - - /** - * Hint for the type of the referenced resource - */ - type?: string; - - /** - * Referrer policy for fetches initiated by the element - */ - referrerPolicy?: - | "" - | "no-referrer" - | "no-referrer-when-downgrade" - | "same-origin" - | "origin" - | "strict-origin" - | "origin-when-cross-origin" - | "strict-origin-when-cross-origin" - | "unsafe-url"; - - /** - * Sizes of the icons (for rel="icon") - */ - sizes?: string; - - /** - * Potential destination for a preload request (for rel="preload" and rel="modulepreload") - */ - as?: LiteralUnion< - | "audio" - | "audioworklet" - | "document" - | "embed" - | "fetch" - | "font" - | "frame" - | "iframe" - | "image" - | "manifest" - | "object" - | "paintworklet" - | "report" - | "script" - | "serviceworker" - | "sharedworker" - | "style" - | "track" - | "video" - | "worker" - | "xslt", - string - >; - - /** - * Color to use when customizing a site's icon (for rel="mask-icon") - */ - color?: string; - - /** - * Whether the link is disabled - */ - disabled?: boolean; - - /** - * The title attribute has special semantics on this element: Title of the link; CSS style sheet set name. - */ - title?: string; - - /** - * Images to use in different situations, e.g., high-resolution displays, - * small monitors, etc. (for rel="preload") - */ - imageSrcSet?: string; - - /** - * Image sizes for different page layouts (for rel="preload") - */ - imageSizes?: string; -} - -interface HtmlLinkPreloadImage extends HtmlLinkProps { - /** - * Relationship between the document containing the hyperlink and the destination resource - */ - rel: "preload"; - - /** - * Potential destination for a preload request (for rel="preload" and rel="modulepreload") - */ - as: "image"; - - /** - * Address of the hyperlink - */ - href?: string; - - /** - * Images to use in different situations, e.g., high-resolution displays, - * small monitors, etc. (for rel="preload") - */ - imageSrcSet: string; - - /** - * Image sizes for different page layouts (for rel="preload") - */ - imageSizes?: string; -} - -/** - * Represents a `` element. - * - * WHATWG Specification: https://html.spec.whatwg.org/multipage/semantics.html#the-link-element - */ -export type HtmlLinkDescriptor = - // Must have an href *unless* it's a `` with an - // `imageSrcSet` and `imageSizes` props - | (HtmlLinkProps & Pick, "href">) - | (HtmlLinkPreloadImage & Pick, "imageSizes">) - | (HtmlLinkPreloadImage & - Pick, "href"> & { imageSizes?: never }); - -export interface PageLinkDescriptor - extends Omit< - HtmlLinkDescriptor, - | "href" - | "rel" - | "type" - | "sizes" - | "imageSrcSet" - | "imageSizes" - | "as" - | "color" - | "title" - > { - /** - * The absolute path of the page to prefetch. - */ - page: string; -} - -export type LinkDescriptor = HtmlLinkDescriptor | PageLinkDescriptor; diff --git a/packages/remix-server-runtime/markup.ts b/packages/remix-server-runtime/markup.ts deleted file mode 100644 index 4ab1fdcc784..00000000000 --- a/packages/remix-server-runtime/markup.ts +++ /dev/null @@ -1,19 +0,0 @@ -// This escapeHtml utility is based on https://github.com/zertosh/htmlescape -// License: https://github.com/zertosh/htmlescape/blob/0527ca7156a524d256101bb310a9f970f63078ad/LICENSE - -// We've chosen to inline the utility here to reduce the number of npm dependencies we have, -// slightly decrease the code size compared the original package and make it esm compatible. - -const ESCAPE_LOOKUP: { [match: string]: string } = { - "&": "\\u0026", - ">": "\\u003e", - "<": "\\u003c", - "\u2028": "\\u2028", - "\u2029": "\\u2029", -}; - -const ESCAPE_REGEX = /[&><\u2028\u2029]/g; - -export function escapeHtml(html: string) { - return html.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]); -} diff --git a/packages/remix-server-runtime/mode.ts b/packages/remix-server-runtime/mode.ts deleted file mode 100644 index 903aaa3bee8..00000000000 --- a/packages/remix-server-runtime/mode.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * The mode to use when running the server. - */ -export enum ServerMode { - Development = "development", - Production = "production", - Test = "test", -} - -export function isServerMode(value: any): value is ServerMode { - return ( - value === ServerMode.Development || - value === ServerMode.Production || - value === ServerMode.Test - ); -} diff --git a/packages/remix-server-runtime/package.json b/packages/remix-server-runtime/package.json deleted file mode 100644 index 9371bff4faf..00000000000 --- a/packages/remix-server-runtime/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "@remix-run/server-runtime", - "version": "2.16.7", - "description": "Server runtime for Remix", - "bugs": { - "url": "https://github.com/remix-run/remix/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/remix-run/remix", - "directory": "packages/remix-server-runtime" - }, - "license": "MIT", - "sideEffects": false, - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "module": "dist/esm/index.js", - "scripts": { - "tsc": "tsc" - }, - "dependencies": { - "@remix-run/router": "1.23.0", - "@types/cookie": "^0.6.0", - "@web3-storage/multipart-parser": "^1.0.0", - "cookie": "^0.7.2", - "set-cookie-parser": "^2.4.8", - "source-map": "^0.7.3", - "turbo-stream": "2.4.1" - }, - "devDependencies": { - "@types/set-cookie-parser": "^2.4.1", - "typescript": "^5.1.6" - }, - "peerDependencies": { - "typescript": "^5.1.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - }, - "engines": { - "node": ">=18.0.0" - }, - "files": [ - "dist/", - "CHANGELOG.md", - "LICENSE.md", - "README.md" - ] -} diff --git a/packages/remix-server-runtime/reexport.ts b/packages/remix-server-runtime/reexport.ts deleted file mode 100644 index edc81a16615..00000000000 --- a/packages/remix-server-runtime/reexport.ts +++ /dev/null @@ -1,64 +0,0 @@ -export type { ErrorResponse } from "@remix-run/router"; - -export type { - HandleDataRequestFunction, - HandleDocumentRequestFunction, - HandleErrorFunction, - ServerBuild, - ServerEntryModule, -} from "./build"; - -export type { Future } from "./future"; -export type { UploadHandlerPart, UploadHandler } from "./formData"; -export type { - MemoryUploadHandlerOptions, - MemoryUploadHandlerFilterArgs, -} from "./upload/memoryUploadHandler"; - -export type { - Cookie, - CookieOptions, - CookieParseOptions, - CookieSerializeOptions, - CookieSignatureOptions, -} from "./cookies"; - -export type { SignFunction, UnsignFunction } from "./crypto"; - -export type { AppLoadContext } from "./data"; - -export type { EntryContext } from "./entry"; - -export type { - HtmlLinkDescriptor, - LinkDescriptor, - PageLinkDescriptor, -} from "./links"; - -export type { TypedDeferredData, TypedResponse } from "./responses"; - -export type { - ActionFunction, - ActionFunctionArgs, - DataFunctionArgs, - HeadersArgs, - HeadersFunction, - LinksFunction, - LoaderFunction, - LoaderFunctionArgs, - ServerRuntimeMetaArgs, - ServerRuntimeMetaDescriptor, - ServerRuntimeMetaFunction, -} from "./routeModules"; - -export type { SerializeFrom } from "./serialize"; - -export type { RequestHandler } from "./server"; - -export type { - Session, - SessionData, - SessionIdStorageStrategy, - SessionStorage, - FlashSessionData, -} from "./sessions"; diff --git a/packages/remix-server-runtime/responses.ts b/packages/remix-server-runtime/responses.ts deleted file mode 100644 index 2acfaf129a6..00000000000 --- a/packages/remix-server-runtime/responses.ts +++ /dev/null @@ -1,236 +0,0 @@ -import { - defer as routerDefer, - json as routerJson, - redirect as routerRedirect, - replace as routerReplace, - redirectDocument as routerRedirectDocument, - type UNSAFE_DeferredData as DeferredData, - type TrackedPromise, -} from "@remix-run/router"; - -import { serializeError } from "./errors"; -import type { ServerMode } from "./mode"; - -declare const typedDeferredDataBrand: unique symbol; - -export type TypedDeferredData> = Pick< - DeferredData, - "init" -> & { - data: Data; - readonly [typedDeferredDataBrand]: "TypedDeferredData"; -}; - -export type DeferFunction = >( - data: Data, - init?: number | ResponseInit -) => TypedDeferredData; - -export type JsonFunction = ( - data: Data, - init?: number | ResponseInit -) => TypedResponse; - -// must be a type since this is a subtype of response -// interfaces must conform to the types they extend -export type TypedResponse = Omit & { - json(): Promise; -}; - -/** - * This is a shortcut for creating `application/json` responses. Converts `data` - * to JSON and sets the `Content-Type` header. - * - * @deprecated This utility is deprecated in favor of opting into Single Fetch - * via `future.v3_singleFetch` and returning raw objects. This method will be - * removed in React Router v7. - * - * If you need to return custom headers or status code, you can use the new `data` - * utility (https://remix.run/docs/en/main/utils/data). - * - * If you need to return a JSON Response from a resource route, you can use - * `Response.json` (https://developer.mozilla.org/en-US/docs/Web/API/Response/json_static). - * - * @see https://remix.run/utils/json - */ -export const json: JsonFunction = (data, init = {}) => { - return routerJson(data, init); -}; - -/** - * This is a shortcut for creating Remix deferred responses - * - * @deprecated This utility is deprecated in favor of opting into Single Fetch - * via `future.v3_singleFetch` and returning raw objects. This method will be - * removed in React Router v7. - * - * @see https://remix.run/utils/defer - */ -export const defer: DeferFunction = (data, init = {}) => { - return routerDefer(data, init) as unknown as TypedDeferredData; -}; - -export type RedirectFunction = ( - url: string, - init?: number | ResponseInit -) => TypedResponse; - -/** - * A redirect response. Sets the status code and the `Location` header. - * Defaults to "302 Found". - * - * @see https://remix.run/utils/redirect - */ -export const redirect: RedirectFunction = (url, init = 302) => { - return routerRedirect(url, init) as TypedResponse; -}; - -/** - * A redirect response. Sets the status code and the `Location` header. - * Defaults to "302 Found". - * - * @see https://remix.run/utils/redirect - */ -export const replace: RedirectFunction = (url, init = 302) => { - return routerReplace(url, init) as TypedResponse; -}; - -/** - * A redirect response that will force a document reload to the new location. - * Sets the status code and the `Location` header. - * Defaults to "302 Found". - * - * @see https://remix.run/utils/redirect - */ -export const redirectDocument: RedirectFunction = (url, init = 302) => { - return routerRedirectDocument(url, init) as TypedResponse; -}; - -export function isDeferredData(value: any): value is DeferredData { - let deferred: DeferredData = value; - return ( - deferred && - typeof deferred === "object" && - typeof deferred.data === "object" && - typeof deferred.subscribe === "function" && - typeof deferred.cancel === "function" && - typeof deferred.resolveData === "function" - ); -} - -export function isResponse(value: any): value is Response { - return ( - value != null && - typeof value.status === "number" && - typeof value.statusText === "string" && - typeof value.headers === "object" && - typeof value.body !== "undefined" - ); -} - -const redirectStatusCodes = new Set([301, 302, 303, 307, 308]); -export function isRedirectStatusCode(statusCode: number): boolean { - return redirectStatusCodes.has(statusCode); -} -export function isRedirectResponse(response: Response): boolean { - return isRedirectStatusCode(response.status); -} - -function isTrackedPromise(value: any): value is TrackedPromise { - return ( - value != null && typeof value.then === "function" && value._tracked === true - ); -} - -// TODO: Figure out why ReadableStream types are borked sooooooo badly -// in this file. Probably related to our TS configurations and configs -// bleeding into each other. -const DEFERRED_VALUE_PLACEHOLDER_PREFIX = "__deferred_promise:"; -export function createDeferredReadableStream( - deferredData: DeferredData, - signal: AbortSignal, - serverMode: ServerMode -): any { - let encoder = new TextEncoder(); - let stream = new ReadableStream({ - async start(controller: any) { - let criticalData: any = {}; - - let preresolvedKeys: string[] = []; - for (let [key, value] of Object.entries(deferredData.data)) { - if (isTrackedPromise(value)) { - criticalData[key] = `${DEFERRED_VALUE_PLACEHOLDER_PREFIX}${key}`; - if ( - typeof value._data !== "undefined" || - typeof value._error !== "undefined" - ) { - preresolvedKeys.push(key); - } - } else { - criticalData[key] = value; - } - } - - // Send the critical data - controller.enqueue(encoder.encode(JSON.stringify(criticalData) + "\n\n")); - - for (let preresolvedKey of preresolvedKeys) { - enqueueTrackedPromise( - controller, - encoder, - preresolvedKey, - deferredData.data[preresolvedKey] as TrackedPromise, - serverMode - ); - } - - let unsubscribe = deferredData.subscribe((aborted, settledKey) => { - if (settledKey) { - enqueueTrackedPromise( - controller, - encoder, - settledKey, - deferredData.data[settledKey] as TrackedPromise, - serverMode - ); - } - }); - await deferredData.resolveData(signal); - unsubscribe(); - controller.close(); - }, - }); - - return stream; -} - -function enqueueTrackedPromise( - controller: any, - encoder: TextEncoder, - settledKey: string, - promise: TrackedPromise, - serverMode: ServerMode -) { - if ("_error" in promise) { - controller.enqueue( - encoder.encode( - "error:" + - JSON.stringify({ - [settledKey]: - promise._error instanceof Error - ? serializeError(promise._error, serverMode) - : promise._error, - }) + - "\n\n" - ) - ); - } else { - controller.enqueue( - encoder.encode( - "data:" + - JSON.stringify({ [settledKey]: promise._data ?? null }) + - "\n\n" - ) - ); - } -} diff --git a/packages/remix-server-runtime/rollup.config.js b/packages/remix-server-runtime/rollup.config.js deleted file mode 100644 index 66faabb57be..00000000000 --- a/packages/remix-server-runtime/rollup.config.js +++ /dev/null @@ -1,73 +0,0 @@ -/* eslint-disable import/no-nodejs-modules */ -const path = require("node:path"); -const babel = require("@rollup/plugin-babel").default; -const nodeResolve = require("@rollup/plugin-node-resolve").default; -const copy = require("rollup-plugin-copy"); - -const { - getOutputDir, - isBareModuleId, - createBanner, - copyToPlaygrounds, -} = require("../../rollup.utils"); -const { name: packageName, version } = require("./package.json"); - -/** @returns {import("rollup").RollupOptions[]} */ -module.exports = function rollup() { - let sourceDir = "packages/remix-server-runtime"; - let outputDir = getOutputDir(packageName); - let outputDist = path.join(outputDir, "dist"); - - return [ - { - external(id) { - return isBareModuleId(id); - }, - input: `${sourceDir}/index.ts`, - output: { - banner: createBanner(packageName, version), - dir: outputDist, - format: "cjs", - preserveModules: true, - exports: "named", - }, - plugins: [ - babel({ - babelHelpers: "bundled", - exclude: /node_modules/, - extensions: [".ts", ".tsx"], - }), - nodeResolve({ extensions: [".ts", ".tsx"] }), - copy({ - targets: [ - { src: "LICENSE.md", dest: [outputDir, sourceDir] }, - { src: `${sourceDir}/package.json`, dest: outputDir }, - { src: `${sourceDir}/README.md`, dest: outputDir }, - ], - }), - copyToPlaygrounds(), - ], - }, - { - external(id) { - return isBareModuleId(id); - }, - input: `${sourceDir}/index.ts`, - output: { - banner: createBanner(packageName, version), - dir: `${outputDist}/esm`, - format: "esm", - preserveModules: true, - }, - plugins: [ - babel({ - babelHelpers: "bundled", - exclude: /node_modules/, - extensions: [".ts", ".tsx"], - }), - nodeResolve({ extensions: [".ts", ".tsx"] }), - copyToPlaygrounds(), - ], - }, - ]; -}; diff --git a/packages/remix-server-runtime/routeMatching.ts b/packages/remix-server-runtime/routeMatching.ts deleted file mode 100644 index fe8d20a4c3e..00000000000 --- a/packages/remix-server-runtime/routeMatching.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { Params, AgnosticRouteObject } from "@remix-run/router"; -import { matchRoutes } from "@remix-run/router"; - -import type { ServerRoute } from "./routes"; - -export interface RouteMatch { - params: Params; - pathname: string; - route: Route; -} - -export function matchServerRoutes( - routes: ServerRoute[], - pathname: string, - basename?: string -): RouteMatch[] | null { - let matches = matchRoutes( - routes as unknown as AgnosticRouteObject[], - pathname, - basename - ); - if (!matches) return null; - - return matches.map((match) => ({ - params: match.params, - pathname: match.pathname, - route: match.route as unknown as ServerRoute, - })); -} diff --git a/packages/remix-server-runtime/routeModules.ts b/packages/remix-server-runtime/routeModules.ts deleted file mode 100644 index 58e0ce2f7d0..00000000000 --- a/packages/remix-server-runtime/routeModules.ts +++ /dev/null @@ -1,268 +0,0 @@ -import type { - ActionFunction as RRActionFunction, - ActionFunctionArgs as RRActionFunctionArgs, - AgnosticRouteMatch, - LoaderFunction as RRLoaderFunction, - LoaderFunctionArgs as RRLoaderFunctionArgs, - Location, - Params, -} from "@remix-run/router"; - -import type { AppData, AppLoadContext } from "./data"; -import type { LinkDescriptor } from "./links"; -import type { SerializeFrom } from "./serialize"; - -export interface RouteModules { - [routeId: string]: RouteModule | undefined; -} - -/** - * @deprecated Use `LoaderFunctionArgs`/`ActionFunctionArgs` instead - */ -export type DataFunctionArgs = RRActionFunctionArgs & - RRLoaderFunctionArgs & { - // Context is always provided in Remix, and typed for module augmentation support. - // RR also doesn't export DataFunctionArgs, so we extend the two interfaces here - // even tough they're identical under the hood - context: AppLoadContext; - }; - -/** - * A function that handles data mutations for a route on the server - */ -export type ActionFunction = ( - args: ActionFunctionArgs -) => ReturnType; - -/** - * Arguments passed to a route `action` function - */ -export type ActionFunctionArgs = RRActionFunctionArgs & { - // Context is always provided in Remix, and typed for module augmentation support. - context: AppLoadContext; -}; - -/** - * A function that handles data mutations for a route on the client - * @private Public API is exported from @remix-run/react - */ -type ClientActionFunction = ( - args: ClientActionFunctionArgs -) => ReturnType; - -/** - * Arguments passed to a route `clientAction` function - * @private Public API is exported from @remix-run/react - */ -export type ClientActionFunctionArgs = RRActionFunctionArgs & { - serverAction: () => Promise>; -}; - -/** - * A function that loads data for a route on the server - */ -export type LoaderFunction = ( - args: LoaderFunctionArgs -) => ReturnType; - -/** - * Arguments passed to a route `loader` function - */ -export type LoaderFunctionArgs = RRLoaderFunctionArgs & { - // Context is always provided in Remix, and typed for module augmentation support. - context: AppLoadContext; -}; - -/** - * A function that loads data for a route on the client - * @private Public API is exported from @remix-run/react - */ -type ClientLoaderFunction = (( - args: ClientLoaderFunctionArgs -) => ReturnType) & { - hydrate?: boolean; -}; - -/** - * Arguments passed to a route `clientLoader` function - * @private Public API is exported from @remix-run/react - */ -export type ClientLoaderFunctionArgs = RRLoaderFunctionArgs & { - serverLoader: () => Promise>; -}; - -export type HeadersArgs = { - loaderHeaders: Headers; - parentHeaders: Headers; - actionHeaders: Headers; - errorHeaders: Headers | undefined; -}; - -/** - * A function that returns HTTP headers to be used for a route. These headers - * will be merged with (and take precedence over) headers from parent routes. - */ -export interface HeadersFunction { - (args: HeadersArgs): Headers | HeadersInit; -} - -/** - * A function that defines `` tags to be inserted into the `` of - * the document on route transitions. - */ -export interface LinksFunction { - (): LinkDescriptor[]; -} - -/** - * A function that returns an array of data objects to use for rendering - * metadata HTML tags in a route. These tags are not rendered on descendant - * routes in the route hierarchy. In other words, they will only be rendered on - * the route in which they are exported. - * - * @param Loader - The type of the current route's loader function - * @param MatchLoaders - Mapping from a parent route's filepath to its loader - * function type - * - * Note that parent route filepaths are relative to the `app/` directory. - * - * For example, if this meta function is for `/sales/customers/$customerId`: - * - * ```ts - * // app/root.tsx - * const loader = () => { - * return json({ hello: "world" } as const) - * } - * export type Loader = typeof loader - * - * // app/routes/sales.tsx - * const loader = () => { - * return json({ salesCount: 1074 }) - * } - * export type Loader = typeof loader - * - * // app/routes/sales/customers.tsx - * const loader = () => { - * return json({ customerCount: 74 }) - * } - * export type Loader = typeof loader - * - * // app/routes/sales/customers/$customersId.tsx - * import type { Loader as RootLoader } from "../../../root" - * import type { Loader as SalesLoader } from "../../sales" - * import type { Loader as CustomersLoader } from "../../sales/customers" - * - * const loader = () => { - * return json({ name: "Customer name" }) - * } - * - * const meta: MetaFunction = ({ data, matches }) => { - * const { name } = data - * // ^? string - * const { customerCount } = matches.find((match) => match.id === "routes/sales/customers").data - * // ^? number - * const { salesCount } = matches.find((match) => match.id === "routes/sales").data - * // ^? number - * const { hello } = matches.find((match) => match.id === "root").data - * // ^? "world" - * } - * ``` - */ -export interface ServerRuntimeMetaFunction< - Loader extends LoaderFunction | unknown = unknown, - ParentsLoaders extends Record = Record< - string, - unknown - > -> { - ( - args: ServerRuntimeMetaArgs - ): ServerRuntimeMetaDescriptor[]; -} - -interface ServerRuntimeMetaMatch< - RouteId extends string = string, - Loader extends LoaderFunction | unknown = unknown -> { - id: RouteId; - pathname: AgnosticRouteMatch["pathname"]; - data: Loader extends LoaderFunction ? SerializeFrom : unknown; - handle?: RouteHandle; - params: AgnosticRouteMatch["params"]; - meta: ServerRuntimeMetaDescriptor[]; - error?: unknown; -} - -type ServerRuntimeMetaMatches< - MatchLoaders extends Record = Record< - string, - unknown - > -> = Array< - { - [K in keyof MatchLoaders]: ServerRuntimeMetaMatch< - Exclude, - MatchLoaders[K] - >; - }[keyof MatchLoaders] ->; - -export interface ServerRuntimeMetaArgs< - Loader extends LoaderFunction | unknown = unknown, - MatchLoaders extends Record = Record< - string, - unknown - > -> { - data: - | (Loader extends LoaderFunction ? SerializeFrom : AppData) - | undefined; - params: Params; - location: Location; - matches: ServerRuntimeMetaMatches; - error?: unknown; -} - -export type ServerRuntimeMetaDescriptor = - | { charSet: "utf-8" } - | { title: string } - | { name: string; content: string } - | { property: string; content: string } - | { httpEquiv: string; content: string } - | { "script:ld+json": LdJsonObject } - | { tagName: "meta" | "link"; [name: string]: string } - | { [name: string]: unknown }; - -type LdJsonObject = { [Key in string]: LdJsonValue } & { - [Key in string]?: LdJsonValue | undefined; -}; -type LdJsonArray = LdJsonValue[] | readonly LdJsonValue[]; -type LdJsonPrimitive = string | number | boolean | null; -type LdJsonValue = LdJsonPrimitive | LdJsonObject | LdJsonArray; - -/** - * An arbitrary object that is associated with a route. - */ -export type RouteHandle = unknown; - -export interface EntryRouteModule { - clientAction?: ClientActionFunction; - clientLoader?: ClientLoaderFunction; - ErrorBoundary?: any; // Weakly typed because server-runtime is not React-aware - HydrateFallback?: any; // Weakly typed because server-runtime is not React-aware - Layout?: any; // Weakly typed because server-runtime is not React-aware - default: any; // Weakly typed because server-runtime is not React-aware - handle?: RouteHandle; - links?: LinksFunction; - meta?: ServerRuntimeMetaFunction; -} - -export interface ServerRouteModule extends EntryRouteModule { - action?: ActionFunction; - headers?: HeadersFunction | { [name: string]: string }; - loader?: LoaderFunction; -} diff --git a/packages/remix-server-runtime/routes.ts b/packages/remix-server-runtime/routes.ts deleted file mode 100644 index 6d4fbe2752f..00000000000 --- a/packages/remix-server-runtime/routes.ts +++ /dev/null @@ -1,135 +0,0 @@ -import type { - AgnosticDataRouteObject, - LoaderFunctionArgs as RRLoaderFunctionArgs, - ActionFunctionArgs as RRActionFunctionArgs, -} from "@remix-run/router"; - -import { callRouteAction, callRouteLoader } from "./data"; -import type { FutureConfig } from "./entry"; -import type { ServerRouteModule } from "./routeModules"; - -export interface RouteManifest { - [routeId: string]: Route; -} - -export type ServerRouteManifest = RouteManifest>; - -// NOTE: make sure to change the Route in remix-react if you change this -export interface Route { - index?: boolean; - caseSensitive?: boolean; - id: string; - parentId?: string; - path?: string; -} - -// NOTE: make sure to change the EntryRoute in remix-react if you change this -export interface EntryRoute extends Route { - hasAction: boolean; - hasLoader: boolean; - hasClientAction: boolean; - hasClientLoader: boolean; - hasErrorBoundary: boolean; - imports?: string[]; - css?: string[]; - module: string; - parentId?: string; -} - -export interface ServerRoute extends Route { - children: ServerRoute[]; - module: ServerRouteModule; -} - -function groupRoutesByParentId(manifest: ServerRouteManifest) { - let routes: Record[]> = {}; - - Object.values(manifest).forEach((route) => { - let parentId = route.parentId || ""; - if (!routes[parentId]) { - routes[parentId] = []; - } - routes[parentId].push(route); - }); - - return routes; -} - -// Create a map of routes by parentId to use recursively instead of -// repeatedly filtering the manifest. -export function createRoutes( - manifest: ServerRouteManifest, - parentId: string = "", - routesByParentId: Record< - string, - Omit[] - > = groupRoutesByParentId(manifest) -): ServerRoute[] { - return (routesByParentId[parentId] || []).map((route) => ({ - ...route, - children: createRoutes(manifest, route.id, routesByParentId), - })); -} - -// Convert the Remix ServerManifest into DataRouteObject's for use with -// createStaticHandler -export function createStaticHandlerDataRoutes( - manifest: ServerRouteManifest, - future: FutureConfig, - parentId: string = "", - routesByParentId: Record< - string, - Omit[] - > = groupRoutesByParentId(manifest) -): AgnosticDataRouteObject[] { - return (routesByParentId[parentId] || []).map((route) => { - let commonRoute = { - // Always include root due to default boundaries - hasErrorBoundary: - route.id === "root" || route.module.ErrorBoundary != null, - id: route.id, - path: route.path, - loader: route.module.loader - ? // Need to use RR's version here to permit the optional context even - // though we know it'll always be provided in remix - (args: RRLoaderFunctionArgs, dataStrategyCtx?: unknown) => - callRouteLoader({ - request: args.request, - params: args.params, - loadContext: args.context, - loader: route.module.loader!, - routeId: route.id, - singleFetch: future.v3_singleFetch === true, - }) - : undefined, - action: route.module.action - ? (args: RRActionFunctionArgs, dataStrategyCtx?: unknown) => - callRouteAction({ - request: args.request, - params: args.params, - loadContext: args.context, - action: route.module.action!, - routeId: route.id, - singleFetch: future.v3_singleFetch === true, - }) - : undefined, - handle: route.module.handle, - }; - - return route.index - ? { - index: true, - ...commonRoute, - } - : { - caseSensitive: route.caseSensitive, - children: createStaticHandlerDataRoutes( - manifest, - future, - route.id, - routesByParentId - ), - ...commonRoute, - }; - }); -} diff --git a/packages/remix-server-runtime/serialize.ts b/packages/remix-server-runtime/serialize.ts deleted file mode 100644 index 9f417d68e26..00000000000 --- a/packages/remix-server-runtime/serialize.ts +++ /dev/null @@ -1,188 +0,0 @@ -import type { EmptyObject, Jsonify } from "./jsonify"; -import type { TypedDeferredData, TypedResponse } from "./responses"; -import type { - ClientActionFunctionArgs, - ClientLoaderFunctionArgs, -} from "./routeModules"; -import { expectType } from "./typecheck"; -import { type Expect, type Equal } from "./typecheck"; -import { type SerializeFrom as SingleFetch_SerializeFrom } from "./single-fetch"; -import type { Future } from "./future"; - -// prettier-ignore -type SingleFetchEnabled = - Future extends { v3_singleFetch: infer T extends boolean } ? T : false - -// prettier-ignore -/** - * Infer JSON serialized data type returned by a loader or action, while - * avoiding deserialization if the input type if it's a clientLoader or - * clientAction that returns a non-Response - * - * For example: - * `type LoaderData = SerializeFrom` - * - * @deprecated SerializeFrom is deprecated and will be removed in React Router - * v7. Please use the generics on `useLoaderData`/etc. instead of manually - * deserializing in Remix v2. You can convert to the generated types once you - * migrate to React Router v7. - */ -export type SerializeFrom = - SingleFetchEnabled extends true ? SingleFetch_SerializeFrom : - T extends (...args: any[]) => infer Output ? - Parameters extends [ClientLoaderFunctionArgs | ClientActionFunctionArgs] ? - // Client data functions may not serialize - SerializeClient> - : - // Serialize responses - Serialize> - : - // Back compat: manually defined data type, not inferred from loader nor action - Jsonify> - -// note: cannot be inlined as logic requires union distribution -// prettier-ignore -type SerializeClient = - Output extends TypedDeferredData ? - // top-level promises - & { - [K in keyof U as K extends symbol - ? never - : Promise extends U[K] - ? K - : never]: DeferValueClient; // use generic to distribute over union - } - // non-promises - & { - [K in keyof U as Promise extends U[K] ? never : K]: U[K]; - } - : - Output extends TypedResponse ? Jsonify : - Awaited - -// prettier-ignore -type DeferValueClient = - T extends undefined ? undefined : - T extends Promise ? Promise> : - T; - -// note: cannot be inlined as logic requires union distribution -// prettier-ignore -type Serialize = - Output extends TypedDeferredData ? - // top-level promises - & { - [K in keyof U as - K extends symbol ? never : - Promise extends U[K] ? K : - never - ]: DeferValue; // use generic to distribute over union - } - // non-promises - & Jsonify<{ - [K in keyof U as - Promise extends U[K] ? never : - K - ]: U[K]; - }> - : - Output extends TypedResponse ? Jsonify : - Jsonify; - -// prettier-ignore -type DeferValue = - T extends undefined ? undefined : - T extends Promise ? Promise>> : - Jsonify; - -// tests ------------------------------------------------------------ - -type Pretty = { [K in keyof T]: T[K] }; - -type Loader = () => Promise>; - -type LoaderDefer> = () => Promise< - TypedDeferredData ->; - -type LoaderBoth< - T1 extends Record, - T2 extends Record -> = () => Promise | TypedDeferredData>; - -type ClientLoaderRaw> = ({ - request, -}: ClientLoaderFunctionArgs) => Promise; // returned non-Response - -type ClientLoaderResponse> = ({ - request, -}: ClientLoaderFunctionArgs) => Promise>; // returned responses - -type ClientLoaderDefer> = ({ - request, -}: ClientLoaderFunctionArgs) => Promise>; // returned responses - -type ClientLoaderResponseAndDefer< - T1 extends Record, - T2 extends Record -> = ({ - request, -}: ClientLoaderFunctionArgs) => Promise< - TypedResponse | TypedDeferredData ->; - -type ClientLoaderRawAndDefer< - T1 extends Record, - T2 extends Record -> = ({ - request, -}: ClientLoaderFunctionArgs) => Promise>; - -// prettier-ignore -// eslint-disable-next-line @typescript-eslint/no-unused-vars -type _tests = [ - // back compat: plain object - Expect>, {a: string}>>, - - // only thrown responses (e.g. redirects) - Expect>, never>>, - - // basic loader data - Expect>>, {a: string}>>, - - // infer data type from `toJSON` - Expect>>, {a: string}>>, - - // regression test for specific field names - Expect>>, {a: string, name: number, data: boolean}>>, - - // defer top-level promises - Expect}>> extends {a: string, lazy: Promise<{ b: number }>} ? true : false>, - - // conditional defer or json - Expect }, { c: string; lazy: Promise<{ d: number }>}>> extends { a: string, b: EmptyObject } | { c: string; lazy: Promise<{ d: number }> } ? true : false>, - - // clientLoader raw JSON - Expect>>, {a: string}>>, - Expect }>>>, {a: Date, b: Map}>>, - - // clientLoader json() Response - Expect>>, {a: string}>>, - Expect>>, {a: string}>>, - - // clientLoader defer() data - Expect}>> extends {a: string, lazy: Promise<{ b: number }>} ? true : false>, - - // clientLoader conditional defer or json - Expect }, { c: string; lazy: Promise<{ d: number }>}>> extends { a: string, b: EmptyObject } | { c: string; lazy: Promise<{ d: number }> } ? true : false>, - - // clientLoader conditional defer or raw - Expect }, { c: string; lazy: Promise<{ d: number }>}>> extends { a: string, b: Promise } | { c: string; lazy: Promise<{ d: number }> } ? true : false>, -]; - -// recursive -type Recursive = { a: string; recur?: Recursive }; -declare const recursive: SerializeFrom>; -expectType<{ a: string; recur?: Jsonify }>( - recursive.recur!.recur!.recur! -); diff --git a/packages/remix-server-runtime/server.ts b/packages/remix-server-runtime/server.ts deleted file mode 100644 index 1c730615954..00000000000 --- a/packages/remix-server-runtime/server.ts +++ /dev/null @@ -1,798 +0,0 @@ -import type { - UNSAFE_DeferredData as DeferredData, - ErrorResponse, - StaticHandler, -} from "@remix-run/router"; -import { - UNSAFE_DEFERRED_SYMBOL as DEFERRED_SYMBOL, - getStaticContextFromError, - isRouteErrorResponse, - createStaticHandler, - json as routerJson, - stripBasename, - UNSAFE_ErrorResponseImpl as ErrorResponseImpl, -} from "@remix-run/router"; - -import type { AppLoadContext } from "./data"; -import type { HandleErrorFunction, ServerBuild } from "./build"; -import type { EntryContext } from "./entry"; -import { createEntryRouteModules } from "./entry"; -import { sanitizeErrors, serializeError, serializeErrors } from "./errors"; -import { getDocumentHeaders } from "./headers"; -import invariant from "./invariant"; -import { ServerMode, isServerMode } from "./mode"; -import type { RouteMatch } from "./routeMatching"; -import { matchServerRoutes } from "./routeMatching"; -import type { EntryRoute, ServerRoute } from "./routes"; -import { createStaticHandlerDataRoutes, createRoutes } from "./routes"; -import { - createDeferredReadableStream, - isRedirectResponse, - isResponse, - json, -} from "./responses"; -import { createServerHandoffString } from "./serverHandoff"; -import { getDevServerHooks } from "./dev"; -import type { SingleFetchResult, SingleFetchResults } from "./single-fetch"; -import { - encodeViaTurboStream, - getSingleFetchRedirect, - singleFetchAction, - singleFetchLoaders, - SingleFetchRedirectSymbol, - SINGLE_FETCH_REDIRECT_STATUS, -} from "./single-fetch"; -import { resourceRouteJsonWarning } from "./deprecations"; - -export type RequestHandler = ( - request: Request, - loadContext?: AppLoadContext -) => Promise; - -export type CreateRequestHandlerFunction = ( - build: ServerBuild | (() => ServerBuild | Promise), - mode?: string -) => RequestHandler; - -// Do not include a response body if the status code is one of these, -// otherwise `undici` will throw an error when constructing the Response: -// https://github.com/nodejs/undici/blob/bd98a6303e45d5e0d44192a93731b1defdb415f3/lib/web/fetch/response.js#L522-L528 -// -// Specs: -// https://datatracker.ietf.org/doc/html/rfc9110#name-informational-1xx -// https://datatracker.ietf.org/doc/html/rfc9110#name-204-no-content -// https://datatracker.ietf.org/doc/html/rfc9110#name-205-reset-content -// https://datatracker.ietf.org/doc/html/rfc9110#name-304-not-modified -const NO_BODY_STATUS_CODES = new Set([100, 101, 204, 205, 304]); - -function derive(build: ServerBuild, mode?: string) { - let routes = createRoutes(build.routes); - let dataRoutes = createStaticHandlerDataRoutes(build.routes, build.future); - let serverMode = isServerMode(mode) ? mode : ServerMode.Production; - let staticHandler = createStaticHandler(dataRoutes, { - basename: build.basename, - future: { - v7_relativeSplatPath: build.future?.v3_relativeSplatPath === true, - v7_throwAbortReason: build.future?.v3_throwAbortReason === true, - }, - }); - - let errorHandler = - build.entry.module.handleError || - ((error, { request }) => { - if (serverMode !== ServerMode.Test && !request.signal.aborted) { - console.error( - // @ts-expect-error This is "private" from users but intended for internal use - isRouteErrorResponse(error) && error.error ? error.error : error - ); - } - }); - return { - routes, - dataRoutes, - serverMode, - staticHandler, - errorHandler, - }; -} - -export const createRequestHandler: CreateRequestHandlerFunction = ( - build, - mode -) => { - let _build: ServerBuild; - let routes: ServerRoute[]; - let serverMode: ServerMode; - let staticHandler: StaticHandler; - let errorHandler: HandleErrorFunction; - - return async function requestHandler(request, loadContext = {}) { - _build = typeof build === "function" ? await build() : build; - mode ??= _build.mode; - if (typeof build === "function") { - let derived = derive(_build, mode); - routes = derived.routes; - serverMode = derived.serverMode; - staticHandler = derived.staticHandler; - errorHandler = derived.errorHandler; - } else if (!routes || !serverMode || !staticHandler || !errorHandler) { - let derived = derive(_build, mode); - routes = derived.routes; - serverMode = derived.serverMode; - staticHandler = derived.staticHandler; - errorHandler = derived.errorHandler; - } - - let url = new URL(request.url); - let params: RouteMatch["params"] = {}; - let handleError = (error: unknown) => { - if (mode === ServerMode.Development) { - getDevServerHooks()?.processRequestError?.(error); - } - - errorHandler(error, { - context: loadContext, - params, - request, - }); - }; - - // Manifest request for fog of war - - let manifestUrl = `${_build.basename ?? "/"}/__manifest`.replace( - /\/+/g, - "/" - ); - if (url.pathname === manifestUrl) { - try { - let res = await handleManifestRequest(_build, routes, url); - return res; - } catch (e) { - handleError(e); - return new Response("Unknown Server Error", { status: 500 }); - } - } - - let matches = matchServerRoutes(routes, url.pathname, _build.basename); - if (matches && matches.length > 0) { - Object.assign(params, matches[0].params); - } - - let response: Response; - if (url.searchParams.has("_data")) { - if (_build.future.v3_singleFetch) { - handleError( - new Error( - "Warning: Single fetch-enabled apps should not be making ?_data requests, " + - "this is likely to break in the future" - ) - ); - } - let routeId = url.searchParams.get("_data")!; - - response = await handleDataRequest( - serverMode, - _build, - staticHandler, - routeId, - request, - loadContext, - handleError - ); - - if (_build.entry.module.handleDataRequest) { - response = await _build.entry.module.handleDataRequest(response, { - context: loadContext, - params, - request, - }); - - if (isRedirectResponse(response)) { - response = createRemixRedirectResponse(response, _build.basename); - } - } - } else if (_build.future.v3_singleFetch && url.pathname.endsWith(".data")) { - let handlerUrl = new URL(request.url); - handlerUrl.pathname = handlerUrl.pathname - .replace(/\.data$/, "") - .replace(/^\/_root$/, "/"); - - let singleFetchMatches = matchServerRoutes( - routes, - handlerUrl.pathname, - _build.basename - ); - - response = await handleSingleFetchRequest( - serverMode, - _build, - staticHandler, - request, - handlerUrl, - loadContext, - handleError - ); - - if (_build.entry.module.handleDataRequest) { - response = await _build.entry.module.handleDataRequest(response, { - context: loadContext, - params: singleFetchMatches ? singleFetchMatches[0].params : {}, - request, - }); - - if (isRedirectResponse(response)) { - let result: SingleFetchResult | SingleFetchResults = - getSingleFetchRedirect( - response.status, - response.headers, - _build.basename - ); - - if (request.method === "GET") { - result = { - [SingleFetchRedirectSymbol]: result, - }; - } - let headers = new Headers(response.headers); - headers.set("Content-Type", "text/x-script"); - - return new Response( - encodeViaTurboStream( - result, - request.signal, - _build.entry.module.streamTimeout, - serverMode - ), - { - status: SINGLE_FETCH_REDIRECT_STATUS, - headers, - } - ); - } - } - } else if ( - matches && - matches[matches.length - 1].route.module.default == null && - matches[matches.length - 1].route.module.ErrorBoundary == null - ) { - response = await handleResourceRequest( - serverMode, - _build, - staticHandler, - matches.slice(-1)[0].route.id, - request, - loadContext, - handleError - ); - } else { - let criticalCss = - mode === ServerMode.Development - ? await getDevServerHooks()?.getCriticalCss?.(_build, url.pathname) - : undefined; - - response = await handleDocumentRequest( - serverMode, - _build, - staticHandler, - request, - loadContext, - handleError, - criticalCss - ); - } - - if (request.method === "HEAD") { - return new Response(null, { - headers: response.headers, - status: response.status, - statusText: response.statusText, - }); - } - - return response; - }; -}; - -async function handleManifestRequest( - build: ServerBuild, - routes: ServerRoute[], - url: URL -) { - if (build.assets.version !== url.searchParams.get("version")) { - return new Response(null, { - status: 204, - headers: { - "X-Remix-Reload-Document": "true", - }, - }); - } - - let patches: Record = {}; - - if (url.searchParams.has("p")) { - let paths = new Set(); - - // In addition to responding with the patches for the requested paths, we - // need to include patches for each partial path so that we pick up any - // pathless/index routes below ancestor segments. So if we - // get a request for `/parent/child`, we need to look for a match on `/parent` - // so that if a `parent._index` route exists we return it so it's available - // for client side matching if the user routes back up to `/parent`. - // This is the same thing we do on initial load in via - // `getPartialManifest()` - url.searchParams.getAll("p").forEach((path) => { - if (!path.startsWith("/")) { - path = `/${path}`; - } - let segments = path.split("/").slice(1); - segments.forEach((_, i) => { - let partialPath = segments.slice(0, i + 1).join("/"); - paths.add(`/${partialPath}`); - }); - }); - - for (let path of paths) { - let matches = matchServerRoutes(routes, path, build.basename); - if (matches) { - for (let match of matches) { - let routeId = match.route.id; - patches[routeId] = build.assets.routes[routeId]; - } - } - } - - return json(patches, { - headers: { - "Cache-Control": "public, max-age=31536000, immutable", - }, - }) as Response; // Override the TypedResponse stuff from json() - } - - return new Response("Invalid Request", { status: 400 }); -} - -async function handleDataRequest( - serverMode: ServerMode, - build: ServerBuild, - staticHandler: StaticHandler, - routeId: string, - request: Request, - loadContext: AppLoadContext, - handleError: (err: unknown) => void -) { - try { - let response = await staticHandler.queryRoute(request, { - routeId, - requestContext: loadContext, - }); - - if (isRedirectResponse(response)) { - return createRemixRedirectResponse(response, build.basename); - } - - if (DEFERRED_SYMBOL in response) { - let deferredData = response[DEFERRED_SYMBOL] as DeferredData; - let body = createDeferredReadableStream( - deferredData, - request.signal, - serverMode - ); - let init = deferredData.init || {}; - let headers = new Headers(init.headers); - headers.set("Content-Type", "text/remix-deferred"); - // Mark successful responses with a header so we can identify in-flight - // network errors that are missing this header - headers.set("X-Remix-Response", "yes"); - init.headers = headers; - return new Response(body, init); - } - - // Mark all successful responses with a header so we can identify in-flight - // network errors that are missing this header - response = safelySetHeader(response, "X-Remix-Response", "yes"); - return response; - } catch (error: unknown) { - if (isResponse(error)) { - let response = safelySetHeader(error, "X-Remix-Catch", "yes"); - return response; - } - - if (isRouteErrorResponse(error)) { - handleError(error); - return errorResponseToJson(error, serverMode); - } - - let errorInstance = - error instanceof Error || error instanceof DOMException - ? error - : new Error("Unexpected Server Error"); - handleError(errorInstance); - return routerJson(serializeError(errorInstance, serverMode), { - status: 500, - headers: { - "X-Remix-Error": "yes", - }, - }); - } -} - -async function handleSingleFetchRequest( - serverMode: ServerMode, - build: ServerBuild, - staticHandler: StaticHandler, - request: Request, - handlerUrl: URL, - loadContext: AppLoadContext, - handleError: (err: unknown) => void -): Promise { - let { result, headers, status } = - request.method !== "GET" - ? await singleFetchAction( - build, - serverMode, - staticHandler, - request, - handlerUrl, - loadContext, - handleError - ) - : await singleFetchLoaders( - build, - serverMode, - staticHandler, - request, - handlerUrl, - loadContext, - handleError - ); - - // Mark all successful responses with a header so we can identify in-flight - // network errors that are missing this header - let resultHeaders = new Headers(headers); - resultHeaders.set("X-Remix-Response", "yes"); - - // Skip response body for unsupported status codes - if (NO_BODY_STATUS_CODES.has(status)) { - return new Response(null, { status, headers: resultHeaders }); - } - - // We use a less-descriptive `text/x-script` here instead of something like - // `text/x-turbo` to enable compression when deployed via Cloudflare. See: - // - https://github.com/remix-run/remix/issues/9884 - // - https://developers.cloudflare.com/speed/optimization/content/brotli/content-compression/ - resultHeaders.set("Content-Type", "text/x-script"); - - // Note: Deferred data is already just Promises, so we don't have to mess - // `activeDeferreds` or anything :) - return new Response( - encodeViaTurboStream( - result, - request.signal, - build.entry.module.streamTimeout, - serverMode - ), - { - status: status || 200, - headers: resultHeaders, - } - ); -} - -async function handleDocumentRequest( - serverMode: ServerMode, - build: ServerBuild, - staticHandler: StaticHandler, - request: Request, - loadContext: AppLoadContext, - handleError: (err: unknown) => void, - criticalCss?: string -) { - let context; - try { - context = await staticHandler.query(request, { - requestContext: loadContext, - }); - } catch (error: unknown) { - handleError(error); - return new Response(null, { status: 500 }); - } - - if (isResponse(context)) { - return context; - } - - let headers = getDocumentHeaders(build, context); - - // Skip response body for unsupported status codes - if (NO_BODY_STATUS_CODES.has(context.statusCode)) { - return new Response(null, { status: context.statusCode, headers }); - } - - // Sanitize errors outside of development environments - if (context.errors) { - Object.values(context.errors).forEach((err) => { - // @ts-expect-error `err.error` is "private" from users but intended for internal use - if (!isRouteErrorResponse(err) || err.error) { - handleError(err); - } - }); - context.errors = sanitizeErrors(context.errors, serverMode); - } - - // Server UI state to send to the client. - // - When single fetch is enabled, this is streamed down via `serverHandoffStream` - // - Otherwise it's stringified into `serverHandoffString` - let state = { - loaderData: context.loaderData, - actionData: context.actionData, - errors: serializeErrors(context.errors, serverMode), - }; - let entryContext: EntryContext = { - manifest: build.assets, - routeModules: createEntryRouteModules(build.routes), - staticHandlerContext: context, - criticalCss, - serverHandoffString: createServerHandoffString({ - basename: build.basename, - criticalCss, - future: build.future, - isSpaMode: build.isSpaMode, - ...(!build.future.v3_singleFetch ? { state } : null), - }), - ...(build.future.v3_singleFetch - ? { - serverHandoffStream: encodeViaTurboStream( - state, - request.signal, - build.entry.module.streamTimeout, - serverMode - ), - renderMeta: {}, - } - : null), - future: build.future, - isSpaMode: build.isSpaMode, - serializeError: (err) => serializeError(err, serverMode), - }; - - let handleDocumentRequestFunction = build.entry.module.default; - try { - return await handleDocumentRequestFunction( - request, - context.statusCode, - headers, - entryContext, - loadContext - ); - } catch (error: unknown) { - handleError(error); - - let errorForSecondRender = error; - - // If they threw a response, unwrap it into an ErrorResponse like we would - // have for a loader/action - if (isResponse(error)) { - try { - let data = await unwrapResponse(error); - errorForSecondRender = new ErrorResponseImpl( - error.status, - error.statusText, - data - ); - } catch (e) { - // If we can't unwrap the response - just leave it as-is - } - } - - // Get a new StaticHandlerContext that contains the error at the right boundary - context = getStaticContextFromError( - staticHandler.dataRoutes, - context, - errorForSecondRender - ); - - // Sanitize errors outside of development environments - if (context.errors) { - context.errors = sanitizeErrors(context.errors, serverMode); - } - - // Get a new entryContext for the second render pass - // Server UI state to send to the client. - // - When single fetch is enabled, this is streamed down via `serverHandoffStream` - // - Otherwise it's stringified into `serverHandoffString` - let state = { - loaderData: context.loaderData, - actionData: context.actionData, - errors: serializeErrors(context.errors, serverMode), - }; - entryContext = { - ...entryContext, - staticHandlerContext: context, - serverHandoffString: createServerHandoffString({ - basename: build.basename, - future: build.future, - isSpaMode: build.isSpaMode, - ...(!build.future.v3_singleFetch ? { state } : null), - }), - ...(build.future.v3_singleFetch - ? { - serverHandoffStream: encodeViaTurboStream( - state, - request.signal, - build.entry.module.streamTimeout, - serverMode - ), - renderMeta: {}, - } - : null), - }; - - try { - return await handleDocumentRequestFunction( - request, - context.statusCode, - headers, - entryContext, - loadContext - ); - } catch (error: any) { - handleError(error); - return returnLastResortErrorResponse(error, serverMode); - } - } -} - -async function handleResourceRequest( - serverMode: ServerMode, - build: ServerBuild, - staticHandler: StaticHandler, - routeId: string, - request: Request, - loadContext: AppLoadContext, - handleError: (err: unknown) => void -) { - try { - // Note we keep the routeId here to align with the Remix handling of - // resource routes which doesn't take ?index into account and just takes - // the leaf match - let response = await staticHandler.queryRoute(request, { - routeId, - requestContext: loadContext, - }); - - if (typeof response === "object" && response !== null) { - invariant( - !(DEFERRED_SYMBOL in response), - `You cannot return a \`defer()\` response from a Resource Route. Did you ` + - `forget to export a default UI component from the "${routeId}" route?` - ); - } - - if (build.future.v3_singleFetch && !isResponse(response)) { - console.warn( - resourceRouteJsonWarning( - request.method === "GET" ? "loader" : "action", - routeId - ) - ); - response = json(response); - } - - // callRouteLoader/callRouteAction always return responses (w/o single fetch). - // With single fetch, users should always be Responses from resource routes - invariant( - isResponse(response), - "Expected a Response to be returned from queryRoute" - ); - return response; - } catch (error: unknown) { - if (isResponse(error)) { - // Note: Not functionally required but ensures that our response headers - // match identically to what Remix returns - let response = safelySetHeader(error, "X-Remix-Catch", "yes"); - return response; - } - - if (isRouteErrorResponse(error)) { - if (error) { - handleError(error); - } - return errorResponseToJson(error, serverMode); - } - - handleError(error); - return returnLastResortErrorResponse(error, serverMode); - } -} - -function errorResponseToJson( - errorResponse: ErrorResponse, - serverMode: ServerMode -): Response { - return routerJson( - serializeError( - // @ts-expect-error This is "private" from users but intended for internal use - errorResponse.error || new Error("Unexpected Server Error"), - serverMode - ), - { - status: errorResponse.status, - statusText: errorResponse.statusText, - headers: { - "X-Remix-Error": "yes", - }, - } - ); -} - -function returnLastResortErrorResponse(error: any, serverMode?: ServerMode) { - let message = "Unexpected Server Error"; - - if (serverMode !== ServerMode.Production) { - message += `\n\n${String(error)}`; - } - - // Good grief folks, get your act together 😂! - return new Response(message, { - status: 500, - headers: { - "Content-Type": "text/plain", - }, - }); -} - -function unwrapResponse(response: Response) { - let contentType = response.headers.get("Content-Type"); - // Check between word boundaries instead of startsWith() due to the last - // paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type - return contentType && /\bapplication\/json\b/.test(contentType) - ? response.body == null - ? null - : response.json() - : response.text(); -} - -function createRemixRedirectResponse( - response: Response, - basename: string | undefined -) { - // We don't have any way to prevent a fetch request from following - // redirects. So we use the `X-Remix-Redirect` header to indicate the - // next URL, and then "follow" the redirect manually on the client. - let headers = new Headers(response.headers); - let redirectUrl = headers.get("Location")!; - headers.set( - "X-Remix-Redirect", - basename ? stripBasename(redirectUrl, basename) || redirectUrl : redirectUrl - ); - headers.set("X-Remix-Status", String(response.status)); - headers.delete("Location"); - if (response.headers.get("Set-Cookie") !== null) { - headers.set("X-Remix-Revalidate", "yes"); - } - - return new Response(null, { - status: 204, - headers, - }); -} - -// Anytime we are setting a header on a `Response` created in the loader/action, -// we have to so it in this manner since in an `undici` world, if the `Response` -// came directly from a `fetch` call, the headers are immutable will throw if -// we try to set a new header. This is a sort of shallow clone of the `Response` -// so we can safely set our own header. -function safelySetHeader( - response: Response, - name: string, - value: string -): Response { - let headers = new Headers(response.headers); - headers.set(name, value); - return new Response(response.body, { - status: response.status, - statusText: response.statusText, - headers, - duplex: response.body ? "half" : undefined, - } as ResponseInit & { duplex?: "half" }); -} diff --git a/packages/remix-server-runtime/serverHandoff.ts b/packages/remix-server-runtime/serverHandoff.ts deleted file mode 100644 index 69add800f63..00000000000 --- a/packages/remix-server-runtime/serverHandoff.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { HydrationState } from "@remix-run/router"; - -import type { FutureConfig } from "./entry"; -import { escapeHtml } from "./markup"; - -type ValidateShape = - // If it extends T - T extends Shape - ? // and there are no leftover props after removing the base - Exclude extends never - ? // we are good - T - : // otherwise it's either too many or too few props - never - : never; - -// TODO: Remove Promises from serialization -export function createServerHandoffString(serverHandoff: { - // Don't allow StaticHandlerContext to be passed in verbatim, since then - // we'd end up including duplicate info - state?: ValidateShape; - criticalCss?: string; - basename: string | undefined; - future: FutureConfig; - isSpaMode: boolean; -}): string { - // Uses faster alternative of jsesc to escape data returned from the loaders. - // This string is inserted directly into the HTML in the `` element. - return escapeHtml(JSON.stringify(serverHandoff)); -} diff --git a/packages/remix-server-runtime/sessions.ts b/packages/remix-server-runtime/sessions.ts deleted file mode 100644 index c00eedb2321..00000000000 --- a/packages/remix-server-runtime/sessions.ts +++ /dev/null @@ -1,314 +0,0 @@ -import type { CookieParseOptions, CookieSerializeOptions } from "cookie"; - -import type { Cookie, CookieOptions, CreateCookieFunction } from "./cookies"; -import { isCookie } from "./cookies"; -import { warnOnce } from "./warnings"; - -/** - * An object of name/value pairs to be used in the session. - */ -export interface SessionData { - [name: string]: any; -} - -/** - * Session persists data across HTTP requests. - * - * @see https://remix.run/utils/sessions#session-api - */ -export interface Session { - /** - * A unique identifier for this session. - * - * Note: This will be the empty string for newly created sessions and - * sessions that are not backed by a database (i.e. cookie-based sessions). - */ - readonly id: string; - - /** - * The raw data contained in this session. - * - * This is useful mostly for SessionStorage internally to access the raw - * session data to persist. - */ - readonly data: FlashSessionData; - - /** - * Returns `true` if the session has a value for the given `name`, `false` - * otherwise. - */ - has(name: (keyof Data | keyof FlashData) & string): boolean; - - /** - * Returns the value for the given `name` in this session. - */ - get( - name: Key - ): - | (Key extends keyof Data ? Data[Key] : undefined) - | (Key extends keyof FlashData ? FlashData[Key] : undefined) - | undefined; - - /** - * Sets a value in the session for the given `name`. - */ - set(name: Key, value: Data[Key]): void; - - /** - * Sets a value in the session that is only valid until the next `get()`. - * This can be useful for temporary values, like error messages. - */ - flash( - name: Key, - value: FlashData[Key] - ): void; - - /** - * Removes a value from the session. - */ - unset(name: keyof Data & string): void; -} - -export type FlashSessionData = Partial< - Data & { - [Key in keyof FlashData as FlashDataKey]: FlashData[Key]; - } ->; -type FlashDataKey = `__flash_${Key}__`; -function flash(name: Key): FlashDataKey { - return `__flash_${name}__`; -} - -export type CreateSessionFunction = ( - initialData?: Data, - id?: string -) => Session; - -/** - * Creates a new Session object. - * - * Note: This function is typically not invoked directly by application code. - * Instead, use a `SessionStorage` object's `getSession` method. - * - * @see https://remix.run/utils/sessions#createsession - */ -export const createSession: CreateSessionFunction = < - Data = SessionData, - FlashData = Data ->( - initialData: Partial = {}, - id = "" -): Session => { - let map = new Map(Object.entries(initialData)) as Map< - keyof Data | FlashDataKey, - any - >; - - return { - get id() { - return id; - }, - get data() { - return Object.fromEntries(map) as FlashSessionData; - }, - has(name) { - return ( - map.has(name as keyof Data) || - map.has(flash(name as keyof FlashData & string)) - ); - }, - get(name) { - if (map.has(name as keyof Data)) return map.get(name as keyof Data); - - let flashName = flash(name as keyof FlashData & string); - if (map.has(flashName)) { - let value = map.get(flashName); - map.delete(flashName); - return value; - } - - return undefined; - }, - set(name, value) { - map.set(name, value); - }, - flash(name, value) { - map.set(flash(name), value); - }, - unset(name) { - map.delete(name); - }, - }; -}; - -export type IsSessionFunction = (object: any) => object is Session; - -/** - * Returns true if an object is a Remix session. - * - * @see https://remix.run/utils/sessions#issession - */ -export const isSession: IsSessionFunction = (object): object is Session => { - return ( - object != null && - typeof object.id === "string" && - typeof object.data !== "undefined" && - typeof object.has === "function" && - typeof object.get === "function" && - typeof object.set === "function" && - typeof object.flash === "function" && - typeof object.unset === "function" - ); -}; - -/** - * SessionStorage stores session data between HTTP requests and knows how to - * parse and create cookies. - * - * A SessionStorage creates Session objects using a `Cookie` header as input. - * Then, later it generates the `Set-Cookie` header to be used in the response. - */ -export interface SessionStorage { - /** - * Parses a Cookie header from a HTTP request and returns the associated - * Session. If there is no session associated with the cookie, this will - * return a new Session with no data. - */ - getSession: ( - cookieHeader?: string | null, - options?: CookieParseOptions - ) => Promise>; - - /** - * Stores all data in the Session and returns the Set-Cookie header to be - * used in the HTTP response. - */ - commitSession: ( - session: Session, - options?: CookieSerializeOptions - ) => Promise; - - /** - * Deletes all data associated with the Session and returns the Set-Cookie - * header to be used in the HTTP response. - */ - destroySession: ( - session: Session, - options?: CookieSerializeOptions - ) => Promise; -} - -/** - * SessionIdStorageStrategy is designed to allow anyone to easily build their - * own SessionStorage using `createSessionStorage(strategy)`. - * - * This strategy describes a common scenario where the session id is stored in - * a cookie but the actual session data is stored elsewhere, usually in a - * database or on disk. A set of create, read, update, and delete operations - * are provided for managing the session data. - */ -export interface SessionIdStorageStrategy< - Data = SessionData, - FlashData = Data -> { - /** - * The Cookie used to store the session id, or options used to automatically - * create one. - */ - cookie?: Cookie | (CookieOptions & { name?: string }); - - /** - * Creates a new record with the given data and returns the session id. - */ - createData: ( - data: FlashSessionData, - expires?: Date - ) => Promise; - - /** - * Returns data for a given session id, or `null` if there isn't any. - */ - readData: (id: string) => Promise | null>; - - /** - * Updates data for the given session id. - */ - updateData: ( - id: string, - data: FlashSessionData, - expires?: Date - ) => Promise; - - /** - * Deletes data for a given session id from the data store. - */ - deleteData: (id: string) => Promise; -} - -export type CreateSessionStorageFunction = < - Data = SessionData, - FlashData = Data ->( - strategy: SessionIdStorageStrategy -) => SessionStorage; - -/** - * Creates a SessionStorage object using a SessionIdStorageStrategy. - * - * Note: This is a low-level API that should only be used if none of the - * existing session storage options meet your requirements. - * - * @see https://remix.run/utils/sessions#createsessionstorage - */ -export const createSessionStorageFactory = - (createCookie: CreateCookieFunction): CreateSessionStorageFunction => - ({ cookie: cookieArg, createData, readData, updateData, deleteData }) => { - let cookie = isCookie(cookieArg) - ? cookieArg - : createCookie(cookieArg?.name || "__session", cookieArg); - - warnOnceAboutSigningSessionCookie(cookie); - - return { - async getSession(cookieHeader, options) { - let id = cookieHeader && (await cookie.parse(cookieHeader, options)); - let data = id && (await readData(id)); - return createSession(data || {}, id || ""); - }, - async commitSession(session, options) { - let { id, data } = session; - let expires = - options?.maxAge != null - ? new Date(Date.now() + options.maxAge * 1000) - : options?.expires != null - ? options.expires - : cookie.expires; - - if (id) { - await updateData(id, data, expires); - } else { - id = await createData(data, expires); - } - - return cookie.serialize(id, options); - }, - async destroySession(session, options) { - await deleteData(session.id); - return cookie.serialize("", { - ...options, - maxAge: undefined, - expires: new Date(0), - }); - }, - }; - }; - -export function warnOnceAboutSigningSessionCookie(cookie: Cookie) { - warnOnce( - cookie.isSigned, - `The "${cookie.name}" cookie is not signed, but session cookies should be ` + - `signed to prevent tampering on the client before they are sent back to the ` + - `server. See https://remix.run/utils/cookies#signing-cookies ` + - `for more information.` - ); -} diff --git a/packages/remix-server-runtime/sessions/cookieStorage.ts b/packages/remix-server-runtime/sessions/cookieStorage.ts deleted file mode 100644 index 09a2e765681..00000000000 --- a/packages/remix-server-runtime/sessions/cookieStorage.ts +++ /dev/null @@ -1,69 +0,0 @@ -import type { CreateCookieFunction } from "../cookies"; -import { isCookie } from "../cookies"; -import type { - SessionStorage, - SessionIdStorageStrategy, - SessionData, -} from "../sessions"; -import { warnOnceAboutSigningSessionCookie, createSession } from "../sessions"; - -interface CookieSessionStorageOptions { - /** - * The Cookie used to store the session data on the client, or options used - * to automatically create one. - */ - cookie?: SessionIdStorageStrategy["cookie"]; -} - -export type CreateCookieSessionStorageFunction = < - Data = SessionData, - FlashData = Data ->( - options?: CookieSessionStorageOptions -) => SessionStorage; - -/** - * Creates and returns a SessionStorage object that stores all session data - * directly in the session cookie itself. - * - * This has the advantage that no database or other backend services are - * needed, and can help to simplify some load-balanced scenarios. However, it - * also has the limitation that serialized session data may not exceed the - * browser's maximum cookie size. Trade-offs! - * - * @see https://remix.run/utils/sessions#createcookiesessionstorage - */ -export const createCookieSessionStorageFactory = - (createCookie: CreateCookieFunction): CreateCookieSessionStorageFunction => - ({ cookie: cookieArg } = {}) => { - let cookie = isCookie(cookieArg) - ? cookieArg - : createCookie(cookieArg?.name || "__session", cookieArg); - - warnOnceAboutSigningSessionCookie(cookie); - - return { - async getSession(cookieHeader, options) { - return createSession( - (cookieHeader && (await cookie.parse(cookieHeader, options))) || {} - ); - }, - async commitSession(session, options) { - let serializedCookie = await cookie.serialize(session.data, options); - if (serializedCookie.length > 4096) { - throw new Error( - "Cookie length will exceed browser maximum. Length: " + - serializedCookie.length - ); - } - return serializedCookie; - }, - async destroySession(_session, options) { - return cookie.serialize("", { - ...options, - maxAge: undefined, - expires: new Date(0), - }); - }, - }; - }; diff --git a/packages/remix-server-runtime/sessions/memoryStorage.ts b/packages/remix-server-runtime/sessions/memoryStorage.ts deleted file mode 100644 index 9ad13d7f7c6..00000000000 --- a/packages/remix-server-runtime/sessions/memoryStorage.ts +++ /dev/null @@ -1,73 +0,0 @@ -import type { - SessionData, - SessionStorage, - SessionIdStorageStrategy, - CreateSessionStorageFunction, - FlashSessionData, -} from "../sessions"; - -interface MemorySessionStorageOptions { - /** - * The Cookie used to store the session id on the client, or options used - * to automatically create one. - */ - cookie?: SessionIdStorageStrategy["cookie"]; -} - -export type CreateMemorySessionStorageFunction = < - Data = SessionData, - FlashData = Data ->( - options?: MemorySessionStorageOptions -) => SessionStorage; - -/** - * Creates and returns a simple in-memory SessionStorage object, mostly useful - * for testing and as a reference implementation. - * - * Note: This storage does not scale beyond a single process, so it is not - * suitable for most production scenarios. - * - * @see https://remix.run/utils/sessions#creatememorysessionstorage - */ -export const createMemorySessionStorageFactory = - ( - createSessionStorage: CreateSessionStorageFunction - ): CreateMemorySessionStorageFunction => - ({ - cookie, - }: MemorySessionStorageOptions = {}): SessionStorage => { - let map = new Map< - string, - { data: FlashSessionData; expires?: Date } - >(); - - return createSessionStorage({ - cookie, - async createData(data, expires) { - let id = Math.random().toString(36).substring(2, 10); - map.set(id, { data, expires }); - return id; - }, - async readData(id) { - if (map.has(id)) { - let { data, expires } = map.get(id)!; - - if (!expires || expires > new Date()) { - return data; - } - - // Remove expired session data. - if (expires) map.delete(id); - } - - return null; - }, - async updateData(id, data, expires) { - map.set(id, { data, expires }); - }, - async deleteData(id) { - map.delete(id); - }, - }); - }; diff --git a/packages/remix-server-runtime/single-fetch.ts b/packages/remix-server-runtime/single-fetch.ts deleted file mode 100644 index 834fc012367..00000000000 --- a/packages/remix-server-runtime/single-fetch.ts +++ /dev/null @@ -1,630 +0,0 @@ -import type { - StaticHandler, - DataStrategyFunctionArgs, - DataStrategyFunction, - UNSAFE_DataWithResponseInit as DataWithResponseInit, -} from "@remix-run/router"; -import { - isRouteErrorResponse, - data as routerData, - UNSAFE_ErrorResponseImpl as ErrorResponseImpl, - stripBasename, -} from "@remix-run/router"; -import { encode } from "turbo-stream"; - -import { type Expect, type Equal } from "./typecheck"; -import type { ServerBuild } from "./build"; -import type { AppLoadContext } from "./data"; -import { sanitizeError, sanitizeErrors } from "./errors"; -import { getDocumentHeaders } from "./headers"; -import { ServerMode } from "./mode"; -import type { TypedDeferredData, TypedResponse } from "./responses"; -import { isRedirectStatusCode, isResponse } from "./responses"; -import type { Jsonify } from "./jsonify"; -import type { - ClientActionFunctionArgs, - ClientLoaderFunctionArgs, - LoaderFunctionArgs, -} from "./routeModules"; - -export const SingleFetchRedirectSymbol = Symbol("SingleFetchRedirect"); - -type SingleFetchRedirectResult = { - redirect: string; - status: number; - revalidate: boolean; - reload: boolean; - replace: boolean; -}; -export type SingleFetchResult = - | { data: unknown } - | { error: unknown } - | SingleFetchRedirectResult; - -export type SingleFetchResults = { - [key: string]: SingleFetchResult; - [SingleFetchRedirectSymbol]?: SingleFetchRedirectResult; -}; - -// We can't use a 3xx status or else the `fetch()` would follow the redirect. -// We need to communicate the redirect back as data so we can act on it in the -// client side router. We use a 202 to avoid any automatic caching we might -// get from a 200 since a "temporary" redirect should not be cached. This lets -// the user control cache behavior via Cache-Control -export const SINGLE_FETCH_REDIRECT_STATUS = 202; - -export function getSingleFetchDataStrategy({ - isActionDataRequest, - loadRouteIds, -}: { - isActionDataRequest?: boolean; - loadRouteIds?: string[]; -} = {}): DataStrategyFunction { - return async ({ request, matches }: DataStrategyFunctionArgs) => { - // Don't call loaders on action data requests - if (isActionDataRequest && request.method === "GET") { - return {}; - } - - // Only run opt-in loaders when fine-grained revalidation is enabled - let matchesToLoad = loadRouteIds - ? matches.filter((m) => loadRouteIds.includes(m.route.id)) - : matches; - let results = await Promise.all( - matchesToLoad.map((match) => match.resolve()) - ); - return results.reduce( - (acc, result, i) => - Object.assign(acc, { [matchesToLoad[i].route.id]: result }), - {} - ); - }; -} - -export async function singleFetchAction( - build: ServerBuild, - serverMode: ServerMode, - staticHandler: StaticHandler, - request: Request, - handlerUrl: URL, - loadContext: AppLoadContext, - handleError: (err: unknown) => void -): Promise<{ result: SingleFetchResult; headers: Headers; status: number }> { - try { - let handlerRequest = new Request(handlerUrl, { - method: request.method, - body: request.body, - headers: request.headers, - signal: request.signal, - ...(request.body ? { duplex: "half" } : undefined), - }); - - let result = await staticHandler.query(handlerRequest, { - requestContext: loadContext, - skipLoaderErrorBubbling: true, - dataStrategy: getSingleFetchDataStrategy({ - isActionDataRequest: true, - }), - }); - - // Unlike `handleDataRequest`, when singleFetch is enabled, query does - // let non-Response return values through - if (isResponse(result)) { - return { - result: getSingleFetchRedirect( - result.status, - result.headers, - build.basename - ), - headers: result.headers, - status: SINGLE_FETCH_REDIRECT_STATUS, - }; - } - - let context = result; - let headers = getDocumentHeaders(build, context); - - if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) { - return { - result: getSingleFetchRedirect( - context.statusCode, - headers, - build.basename - ), - headers, - status: SINGLE_FETCH_REDIRECT_STATUS, - }; - } - - // Sanitize errors outside of development environments - if (context.errors) { - Object.values(context.errors).forEach((err) => { - // @ts-expect-error This is "private" from users but intended for internal use - if (!isRouteErrorResponse(err) || err.error) { - handleError(err); - } - }); - context.errors = sanitizeErrors(context.errors, serverMode); - } - - let singleFetchResult: SingleFetchResult; - if (context.errors) { - singleFetchResult = { error: Object.values(context.errors)[0] }; - } else { - singleFetchResult = { data: Object.values(context.actionData || {})[0] }; - } - - return { - result: singleFetchResult, - headers, - status: context.statusCode, - }; - } catch (error) { - handleError(error); - // These should only be internal remix errors, no need to deal with responseStubs - return { - result: { error }, - headers: new Headers(), - status: 500, - }; - } -} - -export async function singleFetchLoaders( - build: ServerBuild, - serverMode: ServerMode, - staticHandler: StaticHandler, - request: Request, - handlerUrl: URL, - loadContext: AppLoadContext, - handleError: (err: unknown) => void -): Promise<{ result: SingleFetchResults; headers: Headers; status: number }> { - try { - let handlerRequest = new Request(handlerUrl, { - headers: request.headers, - signal: request.signal, - }); - let loadRouteIds = - new URL(request.url).searchParams.get("_routes")?.split(",") || undefined; - - let result = await staticHandler.query(handlerRequest, { - requestContext: loadContext, - skipLoaderErrorBubbling: true, - dataStrategy: getSingleFetchDataStrategy({ - loadRouteIds, - }), - }); - - if (isResponse(result)) { - return { - result: { - [SingleFetchRedirectSymbol]: getSingleFetchRedirect( - result.status, - result.headers, - build.basename - ), - }, - headers: result.headers, - status: SINGLE_FETCH_REDIRECT_STATUS, - }; - } - - let context = result; - let headers = getDocumentHeaders(build, context); - - if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) { - return { - result: { - [SingleFetchRedirectSymbol]: getSingleFetchRedirect( - context.statusCode, - headers, - build.basename - ), - }, - headers, - status: SINGLE_FETCH_REDIRECT_STATUS, - }; - } - - // Sanitize errors outside of development environments - if (context.errors) { - Object.values(context.errors).forEach((err) => { - // @ts-expect-error This is "private" from users but intended for internal use - if (!isRouteErrorResponse(err) || err.error) { - handleError(err); - } - }); - context.errors = sanitizeErrors(context.errors, serverMode); - } - - // Aggregate results based on the matches we intended to load since we get - // `null` values back in `context.loaderData` for routes we didn't load - let results: SingleFetchResults = {}; - let loadedMatches = loadRouteIds - ? context.matches.filter( - (m) => m.route.loader && loadRouteIds!.includes(m.route.id) - ) - : context.matches; - - loadedMatches.forEach((m) => { - let data = context.loaderData?.[m.route.id]; - let error = context.errors?.[m.route.id]; - if (error !== undefined) { - results[m.route.id] = { error }; - } else if (data !== undefined) { - results[m.route.id] = { data }; - } - }); - - return { - result: results, - headers, - status: context.statusCode, - }; - } catch (error: unknown) { - handleError(error); - // These should only be internal remix errors, no need to deal with responseStubs - return { - result: { root: { error } }, - headers: new Headers(), - status: 500, - }; - } -} - -export function getSingleFetchRedirect( - status: number, - headers: Headers, - basename: string | undefined -): SingleFetchRedirectResult { - let redirect = headers.get("Location")!; - - if (basename) { - redirect = stripBasename(redirect, basename) || redirect; - } - - return { - redirect, - status, - revalidate: - // Technically X-Remix-Revalidate isn't needed here - that was an implementation - // detail of ?_data requests as our way to tell the front end to revalidate when - // we didn't have a response body to include that information in. - // With single fetch, we tell the front end via this revalidate boolean field. - // However, we're respecting it for now because it may be something folks have - // used in their own responses - // TODO(v3): Consider removing or making this official public API - headers.has("X-Remix-Revalidate") || headers.has("Set-Cookie"), - reload: headers.has("X-Remix-Reload-Document"), - replace: headers.has("X-Remix-Replace"), - }; -} - -// Note: If you change this function please change the corresponding -// decodeViaTurboStream function in server-runtime -export function encodeViaTurboStream( - data: any, - requestSignal: AbortSignal, - streamTimeout: number | undefined, - serverMode: ServerMode -) { - let controller = new AbortController(); - // How long are we willing to wait for all of the promises in `data` to resolve - // before timing out? We default this to 50ms shorter than the default value for - // `ABORT_DELAY` in our built-in `entry.server.tsx` so that once we reject we - // have time to flush the rejections down through React's rendering stream before ` - // we call abort() on that. If the user provides their own it's up to them to - // decouple the aborting of the stream from the aborting of React's renderToPipeableStream - let timeoutId = setTimeout( - () => controller.abort(new Error("Server Timeout")), - typeof streamTimeout === "number" ? streamTimeout : 4950 - ); - requestSignal.addEventListener("abort", () => clearTimeout(timeoutId)); - - return encode(data, { - signal: controller.signal, - plugins: [ - (value) => { - // Even though we sanitized errors on context.errors prior to responding, - // we still need to handle this for any deferred data that rejects with an - // Error - as those will not be sanitized yet - if (value instanceof Error) { - let { name, message, stack } = - serverMode === ServerMode.Production - ? sanitizeError(value, serverMode) - : value; - return ["SanitizedError", name, message, stack]; - } - - if (value instanceof ErrorResponseImpl) { - let { data, status, statusText } = value; - return ["ErrorResponse", data, status, statusText]; - } - - if ( - value && - typeof value === "object" && - SingleFetchRedirectSymbol in value - ) { - return ["SingleFetchRedirect", value[SingleFetchRedirectSymbol]]; - } - }, - ], - postPlugins: [ - (value) => { - if (!value) return; - if (typeof value !== "object") return; - - return [ - "SingleFetchClassInstance", - Object.fromEntries(Object.entries(value)), - ]; - }, - () => ["SingleFetchFallback"], - ], - }); -} - -export function data(value: T, init?: number | ResponseInit) { - return routerData(value, init); -} - -type Serializable = - | undefined - | null - | boolean - | string - | symbol - | number - | bigint - | Date - | URL - | RegExp - | Error - | ReadonlyArray - | Array - | { [key: PropertyKey]: Serializable } - | Map - | Set - | Promise; - -// prettier-ignore -type Serialize = - T extends void ? undefined : - - // First, let type stay as-is if its already serializable... - T extends Serializable ? T : - - // ...then don't allow functions to be serialized... - T extends (...args: any[]) => unknown ? undefined : - - // ...lastly handle inner types for all container types allowed by `turbo-stream` - - // Promise - T extends Promise ? Promise> : - - // Map & Set - T extends Map ? Map, Serialize> : - T extends Set ? Set> : - - // Array - T extends [] ? [] : - T extends readonly [infer F, ...infer R] ? [Serialize, ...Serialize] : - T extends Array ? Array> : - T extends readonly unknown[] ? readonly Serialize[] : - - // Record - T extends Record ? {[K in keyof T]: Serialize} : - - undefined - -// prettier-ignore -type ClientData = - T extends TypedResponse ? Jsonify : - T extends TypedDeferredData ? U : - T - -// prettier-ignore -type ServerData = - T extends TypedResponse ? Jsonify : - T extends TypedDeferredData ? Serialize : - T extends DataWithResponseInit ? Serialize : - Serialize - -// Backwards-compatible type for Remix v2 where json/defer still use the old types, -// and only non-json/defer returns use the new types. This allows for incremental -// migration of loaders to return naked objects. In the next major version, -// json/defer will be removed so everything will use the new simplified typings. -// prettier-ignore -export type SerializeFrom = - T extends (...args: infer Args) => infer Return ? - Args extends [ClientLoaderFunctionArgs | ClientActionFunctionArgs] ? ClientData> : - ServerData> - : - T - -type ServerLoader = (args: LoaderFunctionArgs) => T; -type ClientLoader = (args: ClientLoaderFunctionArgs) => T; - -class TestClass { - constructor(public a: string, public b: Date) { - this.a = a; - this.b = b; - } - - testmethod() {} -} - -interface TestInterface { - undefined: undefined; - null: null; - boolean: boolean; - string: string; - symbol: symbol; - number: number; - bigint: bigint; - Date: Date; - URL: URL; - RegExp: RegExp; - Error: Error; - Array: Array; - ReadonlyArray: ReadonlyArray; - Set: Set; - Map: Map; -} - -type Recursive = { - a: string; - b: Date; - recursive?: Recursive; -}; - -type Pretty = { [K in keyof T]: T[K] } & {}; - -// prettier-ignore -// eslint-disable-next-line -type _tests = [ - Expect>, undefined>>, - Expect; - ReadonlyArray: ReadonlyArray; - Set: Set, - Map: Map, - TestInterface: TestInterface, - Recursive: Recursive - }>>, { - undefined: undefined, - null: null, - boolean: boolean, - string: string, - symbol: symbol, - number: number, - bigint: bigint, - Date: Date, - URL: URL, - RegExp: RegExp, - Error: Error, - Array: Array; - ReadonlyArray: ReadonlyArray; - Set: Set, - Map: Map, - TestInterface: TestInterface - Recursive: Recursive - }>>, - Expect, - ReadonlyArray, - Set, - Map, - ]>>, [ - undefined, - null, - boolean, - string, - symbol, - number, - bigint, - Date, - URL, - RegExp, - Error, - Array, - ReadonlyArray, - Set, - Map, - ]>>, - Expect, - ReadonlyArray, - Set, - Map, - ]>>>, [ - undefined, - null, - boolean, - string, - symbol, - number, - bigint, - Date, - URL, - RegExp, - Error, - Array, - ReadonlyArray, - Set, - Map, - ]>>, - - Expect void, - class: TestClass - }>>, { - function: undefined, - class: { - a: string - b: Date, - testmethod: undefined - }, - }>>, - - Expect void, - class: TestClass - }>>, { - function: () => void, - class: TestClass - }>>, - - Expect>>>, { a: string, b: string }>>, - Expect}>>>>, { a: string, b: Promise }>>, - - // non-function backcompat - Expect, {a: string, b: Date}>>, - - Expect - | TypedDeferredData<{ e: string; f: Promise }> - | DataWithResponseInit<{ g: string; h: Date }> - >>, - | { a: string; b: Date } - | Jsonify<{ c: string; d: Date }> - | { e: string; f: Promise } - | { g: string; h: Date } - >>, -] diff --git a/packages/remix-server-runtime/tsconfig.json b/packages/remix-server-runtime/tsconfig.json deleted file mode 100644 index 57baa337e08..00000000000 --- a/packages/remix-server-runtime/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "include": ["**/*.ts"], - "exclude": ["dist", "__tests__", "node_modules"], - "compilerOptions": { - "lib": ["DOM", "DOM.Iterable", "ES2022"], - "target": "ES2022", - - "moduleResolution": "Bundler", - "allowSyntheticDefaultImports": true, - "strict": true, - "declaration": true, - "emitDeclarationOnly": true, - "rootDir": ".", - "outDir": "../../build/node_modules/@remix-run/server-runtime/dist", - - // Avoid naming conflicts between lib.dom.d.ts and globals.ts - "skipLibCheck": true - } -} diff --git a/packages/remix-server-runtime/typecheck.ts b/packages/remix-server-runtime/typecheck.ts deleted file mode 100644 index 7f6ffeab236..00000000000 --- a/packages/remix-server-runtime/typecheck.ts +++ /dev/null @@ -1,15 +0,0 @@ -// typecheck that expression is assignable to type -export function expectType(_expression: T) {} - -// prettier-ignore -// adapted from https://github.com/type-challenges/type-challenges/blob/main/utils/index.d.ts -export type Equal = - (() => T extends X ? 1 : 2) extends - (() => T extends Y ? 1 : 2) ? true : false - -// adapted from https://github.com/type-challenges/type-challenges/blob/main/utils/index.d.ts -export type Expect = T; - -// looser, lazy equality check for recursive types -// prettier-ignore -export type MutualExtends = [A] extends [B] ? [B] extends [A] ? true : false : false diff --git a/packages/remix-server-runtime/upload/errors.ts b/packages/remix-server-runtime/upload/errors.ts deleted file mode 100644 index e5ed3d42f6b..00000000000 --- a/packages/remix-server-runtime/upload/errors.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class MaxPartSizeExceededError extends Error { - constructor(public field: string, public maxBytes: number) { - super(`Field "${field}" exceeded upload size of ${maxBytes} bytes.`); - } -} diff --git a/packages/remix-server-runtime/upload/memoryUploadHandler.ts b/packages/remix-server-runtime/upload/memoryUploadHandler.ts deleted file mode 100644 index 27dec693b57..00000000000 --- a/packages/remix-server-runtime/upload/memoryUploadHandler.ts +++ /dev/null @@ -1,50 +0,0 @@ -import type { UploadHandler } from "../formData"; -import { MaxPartSizeExceededError } from "./errors"; - -export type MemoryUploadHandlerFilterArgs = { - filename?: string; - contentType: string; - name: string; -}; - -export type MemoryUploadHandlerOptions = { - /** - * The maximum upload size allowed. If the size is exceeded an error will be thrown. - * Defaults to 3000000B (3MB). - */ - maxPartSize?: number; - /** - * - * @param filename - * @param mimetype - * @param encoding - */ - filter?(args: MemoryUploadHandlerFilterArgs): boolean | Promise; -}; - -export function createMemoryUploadHandler({ - filter, - maxPartSize = 3000000, -}: MemoryUploadHandlerOptions = {}): UploadHandler { - return async ({ filename, contentType, name, data }) => { - if (filter && !(await filter({ filename, contentType, name }))) { - return undefined; - } - - let size = 0; - let chunks = []; - for await (let chunk of data) { - size += chunk.byteLength; - if (size > maxPartSize) { - throw new MaxPartSizeExceededError(name, maxPartSize); - } - chunks.push(chunk); - } - - if (typeof filename === "string") { - return new File(chunks, filename, { type: contentType }); - } - - return await new Blob(chunks, { type: contentType }).text(); - }; -} diff --git a/packages/remix-server-runtime/warnings.ts b/packages/remix-server-runtime/warnings.ts deleted file mode 100644 index 45acd960108..00000000000 --- a/packages/remix-server-runtime/warnings.ts +++ /dev/null @@ -1,8 +0,0 @@ -const alreadyWarned: { [message: string]: boolean } = {}; - -export function warnOnce(condition: boolean, message: string): void { - if (!condition && !alreadyWarned[message]) { - alreadyWarned[message] = true; - console.warn(message); - } -} diff --git a/packages/remix-testing/CHANGELOG.md b/packages/remix-testing/CHANGELOG.md deleted file mode 100644 index 0f4d198bb04..00000000000 --- a/packages/remix-testing/CHANGELOG.md +++ /dev/null @@ -1,677 +0,0 @@ -# `@remix-run/testing` - -## 2.16.7 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@2.16.7` - - `@remix-run/react@2.16.7` - -## 2.16.6 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.16.6` - - `@remix-run/node@2.16.6` - -## 2.16.5 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@2.16.5` - - `@remix-run/react@2.16.5` - -## 2.16.4 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@2.16.4` - - `@remix-run/react@2.16.4` - -## 2.16.3 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@2.16.3` - - `@remix-run/react@2.16.3` - -## 2.16.2 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.16.2` - - `@remix-run/node@2.16.2` - -## 2.16.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.16.1` - - `@remix-run/node@2.16.1` - -## 2.16.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.16.0` - - `@remix-run/node@2.16.0` - -## 2.15.3 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.15.3` - - `@remix-run/node@2.15.3` - -## 2.15.2 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.15.2` - - `@remix-run/node@2.15.2` - -## 2.15.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@2.15.1` - - `@remix-run/react@2.15.1` - -## 2.15.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@2.15.0` - - `@remix-run/react@2.15.0` - -## 2.14.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.14.0` - - `@remix-run/node@2.14.0` - -## 2.13.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@2.13.1` - - `@remix-run/react@2.13.1` - -## 2.13.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.13.0` - - `@remix-run/node@2.13.0` - -## 2.12.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@2.12.1` - - `@remix-run/react@2.12.1` - -## 2.12.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.12.0` - - `@remix-run/node@2.12.0` - -## 2.11.2 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.11.2` - - `@remix-run/node@2.11.2` - -## 2.11.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.11.1` - - `@remix-run/node@2.11.1` - -## 2.11.0 - -### Minor Changes - -- Rename `future.unstable_fogOfWar` to `future.unstable_lazyRouteDiscovery` for clarity ([#9763](https://github.com/remix-run/remix/pull/9763)) - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@2.11.0` - - `@remix-run/react@2.11.0` - -## 2.10.3 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.10.3` - - `@remix-run/node@2.10.3` - -## 2.10.2 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.10.2` - - `@remix-run/node@2.10.2` - -## 2.10.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.10.1` - - `@remix-run/node@2.10.1` - -## 2.10.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.10.0` - - `@remix-run/node@2.10.0` - -## 2.9.2 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.9.2` - - `@remix-run/node@2.9.2` - -## 2.9.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.9.1` - - `@remix-run/node@2.9.1` - -## 2.9.0 - -### Minor Changes - -- New `future.unstable_singleFetch` flag ([#8773](https://github.com/remix-run/remix/pull/8773)) - - - Naked objects returned from loaders/actions are no longer automatically converted to JSON responses. They'll be streamed as-is via `turbo-stream` so `Date`'s will become `Date` through `useLoaderData()` - - You can return naked objects with `Promise`'s without needing to use `defer()` - including nested `Promise`'s - - If you need to return a custom status code or custom response headers, you can still use the `defer` utility - - `` is no longer used. Instead, you should `export const streamTimeout` from `entry.server.tsx` and the remix server runtime will use that as the delay to abort the streamed response - - If you export your own streamTimeout, you should decouple that from aborting the react `renderToPipeableStream`. You should always ensure that react is aborted _afer_ the stream is aborted so that abort rejections can be flushed down - - Actions no longer automatically revalidate on 4xx/5xx responses (via RR `future.unstable_skipActionErrorRevalidation` flag) - you can return a 2xx to opt-into revalidation or use `shouldRevalidate` - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@2.9.0` - - `@remix-run/react@2.9.0` - -## 2.8.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.8.1` - - `@remix-run/node@2.8.1` - -## 2.8.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.8.0` - - `@remix-run/node@2.8.0` - -## 2.7.2 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@2.7.2` - - `@remix-run/react@2.7.2` - -## 2.7.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@2.7.1` - - `@remix-run/react@2.7.1` - -## 2.7.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.7.0` - - `@remix-run/node@2.7.0` - -## 2.6.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.6.0` - - `@remix-run/node@2.6.0` - -## 2.5.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.5.1` - - `@remix-run/node@2.5.1` - -## 2.5.0 - -### Minor Changes - -- Add unstable support for "SPA Mode" ([#8457](https://github.com/remix-run/remix/pull/8457)) - - You can opt into SPA Mode by setting `unstable_ssr: false` in your Remix Vite plugin config: - - ```js - // vite.config.ts - import { unstable_vitePlugin as remix } from "@remix-run/dev"; - import { defineConfig } from "vite"; - - export default defineConfig({ - plugins: [remix({ unstable_ssr: false })], - }); - ``` - - Development in SPA Mode is just like a normal Remix app, and still uses the Remix dev server for HMR/HDR: - - ```sh - remix vite:dev - ``` - - Building in SPA Mode will generate an `index.html` file in your client assets directory: - - ```sh - remix vite:build - ``` - - To run your SPA, you serve your client assets directory via an HTTP server: - - ```sh - npx http-server build/client - ``` - - For more information, please refer to the [SPA Mode docs](https://remix.run/future/spa-mode). - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.5.0` - - `@remix-run/node@2.5.0` - -## 2.4.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.4.1` - - `@remix-run/node@2.4.1` - -## 2.4.0 - -### Minor Changes - -- Add support for `clientLoader`/`clientAction`/`HydrateFallback` route exports ([RFC](https://github.com/remix-run/remix/discussions/7634)). ([#8173](https://github.com/remix-run/remix/pull/8173)) -- Add a new `future.v3_relativeSplatPath` flag to implement a breaking bug fix to relative routing when inside a splat route. For more information, please see the React Router [`6.21.0` Release Notes](https://github.com/remix-run/react-router/blob/release-next/CHANGELOG.md#futurev7_relativesplatpath) and the [`useResolvedPath` docs](https://remix.run/hooks/use-resolved-path#splat-paths). ([#8216](https://github.com/remix-run/remix/pull/8216)) - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.4.0` - - `@remix-run/node@2.4.0` - -## 2.3.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.3.1` - - `@remix-run/node@2.3.1` - -## 2.3.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.3.0` - - `@remix-run/node@2.3.0` - -## 2.2.0 - -### Minor Changes - -- Unstable Vite support for Node-based Remix apps ([#7590](https://github.com/remix-run/remix/pull/7590)) - - `remix build` 👉 `vite build && vite build --ssr` - - `remix dev` 👉 `vite dev` - - Other runtimes (e.g. Deno, Cloudflare) not yet supported. - - See "Future > Vite" in the Remix Docs for details - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.2.0` - - `@remix-run/node@2.2.0` - -## 2.1.0 - -### Minor Changes - -- Remove the `unstable_` prefix from `createRemixStub` - after real-world experience, we're confident in the API and ready to commit to it ([#7647](https://github.com/remix-run/remix/pull/7647)) - - **Note**: This involves 1 small breaking change. The `` prop has been renamed to `` - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.1.0` - - `@remix-run/node@2.1.0` - -## 2.0.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.0.1` - - `@remix-run/node@2.0.1` - -## 2.0.0 - -### Major Changes - -- Drop React 17 support ([#7121](https://github.com/remix-run/remix/pull/7121)) -- Require Node >=18.0.0 ([#6939](https://github.com/remix-run/remix/pull/6939)) -- Remove `v2_normalizeFormMethod` future flag - all `formMethod` values will be normalized in v2 ([#6875](https://github.com/remix-run/remix/pull/6875)) -- Remove `v2_routeConvention` flag - the flat route file convention is now standard ([#6969](https://github.com/remix-run/remix/pull/6969)) -- Remove `v2_headers` flag - it is now the default behavior to use the deepest `headers` function in the route tree ([#6979](https://github.com/remix-run/remix/pull/6979)) -- Remove `v2_errorBoundary` flag and `CatchBoundary` implementation ([#6906](https://github.com/remix-run/remix/pull/6906)) -- The route `meta` API now defaults to the new "V2 Meta" API ([#6958](https://github.com/remix-run/remix/pull/6958)) - - Please refer to the ([docs](https://remix.run/docs/en/2.0.0/route/meta) and [Preparing for V2](https://remix.run/docs/en/2.0.0/start/v2#route-meta) guide for more information. -- Promote the `future.v2_dev` flag in `remix.config.js` to a root level `dev` config ([#7002](https://github.com/remix-run/remix/pull/7002)) -- Removed support for "magic exports" from the `remix` package. This package can be removed from your `package.json` and you should update all imports to use the source `@remix-run/*` packages: ([#6895](https://github.com/remix-run/remix/pull/6895)) - - ```diff - - import type { ActionArgs } from "remix"; - - import { json, useLoaderData } from "remix"; - + import type { ActionArgs } from "@remix-run/node"; - + import { json } from "@remix-run/node"; - + import { useLoaderData } from "@remix-run/react"; - ``` - -### Minor Changes - -- `unstable_createRemixStub` now supports adding `meta`/`links` functions on stubbed Remix routes ([#7186](https://github.com/remix-run/remix/pull/7186)) - - ⚠️ `unstable_createRemixStub` no longer supports the `element`/`errorElement` properties on routes. You must use `Component`/`ErrorBoundary` to match what you would export from a Remix route module. -- Update Remix to use React Router `route.lazy` for module loading ([#7133](https://github.com/remix-run/remix/pull/7133)) - -### Patch Changes - -- Fix types for `StubRouteObject` `children` property ([#7098](https://github.com/remix-run/remix/pull/7098)) -- Updated dependencies: - - `@remix-run/react@2.0.0` - - `@remix-run/node@2.0.0` - - [`react-router-dom@6.16.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.16.0) - - [`@remix-run/router@1.9.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#190) - -## 1.19.3 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@1.19.3` - - `@remix-run/react@1.19.3` - -## 1.19.2 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@1.19.2` - - `@remix-run/react@1.19.2` - -## 1.19.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@1.19.1` - - `@remix-run/react@1.19.1` - -## 1.19.0 - -### Patch Changes - -- Bump RR 6.14.2 ([#6854](https://github.com/remix-run/remix/pull/6854)) -- Updated dependencies: - - `@remix-run/react@1.19.0` - - `@remix-run/node@1.19.0` - - [`react-router-dom@6.14.2`](https://github.com/remix-run/react-router/releases/tag/react-router%406.14.2) - - [`@remix-run/router@1.7.2`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#172) - -## 1.18.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@1.18.1` - - `@remix-run/node@1.18.1` - - [`react-router-dom@6.14.1`](https://github.com/remix-run/react-router/releases/tag/react-router%406.14.1) - - [`@remix-run/router@1.7.1`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#171) - -## 1.18.0 - -### Minor Changes - -- stabilize v2 dev server ([#6615](https://github.com/remix-run/remix/pull/6615)) - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@1.18.0` - - `@remix-run/node@1.18.0` - -## 1.17.1 - -### Patch Changes - -- Updated dependencies: - - [`react-router-dom@6.13.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.13.0) - - `@remix-run/react@1.17.1` - - `@remix-run/node@1.17.1` - -## 1.17.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@1.17.0` - - `@remix-run/node@1.17.0` - - [`react-router-dom@6.12.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.12.0) - - [`@remix-run/router@1.6.3`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#163) - -## 1.16.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@1.16.1` - - `@remix-run/node@1.16.1` - -## 1.16.0 - -### Minor Changes - -- Enable support for [CSS Modules](https://github.com/css-modules/css-modules), [Vanilla Extract](http://vanilla-extract.style) and CSS side-effect imports ([#6046](https://github.com/remix-run/remix/pull/6046)) - - These CSS bundling features were previously only available via `future.unstable_cssModules`, `future.unstable_vanillaExtract` and `future.unstable_cssSideEffectImports` options in `remix.config.js`, but they have now been stabilized. - - In order to use these features, check out our guide to [CSS bundling](https://remix.run/docs/en/1.16.0/guides/styling#css-bundling) in your project. - -### Patch Changes - -- feat(remix-testing): cast types to use Remix type definitions + allow passing context ([#6065](https://github.com/remix-run/remix/pull/6065)) -- Updated dependencies: - - [`react-router-dom@6.11.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.11.0) - - [`@remix-run/router@1.6.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#160) - - `@remix-run/react@1.16.0` - - `@remix-run/node@1.16.0` - -## 1.15.0 - -### Patch Changes - -- Bumped React Router dependencies to the latest version. [See the release notes for more details.](https://github.com/remix-run/react-router/releases/tag/react-router%406.10.0) ([`e14699547`](https://github.com/remix-run/remix/commit/e1469954737a2e45636b6aef73dc9ae251fb1b20)) -- Updated dependencies: - - `@remix-run/react@1.15.0` - - `@remix-run/node@1.15.0` - -## 1.14.3 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@1.14.3` - - `@remix-run/react@1.14.3` - -## 1.14.2 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@1.14.2` - - `@remix-run/react@1.14.2` - -## 1.14.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@1.14.1` - - `@remix-run/node@1.14.1` - -## 1.14.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@1.14.0` - - `@remix-run/node@1.14.0` - - `@remix-run/router@1.3.3` - - `react-router-dom@8.6.2` - -## 1.13.0 - -### Minor Changes - -- Add built-in support for PostCSS via the `future.unstable_postcss` feature flag ([#5229](https://github.com/remix-run/remix/pull/5229)) -- Add built-in support for Tailwind via the `future.unstable_tailwind` feature flag ([#5229](https://github.com/remix-run/remix/pull/5229)) - -### Patch Changes - -- Bump React Router dependencies to the latest version. [See the release notes for more details.](https://github.com/remix-run/react-router/releases/tag/react-router%406.8.1) ([#5389](https://github.com/remix-run/remix/pull/5389)) -- Updated dependencies: - - `@remix-run/react@1.13.0` - - `@remix-run/node@1.13.0` - -## 1.12.0 - -### Patch Changes - -- Ensure all routes have IDs when using the `createRemixStub` testing helper ([#5128](https://github.com/remix-run/remix/pull/5128)) -- Bump React Router dependencies to the latest version. [See the release notes for more details.](https://github.com/remix-run/react-router/releases/tag/react-router%406.8.0) ([#5242](https://github.com/remix-run/remix/pull/5242)) -- Updated dependencies: - - `@remix-run/react@1.12.0` - - `@remix-run/node@1.12.0` - -## 1.11.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@1.11.1` - - `@remix-run/react@1.11.1` - -## 1.11.0 - -### Minor Changes - -- Added support for [Vanilla Extract](https://vanilla-extract.style) via the `unstable_vanillaExtract` future flag. **IMPORTANT:** Features marked with `unstable` are … unstable. While we're confident in the use cases they solve, the API and implementation may change without a major version bump. ([#5040](https://github.com/remix-run/remix/pull/5040)) -- Add support for CSS side-effect imports via the `unstable_cssSideEffectImports` future flag. **IMPORTANT:** Features marked with `unstable` are … unstable. While we're confident in the use cases they solve, the API and implementation may change without a major version bump. ([#4919](https://github.com/remix-run/remix/pull/4919)) -- Add support for CSS Modules via the `unstable_cssModules` future flag. **IMPORTANT:** Features marked with `unstable` are … unstable. While we're confident in the use cases they solve, the API and implementation may change without a major version bump. ([#4852](https://github.com/remix-run/remix/pull/4852)) - -### Patch Changes - -- Introduces the `defer()` API from `@remix-run/router` with support for server-rendering and HTTP streaming. This utility allows you to defer values returned from `loader` functions by returning promises instead of resolved values. This has been refered to as _"sending a promise over the wire"_. ([#4920](https://github.com/remix-run/remix/pull/4920)) - - Informational Resources: - - - - - - - Documentation Resources (better docs specific to Remix are in the works): - - - - - - - - - - -- Updated dependencies: - - `@remix-run/react@1.11.0` - - `@remix-run/node@1.11.0` - -## 1.10.1 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@1.10.1` - - `@remix-run/node@1.10.1` - -## 1.10.0 - -### Patch Changes - -- Remove internal `installGlobals` function now that `@remix-run/web-form-data` includes support for passing a `HTMLFormElement` ([#4755](https://github.com/remix-run/remix/pull/4755)) -- Use React Router data APIs directly ([#4915](https://github.com/remix-run/remix/pull/4915)) -- Updated dependencies: - - `@remix-run/react@1.10.0` - - `@remix-run/node@1.10.0` - -## 1.9.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@1.9.0` - - `@remix-run/server-runtime@1.9.0` - - `@remix-run/node@1.9.0` diff --git a/packages/remix-testing/README.md b/packages/remix-testing/README.md deleted file mode 100644 index 40685a7476f..00000000000 --- a/packages/remix-testing/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Welcome to Remix! - -[Remix](https://remix.run) is a web framework that helps you build better websites with React. - -To get started, open a new shell and run: - -```sh -npx create-remix@latest -``` - -Then follow the prompts you see in your terminal. - -For more information about Remix, [visit remix.run](https://remix.run)! diff --git a/packages/remix-testing/__tests__/stub-test.tsx b/packages/remix-testing/__tests__/stub-test.tsx deleted file mode 100644 index 87ad7f968c4..00000000000 --- a/packages/remix-testing/__tests__/stub-test.tsx +++ /dev/null @@ -1,227 +0,0 @@ -import * as React from "react"; -import { render, screen, waitFor } from "@testing-library/react"; -import user from "@testing-library/user-event"; -import { createRemixStub } from "@remix-run/testing"; -import { - Form, - Outlet, - useActionData, - useFetcher, - useLoaderData, - useMatches, -} from "@remix-run/react"; -import type { LoaderFunctionArgs } from "@remix-run/node"; -import { json } from "@remix-run/node"; - -test("renders a route", () => { - let RemixStub = createRemixStub([ - { - path: "/", - Component: () =>
HOME
, - }, - ]); - - render(); - - expect(screen.getByText("HOME")).toBeInTheDocument(); -}); - -test("renders a nested route", () => { - let RemixStub = createRemixStub([ - { - Component() { - return ( -
-

ROOT

- -
- ); - }, - children: [ - { - path: "/", - Component: () =>
INDEX
, - }, - ], - }, - ]); - - render(); - - expect(screen.getByText("ROOT")).toBeInTheDocument(); - expect(screen.getByText("INDEX")).toBeInTheDocument(); -}); - -test("loaders work", async () => { - let RemixStub = createRemixStub([ - { - path: "/", - Component() { - let data = useLoaderData(); - return
Message: {data.message}
; - }, - loader() { - return json({ message: "hello" }); - }, - }, - ]); - - render(); - - await waitFor(() => screen.findByText("Message: hello")); -}); - -test("actions work", async () => { - let RemixStub = createRemixStub([ - { - path: "/", - Component() { - let data = useActionData() as { message: string } | undefined; - return ( - - - {data ?
Message: {data.message}
: null} - - ); - }, - action() { - return json({ message: "hello" }); - }, - }, - ]); - - render(); - - user.click(screen.getByText("Submit")); - await waitFor(() => screen.findByText("Message: hello")); -}); - -test("fetchers work", async () => { - let count = 0; - let RemixStub = createRemixStub([ - { - path: "/", - Component() { - let fetcher = useFetcher<{ count: number }>(); - return ( - - ); - }, - }, - { - path: "/api", - loader() { - return json({ count: ++count }); - }, - }, - ]); - - render(); - - user.click(screen.getByText("idle 0")); - await waitFor(() => screen.findByText("idle 1")); - - user.click(screen.getByText("idle 1")); - await waitFor(() => screen.findByText("idle 2")); -}); - -test("can pass a predefined loader", () => { - async function loader(_args: LoaderFunctionArgs) { - return json({ hi: "there" }); - } - - createRemixStub([ - { - path: "/example", - loader, - }, - ]); -}); - -test("can pass context values", async () => { - let RemixStub = createRemixStub( - [ - { - path: "/", - Component() { - let data = useLoaderData() as { context: string }; - return ( -
-
Context: {data.context}
- -
- ); - }, - loader({ context }) { - return json(context); - }, - children: [ - { - path: "hello", - Component() { - let data = useLoaderData() as { context: string }; - return
Context: {data.context}
; - }, - loader({ context }) { - return json(context); - }, - }, - ], - }, - ], - { context: "hello" } - ); - - render(); - - expect(await screen.findByTestId("root")).toHaveTextContent( - /context: hello/i - ); - expect(await screen.findByTestId("hello")).toHaveTextContent( - /context: hello/i - ); -}); - -test("all routes have ids", () => { - let RemixStub = createRemixStub([ - { - Component() { - return ( -
-

ROOT

- -
- ); - }, - children: [ - { - path: "/", - Component() { - let matches = useMatches(); - - return ( -
-

HOME

-
-                  {JSON.stringify(matches, null, 2)}
-                
-
- ); - }, - }, - ], - }, - ]); - - render(); - - let matchesTextContent = screen.getByTestId("matches").textContent; - // eslint-disable-next-line jest-dom/prefer-in-document - expect(matchesTextContent).toBeDefined(); - let matches = JSON.parse(matchesTextContent!); - let matchesWithoutIds = matches.filter((match: any) => match.id == null); - - expect(matchesWithoutIds).toHaveLength(0); -}); diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx deleted file mode 100644 index 1433659f686..00000000000 --- a/packages/remix-testing/create-remix-stub.tsx +++ /dev/null @@ -1,218 +0,0 @@ -import * as React from "react"; -import { - UNSAFE_convertRoutesToDataRoutes, - type HydrationState, - type InitialEntry, - type Router, - type ActionFunctionArgs as RRActionFunctionArgs, - type LoaderFunctionArgs as RRLoaderFunctionArgs, -} from "@remix-run/router"; -import { UNSAFE_RemixContext as RemixContext } from "@remix-run/react"; -import type { - UNSAFE_FutureConfig as FutureConfig, - UNSAFE_AssetsManifest as AssetsManifest, - UNSAFE_EntryRoute as EntryRoute, - UNSAFE_RouteModules as RouteModules, - UNSAFE_RemixContextObject as RemixContextObject, - MetaFunction, -} from "@remix-run/react"; -import type { - DataRouteObject, - IndexRouteObject, - NonIndexRouteObject, -} from "react-router-dom"; -import { createMemoryRouter, Outlet, RouterProvider } from "react-router-dom"; -import type { - ActionFunction, - AppLoadContext, - LinksFunction, - LoaderFunction, -} from "@remix-run/server-runtime"; - -interface StubIndexRouteObject - extends Omit< - IndexRouteObject, - "loader" | "action" | "element" | "errorElement" | "children" - > { - loader?: LoaderFunction; - action?: ActionFunction; - children?: StubRouteObject[]; - meta?: MetaFunction; - links?: LinksFunction; -} - -interface StubNonIndexRouteObject - extends Omit< - NonIndexRouteObject, - "loader" | "action" | "element" | "errorElement" | "children" - > { - loader?: LoaderFunction; - action?: ActionFunction; - children?: StubRouteObject[]; - meta?: MetaFunction; - links?: LinksFunction; -} - -type StubRouteObject = StubIndexRouteObject | StubNonIndexRouteObject; - -export interface RemixStubProps { - /** - * The initial entries in the history stack. This allows you to start a test with - * multiple locations already in the history stack (for testing a back navigation, etc.) - * The test will default to the last entry in initialEntries if no initialIndex is provided. - * e.g. initialEntries={["/home", "/about", "/contact"]} - */ - initialEntries?: InitialEntry[]; - - /** - * The initial index in the history stack to render. This allows you to start a test at a specific entry. - * It defaults to the last entry in initialEntries. - * e.g. - * initialEntries: ["/", "/events/123"] - * initialIndex: 1 // start at "/events/123" - */ - initialIndex?: number; - - /** - * Used to set the route's initial loader and action data. - * e.g. hydrationData={{ - * loaderData: { "/contact": { locale: "en-US" } }, - * actionData: { "/login": { errors: { email: "invalid email" } }} - * }} - */ - hydrationData?: HydrationState; - - /** - * Future flags mimicking the settings in remix.config.js - */ - future?: Partial; -} - -export function createRemixStub( - routes: StubRouteObject[], - context: AppLoadContext = {} -) { - return function RemixStub({ - initialEntries, - initialIndex, - hydrationData, - future, - }: RemixStubProps) { - let routerRef = React.useRef(); - let remixContextRef = React.useRef(); - - if (routerRef.current == null) { - remixContextRef.current = { - future: { - v3_fetcherPersist: future?.v3_fetcherPersist === true, - v3_relativeSplatPath: future?.v3_relativeSplatPath === true, - v3_lazyRouteDiscovery: future?.v3_lazyRouteDiscovery === true, - v3_singleFetch: future?.v3_singleFetch === true, - }, - manifest: { - routes: {}, - entry: { imports: [], module: "" }, - url: "", - version: "", - }, - routeModules: {}, - isSpaMode: false, - }; - - // Update the routes to include context in the loader/action and populate - // the manifest and routeModules during the walk - let patched = processRoutes( - // @ts-expect-error loader/action context types don't match :/ - UNSAFE_convertRoutesToDataRoutes(routes, (r) => r), - context, - remixContextRef.current.manifest, - remixContextRef.current.routeModules - ); - routerRef.current = createMemoryRouter(patched, { - initialEntries, - initialIndex, - hydrationData, - }); - } - - return ( - - - - ); - }; -} - -function processRoutes( - routes: StubRouteObject[], - context: AppLoadContext, - manifest: AssetsManifest, - routeModules: RouteModules, - parentId?: string -): DataRouteObject[] { - return routes.map((route) => { - if (!route.id) { - throw new Error( - "Expected a route.id in @remix-run/testing processRoutes() function" - ); - } - - // Patch in the Remix context to loaders/actions - let { loader, action } = route; - let newRoute: DataRouteObject = { - id: route.id, - path: route.path, - index: route.index, - Component: route.Component, - ErrorBoundary: route.ErrorBoundary, - action: action - ? (args: RRActionFunctionArgs) => action!({ ...args, context }) - : undefined, - loader: loader - ? (args: RRLoaderFunctionArgs) => loader!({ ...args, context }) - : undefined, - handle: route.handle, - shouldRevalidate: route.shouldRevalidate, - }; - - // Add the EntryRoute to the manifest - let entryRoute: EntryRoute = { - id: route.id, - path: route.path, - index: route.index, - parentId, - hasAction: route.action != null, - hasLoader: route.loader != null, - // When testing routes, you should just be stubbing loader/action, not - // trying to re-implement the full loader/clientLoader/SSR/hydration flow. - // That is better tested via E2E tests. - hasClientAction: false, - hasClientLoader: false, - hasErrorBoundary: route.ErrorBoundary != null, - module: "build/stub-path-to-module.js", // any need for this? - }; - manifest.routes[newRoute.id] = entryRoute; - - // Add the route to routeModules - routeModules[route.id] = { - default: route.Component || Outlet, - ErrorBoundary: route.ErrorBoundary || undefined, - handle: route.handle, - links: route.links, - meta: route.meta, - shouldRevalidate: route.shouldRevalidate, - }; - - if (route.children) { - newRoute.children = processRoutes( - route.children, - context, - manifest, - routeModules, - newRoute.id - ); - } - - return newRoute; - }); -} diff --git a/packages/remix-testing/index.ts b/packages/remix-testing/index.ts deleted file mode 100644 index 39eb89457bd..00000000000 --- a/packages/remix-testing/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type { RemixStubProps } from "./create-remix-stub"; -export { createRemixStub } from "./create-remix-stub"; diff --git a/packages/remix-testing/jest.config.js b/packages/remix-testing/jest.config.js deleted file mode 100644 index c5d645167a2..00000000000 --- a/packages/remix-testing/jest.config.js +++ /dev/null @@ -1,8 +0,0 @@ -/** @type {import('jest').Config} */ -module.exports = { - ...require("../../jest/jest.config.shared"), - displayName: "testing", - setupFiles: [], - testEnvironment: "jsdom", - setupFilesAfterEnv: ["./jest.setup.js", "@testing-library/jest-dom"], -}; diff --git a/packages/remix-testing/jest.setup.js b/packages/remix-testing/jest.setup.js deleted file mode 100644 index dab603502ce..00000000000 --- a/packages/remix-testing/jest.setup.js +++ /dev/null @@ -1,8 +0,0 @@ -const JSDOMFormData = global.FormData; -global.TextDecoder = require("util").TextDecoder; -global.TextEncoder = require("util").TextEncoder; -global.ReadableStream = require("stream/web").ReadableStream; -global.WritableStream = require("stream/web").WritableStream; - -require("@remix-run/node").installGlobals({ nativeFetch: true }); -global.FormData = JSDOMFormData; diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json deleted file mode 100644 index c527b16108b..00000000000 --- a/packages/remix-testing/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "@remix-run/testing", - "version": "2.16.7", - "description": "Testing utilities for Remix apps", - "homepage": "https://remix.run", - "bugs": { - "url": "https://github.com/remix-run/remix/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/remix-run/remix", - "directory": "packages/remix-testing" - }, - "license": "MIT", - "main": "./dist/index.js", - "typings": "./dist/index.d.ts", - "module": "./dist/esm/index.js", - "scripts": { - "tsc": "tsc" - }, - "dependencies": { - "@remix-run/node": "workspace:*", - "@remix-run/react": "workspace:*", - "@remix-run/router": "1.23.0", - "react-router-dom": "6.30.0" - }, - "devDependencies": { - "@remix-run/server-runtime": "workspace:*", - "@remix-run/testing": "workspace:*", - "@types/node": "^18.17.1", - "@types/react": "^18.2.20", - "@types/react-dom": "^18.2.7", - "jest-environment-jsdom": "^29.7.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "typescript": "^5.1.6" - }, - "peerDependencies": { - "react": "^18.0.0", - "typescript": "^5.1.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - }, - "engines": { - "node": ">=18.0.0" - }, - "files": [ - "dist/", - "CHANGELOG.md", - "LICENSE.md", - "README.md" - ] -} diff --git a/packages/remix-testing/rollup.config.js b/packages/remix-testing/rollup.config.js deleted file mode 100644 index 9ca30d172a2..00000000000 --- a/packages/remix-testing/rollup.config.js +++ /dev/null @@ -1,72 +0,0 @@ -const path = require("node:path"); -const babel = require("@rollup/plugin-babel").default; -const nodeResolve = require("@rollup/plugin-node-resolve").default; -const copy = require("rollup-plugin-copy"); - -const { - copyToPlaygrounds, - createBanner, - getOutputDir, - isBareModuleId, -} = require("../../rollup.utils"); -const { name: packageName, version } = require("./package.json"); - -/** @returns {import("rollup").RollupOptions[]} */ -module.exports = function rollup() { - let sourceDir = path.join("packages", "remix-testing"); - let outputDir = getOutputDir(packageName); - let outputDist = path.join(outputDir, "dist"); - - let sharedPlugins = [ - babel({ - babelHelpers: "bundled", - exclude: /node_modules/, - extensions: [".ts", ".tsx"], - }), - nodeResolve({ extensions: [".ts", ".tsx"] }), - copyToPlaygrounds(), - ]; - - /** @type {import("rollup").RollupOptions} */ - let remixTestingCJS = { - external(id) { - return isBareModuleId(id); - }, - input: path.join(sourceDir, "index.ts"), - output: { - banner: createBanner(packageName, version), - dir: outputDist, - format: "cjs", - preserveModules: true, - exports: "auto", - }, - plugins: [ - ...sharedPlugins, - copy({ - targets: [ - { src: "LICENSE.md", dest: [outputDir, sourceDir] }, - { src: path.join(sourceDir, "package.json"), dest: outputDir }, - { src: path.join(sourceDir, "README.md"), dest: outputDir }, - ], - }), - ], - }; - - // The browser build of remix-testing is ESM so we can treeshake it. - /** @type {import("rollup").RollupOptions} */ - let remixTestingESM = { - external(id) { - return isBareModuleId(id); - }, - input: path.join(sourceDir, "index.ts"), - output: { - banner: createBanner(packageName, version), - dir: path.join(outputDist, "esm"), - format: "esm", - preserveModules: true, - }, - plugins: [...sharedPlugins], - }; - - return [remixTestingCJS, remixTestingESM]; -}; diff --git a/packages/remix-testing/tsconfig.json b/packages/remix-testing/tsconfig.json deleted file mode 100644 index 65fc76e33d8..00000000000 --- a/packages/remix-testing/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "include": ["**/*.ts", "**/*.tsx"], - "exclude": ["dist", "__tests__", "node_modules"], - "compilerOptions": { - "lib": ["DOM", "DOM.Iterable", "ES2022"], - "target": "ES2022", - "module": "ES2022", - "skipLibCheck": true, - - "moduleResolution": "Bundler", - "allowSyntheticDefaultImports": true, - "strict": true, - "jsx": "react", - "declaration": true, - "emitDeclarationOnly": true, - "rootDir": ".", - "outDir": "../../build/node_modules/@remix-run/testing/dist" - } -} diff --git a/packages/remix/CHANGELOG.md b/packages/remix/CHANGELOG.md deleted file mode 100644 index 8ec9b176ee2..00000000000 --- a/packages/remix/CHANGELOG.md +++ /dev/null @@ -1,3 +0,0 @@ -# `remix` - -See the `CHANGELOG.md` in individual Remix packages for all changes. diff --git a/packages/remix/README.md b/packages/remix/README.md deleted file mode 100644 index 5672c412241..00000000000 --- a/packages/remix/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Deprecated - -The `remix` package is no longer used for Remix modules. It was [officially deprecated in v1.6.0](https://github.com/remix-run/remix/releases/tag/v1.6.0) then finally [removed in v2.0.0](https://github.com/remix-run/remix/releases/tag/remix@2.0.0). This package should be removed from your project dependencies if you have it installed. - -For stats about Remix, please consider referring to @remix-run/router or @remix --run/server-runtime instead. - -# Welcome to Remix! - -[Remix](https://remix.run) is a web framework that helps you build better websites with React. - -To get started, open a new shell and run: - -```sh -npx create-remix@latest -``` - -Then follow the prompts you see in your terminal. - -For more information about Remix, [visit remix.run](https://remix.run)! diff --git a/packages/remix/index.ts b/packages/remix/index.ts deleted file mode 100644 index 39768044110..00000000000 --- a/packages/remix/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This class exists to prevent https://github.com/remix-run/remix/issues/2031 from occurring -export class RemixPackageNotUsedError extends Error { - constructor() { - super( - "The `remix` package is no longer used for Remix modules and should be removed " + - "from your project dependencies. See " + - "https://github.com/remix-run/remix/releases/tag/remix%402.0.0" + - " for more information." - ); - } -} - -throw new RemixPackageNotUsedError(); diff --git a/packages/remix/package.json b/packages/remix/package.json deleted file mode 100644 index d502d499c3a..00000000000 --- a/packages/remix/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "remix", - "version": "2.16.7", - "description": "A framework for building better websites", - "homepage": "https://remix.run", - "bugs": { - "url": "https://github.com/remix-run/remix/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/remix-run/remix", - "directory": "packages/remix" - }, - "license": "MIT", - "sideEffects": false, - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "module": "dist/esm/index.js", - "scripts": { - "tsc": "tsc" - }, - "engines": { - "node": ">=18.0.0" - }, - "files": [ - "dist/", - "CHANGELOG.md", - "LICENSE.md", - "README.md" - ] -} diff --git a/packages/remix/rollup.config.js b/packages/remix/rollup.config.js deleted file mode 100644 index fbcb73848e1..00000000000 --- a/packages/remix/rollup.config.js +++ /dev/null @@ -1,60 +0,0 @@ -const babel = require("@rollup/plugin-babel").default; -const path = require("node:path"); - -const { - copyPublishFiles, - copyToPlaygrounds, - createBanner, - getOutputDir, -} = require("../../rollup.utils"); -let { name: packageName, version } = require("./package.json"); - -/** @returns {import("rollup").RollupOptions[]} */ -module.exports = function rollup() { - let sourceDir = "packages/remix"; - let outputDir = getOutputDir(packageName); - let outputDist = path.join(outputDir, "dist"); - - return [ - { - external() { - return true; - }, - input: `${sourceDir}/index.ts`, - output: { - format: "cjs", - dir: outputDist, - banner: createBanner(packageName, version), - }, - plugins: [ - babel({ - babelHelpers: "bundled", - exclude: /node_modules/, - extensions: [".ts", ".tsx"], - }), - copyPublishFiles(packageName), - copyToPlaygrounds(), - ], - }, - { - external() { - return true; - }, - input: `${sourceDir}/index.ts`, - output: { - format: "esm", - dir: path.join(outputDist, "esm"), - banner: createBanner(packageName, version), - }, - plugins: [ - babel({ - babelHelpers: "bundled", - exclude: /node_modules/, - extensions: [".ts", ".tsx"], - }), - copyPublishFiles(packageName), - copyToPlaygrounds(), - ], - }, - ]; -}; diff --git a/packages/remix/tsconfig.json b/packages/remix/tsconfig.json deleted file mode 100644 index 63ef2132dc8..00000000000 --- a/packages/remix/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "include": ["**/*.ts"], - "exclude": ["dist", "__tests__", "node_modules"], - "compilerOptions": { - "lib": ["ES2022"], - "target": "ES2022", - "module": "ES2022", - "skipLibCheck": true, - - "jsx": "react", - "moduleResolution": "Bundler", - "allowSyntheticDefaultImports": true, - "strict": true, - "declaration": true, - "emitDeclarationOnly": true, - "rootDir": ".", - "outDir": "../../build/node_modules/remix/dist" - } -} diff --git a/patches/@changesets__assemble-release-plan@5.2.2.patch b/patches/@changesets__assemble-release-plan@5.2.2.patch deleted file mode 100644 index de028c040a4..00000000000 --- a/patches/@changesets__assemble-release-plan@5.2.2.patch +++ /dev/null @@ -1,39 +0,0 @@ -diff --git a/dist/assemble-release-plan.cjs.dev.js b/dist/assemble-release-plan.cjs.dev.js -index 3a37c62c975518f975c22e1b4b3974d9b325a5da..63e91f23a79765dfe42ebccabe1187d8a046936d 100644 ---- a/dist/assemble-release-plan.cjs.dev.js -+++ b/dist/assemble-release-plan.cjs.dev.js -@@ -251,7 +251,7 @@ function shouldBumpMajor({ - // we check if it is a peerDependency because if it is, our dependent bump type might need to be major. - return depType === "peerDependencies" && nextRelease.type !== "none" && nextRelease.type !== "patch" && ( // 1. If onlyUpdatePeerDependentsWhenOutOfRange set to true, bump major if the version is leaving the range. - // 2. If onlyUpdatePeerDependentsWhenOutOfRange set to false, bump major regardless whether or not the version is leaving the range. -- !onlyUpdatePeerDependentsWhenOutOfRange || !semver__default['default'].satisfies(incrementVersion(nextRelease, preInfo), versionRange)) && ( // bump major only if the dependent doesn't already has a major release. -+ !onlyUpdatePeerDependentsWhenOutOfRange || !semver__default['default'].satisfies(incrementVersion(nextRelease, preInfo), versionRange, { includePrerelease: true })) && ( // bump major only if the dependent doesn't already has a major release. - !releases.has(dependent) || releases.has(dependent) && releases.get(dependent).type !== "major"); - } - -diff --git a/dist/assemble-release-plan.cjs.prod.js b/dist/assemble-release-plan.cjs.prod.js -index 87b4c104bf3fa53ba498ced6f81eda0ed4c86436..004a81572079d2c8fd1fdc74b00cc063be07a4ef 100644 ---- a/dist/assemble-release-plan.cjs.prod.js -+++ b/dist/assemble-release-plan.cjs.prod.js -@@ -130,7 +130,7 @@ function getDependencyVersionRanges(dependentPkgJSON, dependencyRelease) { - } - - function shouldBumpMajor({dependent: dependent, depType: depType, versionRange: versionRange, releases: releases, nextRelease: nextRelease, preInfo: preInfo, onlyUpdatePeerDependentsWhenOutOfRange: onlyUpdatePeerDependentsWhenOutOfRange}) { -- return "peerDependencies" === depType && "none" !== nextRelease.type && "patch" !== nextRelease.type && (!onlyUpdatePeerDependentsWhenOutOfRange || !semver__default.default.satisfies(incrementVersion(nextRelease, preInfo), versionRange)) && (!releases.has(dependent) || releases.has(dependent) && "major" !== releases.get(dependent).type); -+ return "peerDependencies" === depType && "none" !== nextRelease.type && "patch" !== nextRelease.type && (!onlyUpdatePeerDependentsWhenOutOfRange || !semver__default.default.satisfies(incrementVersion(nextRelease, preInfo), versionRange, { includePrerelease: true })) && (!releases.has(dependent) || releases.has(dependent) && "major" !== releases.get(dependent).type); - } - - function flattenReleases(changesets, packagesByName, ignoredPackages) { -diff --git a/dist/assemble-release-plan.esm.js b/dist/assemble-release-plan.esm.js -index c29c008dd709f07cabcb07feff86012c35a01ce5..c27ae1f124702fb278a3e62181c610d4d8402988 100644 ---- a/dist/assemble-release-plan.esm.js -+++ b/dist/assemble-release-plan.esm.js -@@ -243,7 +243,7 @@ function shouldBumpMajor({ - // we check if it is a peerDependency because if it is, our dependent bump type might need to be major. - return depType === "peerDependencies" && nextRelease.type !== "none" && nextRelease.type !== "patch" && ( // 1. If onlyUpdatePeerDependentsWhenOutOfRange set to true, bump major if the version is leaving the range. - // 2. If onlyUpdatePeerDependentsWhenOutOfRange set to false, bump major regardless whether or not the version is leaving the range. -- !onlyUpdatePeerDependentsWhenOutOfRange || !semver.satisfies(incrementVersion(nextRelease, preInfo), versionRange)) && ( // bump major only if the dependent doesn't already has a major release. -+ !onlyUpdatePeerDependentsWhenOutOfRange || !semver.satisfies(incrementVersion(nextRelease, preInfo), versionRange, { includePrerelease: true })) && ( // bump major only if the dependent doesn't already has a major release. - !releases.has(dependent) || releases.has(dependent) && releases.get(dependent).type !== "major"); - } - diff --git a/playground/README.md b/playground/README.md deleted file mode 100644 index c12d3de44d5..00000000000 --- a/playground/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Playground - -This is where you can put Remix projects that use a local version of Remix. Learn more in [the contributing docs](https://remix.run/pages/contributing) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index 0a4c2eb50c0..00000000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,15834 +0,0 @@ -lockfileVersion: '6.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -overrides: - jsdom: ^22.0.0 - -patchedDependencies: - '@changesets/assemble-release-plan@5.2.2': - hash: pkun533jr2p6iwxlsqfp6xfmxe - path: patches/@changesets__assemble-release-plan@5.2.2.patch - -importers: - - .: - dependencies: - '@babel/core': - specifier: ^7.21.8 - version: 7.23.7 - '@babel/plugin-proposal-export-namespace-from': - specifier: ^7.18.9 - version: 7.18.9(@babel/core@7.23.7) - '@babel/plugin-proposal-optional-chaining': - specifier: ^7.21.0 - version: 7.21.0(@babel/core@7.23.7) - '@babel/preset-env': - specifier: ^7.21.5 - version: 7.21.5(@babel/core@7.23.7) - '@babel/preset-react': - specifier: ^7.18.6 - version: 7.18.6(@babel/core@7.23.7) - '@babel/preset-typescript': - specifier: ^7.21.5 - version: 7.21.5(@babel/core@7.23.7) - '@changesets/cli': - specifier: ^2.25.2 - version: 2.25.2 - '@cloudflare/kv-asset-handler': - specifier: ^0.3.0 - version: 0.3.4 - '@manypkg/get-packages': - specifier: ^1.1.3 - version: 1.1.3 - '@mcansh/remark-definition-links': - specifier: 2.4.1 - version: 2.4.1 - '@mdx-js/rollup': - specifier: ^3.0.0 - version: 3.0.0(rollup@2.79.2) - '@octokit/core': - specifier: ^3.6.0 - version: 3.6.0 - '@octokit/graphql': - specifier: ^4.8.0 - version: 4.8.0 - '@octokit/plugin-paginate-rest': - specifier: ^2.17.0 - version: 2.17.0(@octokit/core@3.6.0) - '@octokit/rest': - specifier: ^18.12.0 - version: 18.12.0 - '@playwright/test': - specifier: ^1.49.1 - version: 1.49.1 - '@remix-run/architect': - specifier: workspace:* - version: link:packages/remix-architect - '@remix-run/changelog-github': - specifier: ^0.0.5 - version: 0.0.5 - '@remix-run/cloudflare': - specifier: workspace:* - version: link:packages/remix-cloudflare - '@remix-run/cloudflare-pages': - specifier: workspace:* - version: link:packages/remix-cloudflare-pages - '@remix-run/css-bundle': - specifier: workspace:* - version: link:packages/remix-css-bundle - '@remix-run/dev': - specifier: workspace:* - version: link:packages/remix-dev - '@remix-run/node': - specifier: workspace:* - version: link:packages/remix-node - '@remix-run/react': - specifier: workspace:* - version: link:packages/remix-react - '@remix-run/testing': - specifier: workspace:* - version: link:packages/remix-testing - '@rollup/plugin-babel': - specifier: ^5.2.2 - version: 5.3.1(@babel/core@7.23.7)(rollup@2.79.2) - '@rollup/plugin-commonjs': - specifier: ^21.1.0 - version: 21.1.0(rollup@2.79.2) - '@rollup/plugin-json': - specifier: ^5.0.0 - version: 5.0.2(rollup@2.79.2) - '@rollup/plugin-node-resolve': - specifier: ^11.0.1 - version: 11.2.1(rollup@2.79.2) - '@rollup/plugin-replace': - specifier: ^5.0.2 - version: 5.0.2(rollup@2.79.2) - '@testing-library/cypress': - specifier: ^8.0.2 - version: 8.0.2(cypress@9.6.0) - '@testing-library/jest-dom': - specifier: ^5.17.0 - version: 5.17.0 - '@testing-library/react': - specifier: ^13.3.0 - version: 13.3.0(react-dom@18.2.0)(react@18.2.0) - '@testing-library/user-event': - specifier: ^14.5.1 - version: 14.5.1(@testing-library/dom@9.3.4) - '@types/chalk': - specifier: ^2.2.0 - version: 2.2.0 - '@types/cheerio': - specifier: ^0.22.22 - version: 0.22.30 - '@types/cross-spawn': - specifier: ^6.0.2 - version: 6.0.2 - '@types/dedent': - specifier: ^0.7.0 - version: 0.7.0 - '@types/fs-extra': - specifier: ^8.1.2 - version: 8.1.2 - '@types/glob': - specifier: 7.2.0 - version: 7.2.0 - '@types/jest': - specifier: ^29.5.4 - version: 29.5.4 - '@types/jsonfile': - specifier: ^6.1.0 - version: 6.1.0 - '@types/lodash': - specifier: ^4.14.182 - version: 4.14.182 - '@types/react': - specifier: ^18.2.20 - version: 18.2.20 - '@types/react-dom': - specifier: ^18.2.7 - version: 18.2.7 - '@types/react-test-renderer': - specifier: ^18.0.0 - version: 18.0.0 - '@types/retry': - specifier: ^0.12.0 - version: 0.12.1 - '@types/semver': - specifier: ^7.3.4 - version: 7.3.13 - '@types/serialize-javascript': - specifier: ^5.0.2 - version: 5.0.2 - '@types/shelljs': - specifier: ^0.8.11 - version: 0.8.15 - '@types/ssri': - specifier: ^7.1.0 - version: 7.1.1 - '@types/wait-on': - specifier: ^5.3.2 - version: 5.3.2 - babel-jest: - specifier: ^29.6.4 - version: 29.6.4(@babel/core@7.23.7) - babel-plugin-transform-remove-console: - specifier: ^6.9.4 - version: 6.9.4 - chalk: - specifier: ^4.1.2 - version: 4.1.2 - concurrently: - specifier: ^7.0.0 - version: 7.0.0 - cross-spawn: - specifier: ^7.0.3 - version: 7.0.3 - cypress: - specifier: ^9.6.0 - version: 9.6.0 - eslint: - specifier: ^8.23.1 - version: 8.56.0 - eslint-plugin-markdown: - specifier: ^2.2.1 - version: 2.2.1(eslint@8.56.0) - eslint-plugin-prefer-let: - specifier: ^3.0.1 - version: 3.0.1 - front-matter: - specifier: ^4.0.2 - version: 4.0.2 - fs-extra: - specifier: ^7.0.1 - version: 7.0.1 - glob: - specifier: 8.0.3 - version: 8.0.3 - isbot: - specifier: ^4.1.0 - version: 4.4.0 - jest: - specifier: ^29.6.4 - version: 29.6.4 - jest-watch-select-projects: - specifier: ^2.0.0 - version: 2.0.0 - jest-watch-typeahead: - specifier: ^2.2.2 - version: 2.2.2(jest@29.6.4) - jsonfile: - specifier: ^6.0.1 - version: 6.1.0 - lodash: - specifier: ^4.17.21 - version: 4.17.21 - mime: - specifier: ^3.0.0 - version: 3.0.0 - prettier: - specifier: ^2.7.1 - version: 2.8.1 - prompt-confirm: - specifier: ^2.0.4 - version: 2.0.4 - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) - remark: - specifier: 14.0.2 - version: 14.0.2 - remark-frontmatter: - specifier: 4.0.1 - version: 4.0.1 - remark-gfm: - specifier: 3.0.1 - version: 3.0.1 - remark-parse: - specifier: ^10.0.1 - version: 10.0.1 - remark-stringify: - specifier: ^10.0.2 - version: 10.0.2 - rollup: - specifier: ^2.79.2 - version: 2.79.2 - rollup-plugin-copy: - specifier: ^3.3.0 - version: 3.4.0 - semver: - specifier: ^7.3.7 - version: 7.5.4 - simple-git: - specifier: ^3.16.0 - version: 3.16.0 - source-map-support: - specifier: ^0.5.21 - version: 0.5.21 - to-vfile: - specifier: 7.2.3 - version: 7.2.3 - type-fest: - specifier: ^4.0.0 - version: 4.10.2 - typescript: - specifier: 5.1.6 - version: 5.1.6 - unified: - specifier: ^10.1.2 - version: 10.1.2 - unist-util-remove: - specifier: ^3.1.0 - version: 3.1.0 - unist-util-visit: - specifier: ^4.1.1 - version: 4.1.1 - vite: - specifier: ^6.0.0 - version: 6.0.6(@types/node@18.17.1) - vite-tsconfig-paths: - specifier: ^4.2.2 - version: 4.3.1(typescript@5.1.6)(vite@6.0.6) - wait-on: - specifier: ^7.0.1 - version: 7.0.1 - wrangler: - specifier: ^3.72.3 - version: 3.74.0(@cloudflare/workers-types@4.20240208.0) - - integration: - dependencies: - '@cloudflare/kv-asset-handler': - specifier: ^0.3.0 - version: 0.3.4 - '@cloudflare/workers-types': - specifier: ^4.20230518.0 - version: 4.20240208.0 - '@playwright/test': - specifier: ^1.49.1 - version: 1.49.1 - '@remix-run/dev': - specifier: workspace:* - version: link:../packages/remix-dev - '@remix-run/express': - specifier: workspace:* - version: link:../packages/remix-express - '@remix-run/node': - specifier: workspace:* - version: link:../packages/remix-node - '@remix-run/router': - specifier: 1.23.0 - version: 1.23.0 - '@remix-run/server-runtime': - specifier: workspace:* - version: link:../packages/remix-server-runtime - '@types/express': - specifier: ^4.17.9 - version: 4.17.21 - '@vanilla-extract/css': - specifier: ^1.10.0 - version: 1.14.1 - '@vanilla-extract/vite-plugin': - specifier: ^3.9.2 - version: 3.9.5(vite@5.1.8) - cheerio: - specifier: ^1.0.0-rc.12 - version: 1.0.0-rc.12 - cross-spawn: - specifier: ^7.0.3 - version: 7.0.3 - dedent: - specifier: ^0.7.0 - version: 0.7.0 - execa: - specifier: ^5.1.1 - version: 5.1.1 - express: - specifier: ^4.20.0 - version: 4.21.1 - fs-extra: - specifier: ^10.0.0 - version: 10.1.0 - get-port: - specifier: ^5.1.1 - version: 5.1.1 - glob: - specifier: 8.0.3 - version: 8.0.3 - globby: - specifier: ^11.1.0 - version: 11.1.0 - isbot: - specifier: ^4.1.0 - version: 4.4.0 - npm-run-all: - specifier: ^4.1.5 - version: 4.1.5 - pathe: - specifier: ^1.1.2 - version: 1.1.2 - pidtree: - specifier: ^0.6.0 - version: 0.6.0 - postcss: - specifier: ^8.4.19 - version: 8.4.49 - postcss-import: - specifier: ^15.1.0 - version: 15.1.0(postcss@8.4.49) - prettier: - specifier: ^2.7.1 - version: 2.8.1 - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) - serialize-javascript: - specifier: ^6.0.1 - version: 6.0.2 - shelljs: - specifier: ^0.8.5 - version: 0.8.5 - strip-ansi: - specifier: ^6.0.1 - version: 6.0.1 - strip-indent: - specifier: ^3.0.0 - version: 3.0.0 - tailwindcss: - specifier: ^3.3.0 - version: 3.4.1 - type-fest: - specifier: ^4.0.0 - version: 4.10.2 - typescript: - specifier: ^5.1.0 - version: 5.1.6 - vite-tsconfig-paths: - specifier: ^4.2.2 - version: 4.3.1(typescript@5.1.6)(vite@5.1.8) - wrangler: - specifier: ^3.28.2 - version: 3.74.0(@cloudflare/workers-types@4.20240208.0) - - integration/helpers/cf-template: - dependencies: - '@cloudflare/kv-asset-handler': - specifier: ^0.3.0 - version: 0.3.4 - '@remix-run/cloudflare': - specifier: workspace:* - version: link:../../../packages/remix-cloudflare - '@remix-run/css-bundle': - specifier: workspace:* - version: link:../../../packages/remix-css-bundle - '@remix-run/react': - specifier: workspace:* - version: link:../../../packages/remix-react - isbot: - specifier: ^4.1.0 - version: 4.4.0 - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) - devDependencies: - '@cloudflare/workers-types': - specifier: ^4.20230518.0 - version: 4.20240208.0 - '@remix-run/dev': - specifier: workspace:* - version: link:../../../packages/remix-dev - '@types/react': - specifier: ^18.2.0 - version: 18.2.20 - '@types/react-dom': - specifier: ^18.2.0 - version: 18.2.7 - typescript: - specifier: ^5.1.0 - version: 5.1.6 - wrangler: - specifier: ^3.24.0 - version: 3.74.0(@cloudflare/workers-types@4.20240208.0) - - integration/helpers/deno-template: - dependencies: - '@remix-run/css-bundle': - specifier: workspace:* - version: link:../../../packages/remix-css-bundle - '@remix-run/deno': - specifier: workspace:* - version: link:../../../packages/remix-deno - '@remix-run/react': - specifier: workspace:* - version: link:../../../packages/remix-react - isbot: - specifier: ^4.1.0 - version: 4.4.0 - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) - devDependencies: - '@remix-run/dev': - specifier: workspace:* - version: link:../../../packages/remix-dev - - integration/helpers/node-template: - dependencies: - '@remix-run/css-bundle': - specifier: workspace:* - version: link:../../../packages/remix-css-bundle - '@remix-run/express': - specifier: workspace:* - version: link:../../../packages/remix-express - '@remix-run/node': - specifier: workspace:* - version: link:../../../packages/remix-node - '@remix-run/react': - specifier: workspace:* - version: link:../../../packages/remix-react - '@remix-run/serve': - specifier: workspace:* - version: link:../../../packages/remix-serve - '@remix-run/server-runtime': - specifier: workspace:* - version: link:../../../packages/remix-server-runtime - express: - specifier: ^4.20.0 - version: 4.21.1 - isbot: - specifier: ^4.1.0 - version: 4.4.0 - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) - devDependencies: - '@remix-run/dev': - specifier: workspace:* - version: link:../../../packages/remix-dev - '@remix-run/fs-routes': - specifier: workspace:* - version: link:../../../packages/remix-fs-routes - '@remix-run/route-config': - specifier: workspace:* - version: link:../../../packages/remix-route-config - '@remix-run/routes-option-adapter': - specifier: workspace:* - version: link:../../../packages/remix-routes-option-adapter - '@types/react': - specifier: ^18.2.20 - version: 18.2.20 - '@types/react-dom': - specifier: ^18.2.7 - version: 18.2.7 - '@vanilla-extract/css': - specifier: ^1.10.0 - version: 1.14.1 - '@vanilla-extract/vite-plugin': - specifier: ^3.9.2 - version: 3.9.5(vite@5.1.8) - getos: - specifier: ^3.2.1 - version: 3.2.1 - postcss-import: - specifier: ^15.1.0 - version: 15.1.0(postcss@8.4.49) - tailwindcss: - specifier: ^3.3.0 - version: 3.4.1 - typescript: - specifier: ^5.1.0 - version: 5.1.6 - - integration/helpers/vite-5-template: - dependencies: - '@remix-run/express': - specifier: workspace:* - version: link:../../../packages/remix-express - '@remix-run/node': - specifier: workspace:* - version: link:../../../packages/remix-node - '@remix-run/react': - specifier: workspace:* - version: link:../../../packages/remix-react - '@remix-run/serve': - specifier: workspace:* - version: link:../../../packages/remix-serve - '@vanilla-extract/css': - specifier: ^1.10.0 - version: 1.14.1 - '@vanilla-extract/vite-plugin': - specifier: ^3.9.2 - version: 3.9.5(vite@5.1.8) - express: - specifier: ^4.20.0 - version: 4.21.1 - isbot: - specifier: ^4.1.0 - version: 4.4.0 - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) - serialize-javascript: - specifier: ^6.0.1 - version: 6.0.2 - devDependencies: - '@remix-run/dev': - specifier: workspace:* - version: link:../../../packages/remix-dev - '@remix-run/eslint-config': - specifier: workspace:* - version: link:../../../packages/remix-eslint-config - '@remix-run/route-config': - specifier: workspace:* - version: link:../../../packages/remix-route-config - '@types/react': - specifier: ^18.2.20 - version: 18.2.20 - '@types/react-dom': - specifier: ^18.2.7 - version: 18.2.7 - eslint: - specifier: ^8.38.0 - version: 8.56.0 - typescript: - specifier: ^5.1.6 - version: 5.1.6 - vite: - specifier: 5.1.8 - version: 5.1.8(@types/node@18.17.1) - vite-env-only: - specifier: ^2.0.0 - version: 2.2.0 - vite-tsconfig-paths: - specifier: ^4.2.1 - version: 4.3.1(typescript@5.1.6)(vite@5.1.8) - wrangler: - specifier: ^3.24.0 - version: 3.74.0(@cloudflare/workers-types@4.20240208.0) - - integration/helpers/vite-6-template: - dependencies: - '@remix-run/express': - specifier: workspace:* - version: link:../../../packages/remix-express - '@remix-run/node': - specifier: workspace:* - version: link:../../../packages/remix-node - '@remix-run/react': - specifier: workspace:* - version: link:../../../packages/remix-react - '@remix-run/serve': - specifier: workspace:* - version: link:../../../packages/remix-serve - '@vanilla-extract/css': - specifier: ^1.10.0 - version: 1.14.1 - '@vanilla-extract/vite-plugin': - specifier: ^3.9.2 - version: 3.9.5(vite@6.0.6) - express: - specifier: ^4.20.0 - version: 4.21.1 - isbot: - specifier: ^4.1.0 - version: 4.4.0 - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) - serialize-javascript: - specifier: ^6.0.1 - version: 6.0.2 - devDependencies: - '@remix-run/dev': - specifier: workspace:* - version: link:../../../packages/remix-dev - '@remix-run/eslint-config': - specifier: workspace:* - version: link:../../../packages/remix-eslint-config - '@remix-run/route-config': - specifier: workspace:* - version: link:../../../packages/remix-route-config - '@types/react': - specifier: ^18.2.20 - version: 18.2.20 - '@types/react-dom': - specifier: ^18.2.7 - version: 18.2.7 - eslint: - specifier: ^8.38.0 - version: 8.56.0 - typescript: - specifier: ^5.1.6 - version: 5.1.6 - vite: - specifier: ^6.0.0 - version: 6.0.6(@types/node@18.17.1) - vite-env-only: - specifier: ^2.0.0 - version: 2.2.0 - vite-tsconfig-paths: - specifier: ^4.2.1 - version: 4.3.1(typescript@5.1.6)(vite@6.0.6) - wrangler: - specifier: ^3.24.0 - version: 3.74.0(@cloudflare/workers-types@4.20240208.0) - - integration/helpers/vite-cloudflare-template: - dependencies: - '@remix-run/cloudflare': - specifier: workspace:* - version: link:../../../packages/remix-cloudflare - '@remix-run/cloudflare-pages': - specifier: workspace:* - version: link:../../../packages/remix-cloudflare-pages - '@remix-run/react': - specifier: workspace:* - version: link:../../../packages/remix-react - isbot: - specifier: ^4.1.0 - version: 4.4.0 - miniflare: - specifier: ^3.20231030.4 - version: 3.20240821.1 - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) - devDependencies: - '@cloudflare/workers-types': - specifier: ^4.20230518.0 - version: 4.20240208.0 - '@remix-run/dev': - specifier: workspace:* - version: link:../../../packages/remix-dev - '@remix-run/eslint-config': - specifier: workspace:* - version: link:../../../packages/remix-eslint-config - '@types/react': - specifier: ^18.2.20 - version: 18.2.20 - '@types/react-dom': - specifier: ^18.2.7 - version: 18.2.7 - typescript: - specifier: ^5.1.6 - version: 5.1.6 - vite: - specifier: ^6.0.0 - version: 6.0.6(@types/node@18.17.1) - vite-tsconfig-paths: - specifier: ^4.2.1 - version: 4.3.1(typescript@5.1.6)(vite@6.0.6) - wrangler: - specifier: ^3.24.0 - version: 3.74.0(@cloudflare/workers-types@4.20240208.0) - - packages/create-remix: - dependencies: - '@remix-run/web-fetch': - specifier: ^4.4.2 - version: 4.4.2 - arg: - specifier: ^5.0.1 - version: 5.0.2 - chalk: - specifier: ^4.1.2 - version: 4.1.2 - execa: - specifier: 5.1.1 - version: 5.1.1 - fs-extra: - specifier: ^10.0.0 - version: 10.1.0 - gunzip-maybe: - specifier: ^1.4.2 - version: 1.4.2 - log-update: - specifier: ^5.0.1 - version: 5.0.1 - proxy-agent: - specifier: ^6.3.0 - version: 6.4.0 - recursive-readdir: - specifier: ^2.2.3 - version: 2.2.3 - rimraf: - specifier: ^4.1.2 - version: 4.4.1 - semver: - specifier: ^7.3.7 - version: 7.5.4 - sisteransi: - specifier: ^1.0.5 - version: 1.0.5 - sort-package-json: - specifier: ^1.55.0 - version: 1.57.0 - strip-ansi: - specifier: ^6.0.1 - version: 6.0.1 - tar-fs: - specifier: ^2.1.1 - version: 2.1.1 - devDependencies: - '@types/gunzip-maybe': - specifier: ^1.4.0 - version: 1.4.2 - '@types/recursive-readdir': - specifier: ^2.2.1 - version: 2.2.4 - '@types/tar-fs': - specifier: ^2.0.1 - version: 2.0.4 - esbuild: - specifier: 0.17.6 - version: 0.17.6 - esbuild-register: - specifier: ^3.3.2 - version: 3.5.0(esbuild@0.17.6) - msw: - specifier: ^1.2.3 - version: 1.3.2(typescript@5.1.6) - tiny-invariant: - specifier: ^1.2.0 - version: 1.3.1 - - packages/remix: {} - - packages/remix-architect: - dependencies: - '@architect/functions': - specifier: ^5.2.0 - version: 5.4.1 - '@remix-run/node': - specifier: workspace:* - version: link:../remix-node - '@remix-run/web-fetch': - specifier: ^4.4.2 - version: 4.4.2 - '@types/aws-lambda': - specifier: ^8.10.82 - version: 8.10.133 - devDependencies: - '@types/lambda-tester': - specifier: ^3.6.1 - version: 3.6.2 - '@types/node': - specifier: ^18.17.1 - version: 18.17.1 - lambda-tester: - specifier: ^4.0.1 - version: 4.0.1 - typescript: - specifier: ^5.1.0 - version: 5.1.6 - - packages/remix-cloudflare: - dependencies: - '@cloudflare/kv-asset-handler': - specifier: ^0.1.3 - version: 0.1.3 - '@remix-run/server-runtime': - specifier: workspace:* - version: link:../remix-server-runtime - devDependencies: - '@cloudflare/workers-types': - specifier: ^4.20230518.0 - version: 4.20240208.0 - typescript: - specifier: ^5.1.0 - version: 5.1.6 - - packages/remix-cloudflare-pages: - dependencies: - '@remix-run/cloudflare': - specifier: workspace:* - version: link:../remix-cloudflare - devDependencies: - '@cloudflare/workers-types': - specifier: ^4.20230518.0 - version: 4.20240208.0 - '@types/mime': - specifier: ^2.0.3 - version: 2.0.3 - '@types/node': - specifier: ^18.17.1 - version: 18.17.1 - typescript: - specifier: ^5.1.0 - version: 5.1.6 - - packages/remix-cloudflare-workers: - dependencies: - '@cloudflare/kv-asset-handler': - specifier: ^0.1.3 - version: 0.1.3 - '@remix-run/cloudflare': - specifier: workspace:* - version: link:../remix-cloudflare - devDependencies: - '@cloudflare/workers-types': - specifier: ^4.20230518.0 - version: 4.20240208.0 - '@types/node': - specifier: ^18.17.1 - version: 18.17.1 - typescript: - specifier: ^5.1.6 - version: 5.1.6 - - packages/remix-css-bundle: {} - - packages/remix-deno: - dependencies: - '@remix-run/server-runtime': - specifier: workspace:* - version: link:../remix-server-runtime - mime: - specifier: ^3.0.0 - version: 3.0.0 - typescript: - specifier: ^5.1.0 - version: 5.1.6 - - packages/remix-dev: - dependencies: - '@babel/core': - specifier: ^7.21.8 - version: 7.23.7 - '@babel/generator': - specifier: ^7.21.5 - version: 7.23.6 - '@babel/parser': - specifier: ^7.21.8 - version: 7.23.6 - '@babel/plugin-syntax-decorators': - specifier: ^7.22.10 - version: 7.23.3(@babel/core@7.23.7) - '@babel/plugin-syntax-jsx': - specifier: ^7.21.4 - version: 7.22.5(@babel/core@7.23.7) - '@babel/preset-typescript': - specifier: ^7.21.5 - version: 7.21.5(@babel/core@7.23.7) - '@babel/traverse': - specifier: ^7.23.2 - version: 7.23.7 - '@babel/types': - specifier: ^7.22.5 - version: 7.23.6 - '@mdx-js/mdx': - specifier: ^2.3.0 - version: 2.3.0 - '@npmcli/package-json': - specifier: ^4.0.1 - version: 4.0.1 - '@remix-run/node': - specifier: workspace:* - version: link:../remix-node - '@remix-run/router': - specifier: 1.23.0 - version: 1.23.0 - '@remix-run/server-runtime': - specifier: workspace:* - version: link:../remix-server-runtime - '@types/mdx': - specifier: ^2.0.5 - version: 2.0.5 - '@vanilla-extract/integration': - specifier: ^6.2.0 - version: 6.5.0(@types/node@18.17.1) - arg: - specifier: ^5.0.1 - version: 5.0.2 - cacache: - specifier: ^17.1.3 - version: 17.1.4 - chalk: - specifier: ^4.1.2 - version: 4.1.2 - chokidar: - specifier: ^3.5.1 - version: 3.6.0 - cross-spawn: - specifier: ^7.0.3 - version: 7.0.3 - dotenv: - specifier: ^16.0.0 - version: 16.4.4 - es-module-lexer: - specifier: ^1.3.1 - version: 1.7.0 - esbuild: - specifier: 0.17.6 - version: 0.17.6 - esbuild-plugins-node-modules-polyfill: - specifier: ^1.6.0 - version: 1.6.2(esbuild@0.17.6) - execa: - specifier: 5.1.1 - version: 5.1.1 - exit-hook: - specifier: 2.2.1 - version: 2.2.1 - express: - specifier: ^4.20.0 - version: 4.21.1 - fs-extra: - specifier: ^10.0.0 - version: 10.1.0 - get-port: - specifier: ^5.1.1 - version: 5.1.1 - gunzip-maybe: - specifier: ^1.4.2 - version: 1.4.2 - jsesc: - specifier: 3.0.2 - version: 3.0.2 - json5: - specifier: ^2.2.2 - version: 2.2.3 - lodash: - specifier: ^4.17.21 - version: 4.17.21 - lodash.debounce: - specifier: ^4.0.8 - version: 4.0.8 - minimatch: - specifier: ^9.0.0 - version: 9.0.3 - ora: - specifier: ^5.4.1 - version: 5.4.1 - pathe: - specifier: ^1.1.2 - version: 1.1.2 - picocolors: - specifier: ^1.0.0 - version: 1.1.1 - picomatch: - specifier: ^2.3.1 - version: 2.3.1 - pidtree: - specifier: ^0.6.0 - version: 0.6.0 - postcss: - specifier: ^8.4.19 - version: 8.4.49 - postcss-discard-duplicates: - specifier: ^5.1.0 - version: 5.1.0(postcss@8.4.49) - postcss-load-config: - specifier: ^4.0.1 - version: 4.0.2(postcss@8.4.49) - postcss-modules: - specifier: ^6.0.0 - version: 6.0.0(postcss@8.4.49) - prettier: - specifier: ^2.7.1 - version: 2.8.1 - pretty-ms: - specifier: ^7.0.1 - version: 7.0.1 - react-refresh: - specifier: ^0.14.0 - version: 0.14.0 - remark-frontmatter: - specifier: 4.0.1 - version: 4.0.1 - remark-mdx-frontmatter: - specifier: ^1.0.1 - version: 1.1.1 - semver: - specifier: ^7.3.7 - version: 7.5.4 - set-cookie-parser: - specifier: ^2.6.0 - version: 2.6.0 - tar-fs: - specifier: ^2.1.1 - version: 2.1.1 - tsconfig-paths: - specifier: ^4.0.0 - version: 4.2.0 - typescript: - specifier: ^5.1.0 - version: 5.1.6 - valibot: - specifier: ^0.41.0 - version: 0.41.0(typescript@5.1.6) - vite: - specifier: ^5.1.0 || ^6.0.0 - version: 6.0.6(@types/node@18.17.1) - vite-node: - specifier: ^3.1.3 - version: 3.1.3(@types/node@18.17.1) - ws: - specifier: ^7.5.10 - version: 7.5.10 - devDependencies: - '@remix-run/cloudflare': - specifier: workspace:* - version: link:../remix-cloudflare - '@remix-run/deno': - specifier: workspace:* - version: link:../remix-deno - '@remix-run/react': - specifier: workspace:* - version: link:../remix-react - '@remix-run/serve': - specifier: workspace:* - version: link:../remix-serve - '@remix-run/testing': - specifier: workspace:* - version: link:../remix-testing - '@types/babel__core': - specifier: ^7.20.5 - version: 7.20.5 - '@types/babel__generator': - specifier: ^7.6.8 - version: 7.6.8 - '@types/babel__traverse': - specifier: ^7.20.5 - version: 7.20.5 - '@types/cacache': - specifier: ^17.0.0 - version: 17.0.2 - '@types/cross-spawn': - specifier: ^6.0.2 - version: 6.0.2 - '@types/express': - specifier: ^4.17.9 - version: 4.17.21 - '@types/gunzip-maybe': - specifier: ^1.4.0 - version: 1.4.2 - '@types/jsesc': - specifier: ^3.0.1 - version: 3.0.3 - '@types/lodash.debounce': - specifier: ^4.0.6 - version: 4.0.9 - '@types/node': - specifier: ^18.17.1 - version: 18.17.1 - '@types/npmcli__package-json': - specifier: ^4.0.0 - version: 4.0.4 - '@types/picomatch': - specifier: ^2.3.0 - version: 2.3.3 - '@types/prettier': - specifier: ^2.7.3 - version: 2.7.3 - '@types/set-cookie-parser': - specifier: ^2.4.1 - version: 2.4.7 - '@types/shelljs': - specifier: ^0.8.11 - version: 0.8.15 - '@types/tar-fs': - specifier: ^2.0.1 - version: 2.0.4 - '@types/ws': - specifier: ^7.4.1 - version: 7.4.7 - esbuild-register: - specifier: ^3.3.2 - version: 3.5.0(esbuild@0.17.6) - fast-glob: - specifier: 3.2.11 - version: 3.2.11 - msw: - specifier: ^1.2.3 - version: 1.3.2(typescript@5.1.6) - strip-ansi: - specifier: ^6.0.1 - version: 6.0.1 - tiny-invariant: - specifier: ^1.2.0 - version: 1.3.1 - wrangler: - specifier: ^3.28.2 - version: 3.74.0(@cloudflare/workers-types@4.20240208.0) - - packages/remix-eslint-config: - dependencies: - '@babel/core': - specifier: ^7.21.8 - version: 7.23.7 - '@babel/eslint-parser': - specifier: ^7.21.8 - version: 7.23.10(@babel/core@7.23.7)(eslint@8.56.0) - '@babel/preset-react': - specifier: ^7.18.6 - version: 7.18.6(@babel/core@7.23.7) - '@rushstack/eslint-patch': - specifier: ^1.2.0 - version: 1.7.2 - '@typescript-eslint/eslint-plugin': - specifier: ^5.59.0 - version: 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.56.0)(typescript@5.1.6) - '@typescript-eslint/parser': - specifier: ^5.59.0 - version: 5.62.0(eslint@8.56.0)(typescript@5.1.6) - eslint-import-resolver-node: - specifier: 0.3.7 - version: 0.3.7 - eslint-import-resolver-typescript: - specifier: ^3.5.4 - version: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.29.1)(eslint@8.56.0) - eslint-plugin-import: - specifier: ^2.27.5 - version: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) - eslint-plugin-jest: - specifier: ^26.9.0 - version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0)(eslint@8.56.0)(jest@29.6.4)(typescript@5.1.6) - eslint-plugin-jest-dom: - specifier: ^4.0.3 - version: 4.0.3(eslint@8.56.0) - eslint-plugin-jsx-a11y: - specifier: ^6.7.1 - version: 6.8.0(eslint@8.56.0) - eslint-plugin-node: - specifier: ^11.1.0 - version: 11.1.0(eslint@8.56.0) - eslint-plugin-react: - specifier: ^7.32.2 - version: 7.33.2(eslint@8.56.0) - eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.0(eslint@8.56.0) - eslint-plugin-testing-library: - specifier: ^5.10.2 - version: 5.11.1(eslint@8.56.0)(typescript@5.1.6) - devDependencies: - '@types/eslint': - specifier: ^8.37.0 - version: 8.56.2 - eslint: - specifier: ^8.37.0 - version: 8.56.0 - jest: - specifier: ^29.6.4 - version: 29.6.4 - react: - specifier: ^18.2.0 - version: 18.2.0 - typescript: - specifier: ^5.1.6 - version: 5.1.6 - - packages/remix-express: - dependencies: - '@remix-run/node': - specifier: workspace:* - version: link:../remix-node - devDependencies: - '@types/express': - specifier: ^4.17.9 - version: 4.17.21 - '@types/node': - specifier: ^18.17.1 - version: 18.17.1 - '@types/supertest': - specifier: ^2.0.10 - version: 2.0.16 - express: - specifier: ^4.20.0 - version: 4.21.1 - node-mocks-http: - specifier: ^1.10.1 - version: 1.14.1 - supertest: - specifier: ^6.3.3 - version: 6.3.4 - typescript: - specifier: ^5.1.6 - version: 5.1.6 - - packages/remix-fs-routes: - devDependencies: - '@remix-run/dev': - specifier: workspace:* - version: link:../remix-dev - '@remix-run/route-config': - specifier: workspace:* - version: link:../remix-route-config - typescript: - specifier: ^5.1.6 - version: 5.1.6 - - packages/remix-node: - dependencies: - '@remix-run/server-runtime': - specifier: workspace:* - version: link:../remix-server-runtime - '@remix-run/web-fetch': - specifier: ^4.4.2 - version: 4.4.2 - '@web3-storage/multipart-parser': - specifier: ^1.0.0 - version: 1.0.0 - cookie-signature: - specifier: ^1.1.0 - version: 1.2.1 - source-map-support: - specifier: ^0.5.21 - version: 0.5.21 - stream-slice: - specifier: ^0.1.2 - version: 0.1.2 - undici: - specifier: ^6.21.2 - version: 6.21.2 - devDependencies: - '@types/cookie-signature': - specifier: ^1.0.3 - version: 1.1.2 - '@types/source-map-support': - specifier: ^0.5.4 - version: 0.5.10 - typescript: - specifier: ^5.1.6 - version: 5.1.6 - - packages/remix-react: - dependencies: - '@remix-run/router': - specifier: 1.23.0 - version: 1.23.0 - '@remix-run/server-runtime': - specifier: workspace:* - version: link:../remix-server-runtime - react-router: - specifier: 6.30.0 - version: 6.30.0(react@18.2.0) - react-router-dom: - specifier: 6.30.0 - version: 6.30.0(react-dom@18.2.0)(react@18.2.0) - turbo-stream: - specifier: 2.4.1 - version: 2.4.1 - devDependencies: - '@remix-run/node': - specifier: workspace:* - version: link:../remix-node - '@remix-run/react': - specifier: workspace:* - version: 'link:' - '@testing-library/jest-dom': - specifier: ^5.17.0 - version: 5.17.0 - '@testing-library/react': - specifier: ^13.3.0 - version: 13.3.0(react-dom@18.2.0)(react@18.2.0) - '@types/react': - specifier: ^18.2.20 - version: 18.2.20 - jest-environment-jsdom: - specifier: ^29.6.4 - version: 29.7.0 - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) - typescript: - specifier: ^5.1.6 - version: 5.1.6 - - packages/remix-route-config: - dependencies: - lodash: - specifier: ^4.17.21 - version: 4.17.21 - devDependencies: - '@remix-run/dev': - specifier: workspace:* - version: link:../remix-dev - '@types/lodash': - specifier: ^4.14.182 - version: 4.14.182 - typescript: - specifier: ^5.1.6 - version: 5.1.6 - vite: - specifier: ^6.0.0 - version: 6.0.6(@types/node@18.17.1) - - packages/remix-routes-option-adapter: - devDependencies: - '@remix-run/dev': - specifier: workspace:* - version: link:../remix-dev - '@remix-run/route-config': - specifier: workspace:* - version: link:../remix-route-config - typescript: - specifier: ^5.1.6 - version: 5.1.6 - - packages/remix-serve: - dependencies: - '@remix-run/express': - specifier: workspace:* - version: link:../remix-express - '@remix-run/node': - specifier: workspace:* - version: link:../remix-node - chokidar: - specifier: ^3.5.3 - version: 3.6.0 - compression: - specifier: ^1.7.4 - version: 1.7.4 - express: - specifier: ^4.20.0 - version: 4.21.1 - get-port: - specifier: 5.1.1 - version: 5.1.1 - morgan: - specifier: ^1.10.0 - version: 1.10.0 - source-map-support: - specifier: ^0.5.21 - version: 0.5.21 - devDependencies: - '@types/compression': - specifier: ^1.7.0 - version: 1.7.5 - '@types/express': - specifier: ^4.17.9 - version: 4.17.21 - '@types/morgan': - specifier: ^1.9.2 - version: 1.9.9 - '@types/source-map-support': - specifier: ^0.5.6 - version: 0.5.10 - - packages/remix-server-runtime: - dependencies: - '@remix-run/router': - specifier: 1.23.0 - version: 1.23.0 - '@types/cookie': - specifier: ^0.6.0 - version: 0.6.0 - '@web3-storage/multipart-parser': - specifier: ^1.0.0 - version: 1.0.0 - cookie: - specifier: ^0.7.2 - version: 0.7.2 - set-cookie-parser: - specifier: ^2.4.8 - version: 2.6.0 - source-map: - specifier: ^0.7.3 - version: 0.7.3 - turbo-stream: - specifier: 2.4.1 - version: 2.4.1 - devDependencies: - '@types/set-cookie-parser': - specifier: ^2.4.1 - version: 2.4.7 - typescript: - specifier: ^5.1.6 - version: 5.1.6 - - packages/remix-testing: - dependencies: - '@remix-run/node': - specifier: workspace:* - version: link:../remix-node - '@remix-run/react': - specifier: workspace:* - version: link:../remix-react - '@remix-run/router': - specifier: 1.23.0 - version: 1.23.0 - react-router-dom: - specifier: 6.30.0 - version: 6.30.0(react-dom@18.2.0)(react@18.2.0) - devDependencies: - '@remix-run/server-runtime': - specifier: workspace:* - version: link:../remix-server-runtime - '@remix-run/testing': - specifier: workspace:* - version: 'link:' - '@types/node': - specifier: ^18.17.1 - version: 18.17.1 - '@types/react': - specifier: ^18.2.20 - version: 18.2.20 - '@types/react-dom': - specifier: ^18.2.7 - version: 18.2.7 - jest-environment-jsdom: - specifier: ^29.7.0 - version: 29.7.0 - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) - typescript: - specifier: ^5.1.6 - version: 5.1.6 - -packages: - - /@aashutoshrathi/word-wrap@1.2.6: - resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} - engines: {node: '>=0.10.0'} - - /@adobe/css-tools@4.3.3: - resolution: {integrity: sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==} - - /@alloc/quick-lru@5.2.0: - resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} - engines: {node: '>=10'} - - /@ampproject/remapping@2.2.0: - resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/gen-mapping': 0.1.1 - '@jridgewell/trace-mapping': 0.3.19 - - /@architect/functions@5.4.1: - resolution: {integrity: sha512-F13FBUvVHjerUaSdnXIC3pZUnI10lxyVZ7HsrU8vM2qB5pFNqw5EgqcnVgORz/eqCcqevpIKayQ9yOUf/HuBAA==} - engines: {node: '>=12'} - dependencies: - cookie: 0.5.0 - cookie-signature: 1.2.1 - csrf: 3.1.0 - node-webtokens: 1.0.4 - run-parallel: 1.2.0 - run-waterfall: 1.1.7 - uid-safe: 2.1.5 - dev: false - - /@babel/code-frame@7.23.5: - resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.23.4 - chalk: 2.4.2 - - /@babel/compat-data@7.23.5: - resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} - engines: {node: '>=6.9.0'} - - /@babel/core@7.23.7: - resolution: {integrity: sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==} - engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.2.0 - '@babel/code-frame': 7.23.5 - '@babel/generator': 7.23.6 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) - '@babel/helpers': 7.23.8 - '@babel/parser': 7.23.6 - '@babel/template': 7.22.15 - '@babel/traverse': 7.23.7 - '@babel/types': 7.23.6 - convert-source-map: 2.0.0 - debug: 4.4.0(supports-color@8.1.1) - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - /@babel/eslint-parser@7.23.10(@babel/core@7.23.7)(eslint@8.56.0): - resolution: {integrity: sha512-3wSYDPZVnhseRnxRJH6ZVTNknBz76AEnyC+AYYhasjP3Yy23qz0ERR7Fcd2SHmYuSFJ2kY9gaaDd3vyqU09eSw==} - engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} - peerDependencies: - '@babel/core': ^7.11.0 - eslint: ^7.5.0 || ^8.0.0 - dependencies: - '@babel/core': 7.23.7 - '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 - eslint: 8.56.0 - eslint-visitor-keys: 2.1.0 - semver: 6.3.1 - dev: false - - /@babel/generator@7.23.6: - resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.6 - '@jridgewell/gen-mapping': 0.3.2 - '@jridgewell/trace-mapping': 0.3.19 - jsesc: 2.5.2 - - /@babel/helper-annotate-as-pure@7.18.6: - resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.6 - dev: false - - /@babel/helper-builder-binary-assignment-operator-visitor@7.18.6: - resolution: {integrity: sha512-KT10c1oWEpmrIRYnthbzHgoOf6B+Xd6a5yhdbNtdhtG7aO1or5HViuf1TQR36xY/QprXA5nvxO6nAjhJ4y38jw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-explode-assignable-expression': 7.18.6 - '@babel/types': 7.23.6 - dev: false - - /@babel/helper-compilation-targets@7.23.6: - resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/compat-data': 7.23.5 - '@babel/helper-validator-option': 7.23.5 - browserslist: 4.22.2 - lru-cache: 5.1.1 - semver: 6.3.1 - - /@babel/helper-create-class-features-plugin@7.21.8(@babel/core@7.23.7): - resolution: {integrity: sha512-+THiN8MqiH2AczyuZrnrKL6cAxFRRQDKW9h1YkBvbgKmAm6mwiacig1qT73DHIWMGo40GRnsEfN3LA+E6NtmSw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-member-expression-to-functions': 7.21.5 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-replace-supers': 7.21.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/helper-split-export-declaration': 7.22.6 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/helper-create-regexp-features-plugin@7.21.8(@babel/core@7.23.7): - resolution: {integrity: sha512-zGuSdedkFtsFHGbexAvNuipg1hbtitDLo2XE8/uf6Y9sOQV1xsYX/2pNbtedp/X0eU1pIt+kGvaqHCowkRbS5g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-annotate-as-pure': 7.18.6 - regexpu-core: 5.3.2 - semver: 6.3.1 - dev: false - - /@babel/helper-define-polyfill-provider@0.3.3(@babel/core@7.23.7): - resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} - peerDependencies: - '@babel/core': ^7.4.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 - debug: 4.4.0(supports-color@8.1.1) - lodash.debounce: 4.0.8 - resolve: 1.22.8 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/helper-environment-visitor@7.22.20: - resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} - engines: {node: '>=6.9.0'} - - /@babel/helper-explode-assignable-expression@7.18.6: - resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.6 - dev: false - - /@babel/helper-function-name@7.23.0: - resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.22.15 - '@babel/types': 7.23.6 - - /@babel/helper-hoist-variables@7.22.5: - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.6 - - /@babel/helper-member-expression-to-functions@7.21.5: - resolution: {integrity: sha512-nIcGfgwpH2u4n9GG1HpStW5Ogx7x7ekiFHbjjFRKXbn5zUvqO9ZgotCO4x1aNbKn/x/xOUaXEhyNHCwtFCpxWg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.6 - dev: false - - /@babel/helper-module-imports@7.22.15: - resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.6 - - /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.7): - resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-module-imports': 7.22.15 - '@babel/helper-simple-access': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.20 - - /@babel/helper-optimise-call-expression@7.18.6: - resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.6 - dev: false - - /@babel/helper-plugin-utils@7.22.5: - resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} - engines: {node: '>=6.9.0'} - - /@babel/helper-remap-async-to-generator@7.18.9(@babel/core@7.23.7): - resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-wrap-function': 7.20.5 - '@babel/types': 7.23.6 - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/helper-replace-supers@7.21.5: - resolution: {integrity: sha512-/y7vBgsr9Idu4M6MprbOVUfH3vs7tsIfnVWv/Ml2xgwvyH6LTngdfbf5AdsKwkJy4zgy1X/kuNrEKvhhK28Yrg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-member-expression-to-functions': 7.21.5 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/template': 7.22.15 - '@babel/traverse': 7.23.7 - '@babel/types': 7.23.6 - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/helper-simple-access@7.22.5: - resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.6 - - /@babel/helper-skip-transparent-expression-wrappers@7.20.0: - resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.6 - dev: false - - /@babel/helper-split-export-declaration@7.22.6: - resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.6 - - /@babel/helper-string-parser@7.23.4: - resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} - engines: {node: '>=6.9.0'} - - /@babel/helper-validator-identifier@7.22.20: - resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} - engines: {node: '>=6.9.0'} - - /@babel/helper-validator-option@7.23.5: - resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} - engines: {node: '>=6.9.0'} - - /@babel/helper-wrap-function@7.20.5: - resolution: {integrity: sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-function-name': 7.23.0 - '@babel/template': 7.22.15 - '@babel/traverse': 7.23.7 - '@babel/types': 7.23.6 - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/helpers@7.23.8: - resolution: {integrity: sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.22.15 - '@babel/traverse': 7.23.7 - '@babel/types': 7.23.6 - transitivePeerDependencies: - - supports-color - - /@babel/highlight@7.23.4: - resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.22.20 - chalk: 2.4.2 - js-tokens: 4.0.0 - - /@babel/parser@7.23.6: - resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.23.6 - - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.20.7(@babel/core@7.23.7): - resolution: {integrity: sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.13.0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.23.7) - dev: false - - /@babel/plugin-proposal-async-generator-functions@7.20.7(@babel/core@7.23.7): - resolution: {integrity: sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.23.7) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.7) - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-create-class-features-plugin': 7.21.8(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/plugin-proposal-class-static-block@7.21.0(@babel/core@7.23.7): - resolution: {integrity: sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-static-block instead. - peerDependencies: - '@babel/core': ^7.12.0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-create-class-features-plugin': 7.21.8(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.7) - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/plugin-proposal-dynamic-import@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-dynamic-import instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.7) - dev: false - - /@babel/plugin-proposal-export-namespace-from@7.18.9(@babel/core@7.23.7): - resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.7) - dev: false - - /@babel/plugin-proposal-json-strings@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-json-strings instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.7) - dev: false - - /@babel/plugin-proposal-logical-assignment-operators@7.20.7(@babel/core@7.23.7): - resolution: {integrity: sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-logical-assignment-operators instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.7) - dev: false - - /@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.7) - dev: false - - /@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.7) - dev: false - - /@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.23.7): - resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/compat-data': 7.23.5 - '@babel/core': 7.23.7 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.7) - '@babel/plugin-transform-parameters': 7.21.3(@babel/core@7.23.7) - dev: false - - /@babel/plugin-proposal-optional-catch-binding@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.7) - dev: false - - /@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.23.7): - resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.7) - dev: false - - /@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-create-class-features-plugin': 7.21.8(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/plugin-proposal-private-property-in-object@7.21.0(@babel/core@7.23.7): - resolution: {integrity: sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==} - engines: {node: '>=6.9.0'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-create-class-features-plugin': 7.21.8(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.7) - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} - engines: {node: '>=4'} - deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead. - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-create-regexp-features-plugin': 7.21.8(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.7): - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.7): - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.7): - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - - /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.23.7): - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-decorators@7.23.3(@babel/core@7.23.7): - resolution: {integrity: sha512-cf7Niq4/+/juY67E0PbgH0TDhLQ5J7zS8C/Q5FFx+DWyrRa9sUQdTXkjqKu8zGvuqr7vw1muKiukseihU+PJDA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.7): - resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.23.7): - resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-import-assertions@7.20.0(@babel/core@7.23.7): - resolution: {integrity: sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.7): - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.7): - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - - /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.23.7): - resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.7): - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.7): - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.7): - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.7): - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.7): - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.7): - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - - /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.23.7): - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.7): - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - - /@babel/plugin-syntax-typescript@7.21.4(@babel/core@7.23.7): - resolution: {integrity: sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - - /@babel/plugin-transform-arrow-functions@7.21.5(@babel/core@7.23.7): - resolution: {integrity: sha512-wb1mhwGOCaXHDTcsRYMKF9e5bbMgqwxtqa2Y1ifH96dXJPwbuLX9qHy3clhrxVqgMz7nyNXs8VkxdH8UBcjKqA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-async-to-generator@7.20.7(@babel/core@7.23.7): - resolution: {integrity: sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-module-imports': 7.22.15 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.23.7) - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/plugin-transform-block-scoped-functions@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-block-scoping@7.21.0(@babel/core@7.23.7): - resolution: {integrity: sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-classes@7.21.0(@babel/core@7.23.7): - resolution: {integrity: sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.21.5 - '@babel/helper-split-export-declaration': 7.22.6 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/plugin-transform-computed-properties@7.21.5(@babel/core@7.23.7): - resolution: {integrity: sha512-TR653Ki3pAwxBxUe8srfF3e4Pe3FTA46uaNHYyQwIoM4oWKSoOZiDNyHJ0oIoDIUPSRQbQG7jzgVBX3FPVne1Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/template': 7.22.15 - dev: false - - /@babel/plugin-transform-destructuring@7.21.3(@babel/core@7.23.7): - resolution: {integrity: sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-dotall-regex@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-create-regexp-features-plugin': 7.21.8(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-duplicate-keys@7.18.9(@babel/core@7.23.7): - resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-exponentiation-operator@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.6 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-for-of@7.21.5(@babel/core@7.23.7): - resolution: {integrity: sha512-nYWpjKW/7j/I/mZkGVgHJXh4bA1sfdFnJoOXwJuj4m3Q2EraO/8ZyrkCau9P5tbHQk01RMSt6KYLCsW7730SXQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-function-name@7.18.9(@babel/core@7.23.7): - resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-literals@7.18.9(@babel/core@7.23.7): - resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-member-expression-literals@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-modules-amd@7.20.11(@babel/core@7.23.7): - resolution: {integrity: sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-modules-commonjs@7.21.5(@babel/core@7.23.7): - resolution: {integrity: sha512-OVryBEgKUbtqMoB7eG2rs6UFexJi6Zj6FDXx+esBLPTCxCNxAY9o+8Di7IsUGJ+AVhp5ncK0fxWUBd0/1gPhrQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-simple-access': 7.22.5 - dev: false - - /@babel/plugin-transform-modules-systemjs@7.20.11(@babel/core@7.23.7): - resolution: {integrity: sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-identifier': 7.22.20 - dev: false - - /@babel/plugin-transform-modules-umd@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-named-capturing-groups-regex@7.20.5(@babel/core@7.23.7): - resolution: {integrity: sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-create-regexp-features-plugin': 7.21.8(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-new-target@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-object-super@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.21.5 - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/plugin-transform-parameters@7.21.3(@babel/core@7.23.7): - resolution: {integrity: sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-property-literals@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-react-display-name@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-react-jsx-development@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/plugin-transform-react-jsx': 7.18.6(@babel/core@7.23.7) - dev: false - - /@babel/plugin-transform-react-jsx@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-Mz7xMPxoy9kPS/JScj6fJs03TZ/fZ1dJPlMjRAgTaxaS0fUBk8FV/A2rRgfPsVCZqALNwMexD+0Uaf5zlcKPpw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-module-imports': 7.22.15 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.7) - '@babel/types': 7.23.6 - dev: false - - /@babel/plugin-transform-react-pure-annotations@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-regenerator@7.21.5(@babel/core@7.23.7): - resolution: {integrity: sha512-ZoYBKDb6LyMi5yCsByQ5jmXsHAQDDYeexT1Szvlmui+lADvfSecr5Dxd/PkrTC3pAD182Fcju1VQkB4oCp9M+w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - regenerator-transform: 0.15.1 - dev: false - - /@babel/plugin-transform-reserved-words@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-shorthand-properties@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-spread@7.20.7(@babel/core@7.23.7): - resolution: {integrity: sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - dev: false - - /@babel/plugin-transform-sticky-regex@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-template-literals@7.18.9(@babel/core@7.23.7): - resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-typeof-symbol@7.18.9(@babel/core@7.23.7): - resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-typescript@7.21.3(@babel/core@7.23.7): - resolution: {integrity: sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-create-class-features-plugin': 7.21.8(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.23.7) - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/plugin-transform-unicode-escapes@7.21.5(@babel/core@7.23.7): - resolution: {integrity: sha512-LYm/gTOwZqsYohlvFUe/8Tujz75LqqVC2w+2qPHLR+WyWHGCZPN1KBpJCJn+4Bk4gOkQy/IXKIge6az5MqwlOg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/plugin-transform-unicode-regex@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-create-regexp-features-plugin': 7.21.8(@babel/core@7.23.7) - '@babel/helper-plugin-utils': 7.22.5 - dev: false - - /@babel/preset-env@7.21.5(@babel/core@7.23.7): - resolution: {integrity: sha512-wH00QnTTldTbf/IefEVyChtRdw5RJvODT/Vb4Vcxq1AZvtXj6T0YeX0cAcXhI6/BdGuiP3GcNIL4OQbI2DVNxg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/compat-data': 7.23.5 - '@babel/core': 7.23.7 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.20.7(@babel/core@7.23.7) - '@babel/plugin-proposal-async-generator-functions': 7.20.7(@babel/core@7.23.7) - '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-proposal-class-static-block': 7.21.0(@babel/core@7.23.7) - '@babel/plugin-proposal-dynamic-import': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-proposal-export-namespace-from': 7.18.9(@babel/core@7.23.7) - '@babel/plugin-proposal-json-strings': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-proposal-logical-assignment-operators': 7.20.7(@babel/core@7.23.7) - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.23.7) - '@babel/plugin-proposal-optional-catch-binding': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.23.7) - '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-proposal-private-property-in-object': 7.21.0(@babel/core@7.23.7) - '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.7) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.7) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.7) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.7) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.7) - '@babel/plugin-syntax-import-assertions': 7.20.0(@babel/core@7.23.7) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.7) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.7) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.7) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.7) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.7) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.7) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.7) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.7) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.7) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.7) - '@babel/plugin-transform-arrow-functions': 7.21.5(@babel/core@7.23.7) - '@babel/plugin-transform-async-to-generator': 7.20.7(@babel/core@7.23.7) - '@babel/plugin-transform-block-scoped-functions': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-block-scoping': 7.21.0(@babel/core@7.23.7) - '@babel/plugin-transform-classes': 7.21.0(@babel/core@7.23.7) - '@babel/plugin-transform-computed-properties': 7.21.5(@babel/core@7.23.7) - '@babel/plugin-transform-destructuring': 7.21.3(@babel/core@7.23.7) - '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-duplicate-keys': 7.18.9(@babel/core@7.23.7) - '@babel/plugin-transform-exponentiation-operator': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-for-of': 7.21.5(@babel/core@7.23.7) - '@babel/plugin-transform-function-name': 7.18.9(@babel/core@7.23.7) - '@babel/plugin-transform-literals': 7.18.9(@babel/core@7.23.7) - '@babel/plugin-transform-member-expression-literals': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-modules-amd': 7.20.11(@babel/core@7.23.7) - '@babel/plugin-transform-modules-commonjs': 7.21.5(@babel/core@7.23.7) - '@babel/plugin-transform-modules-systemjs': 7.20.11(@babel/core@7.23.7) - '@babel/plugin-transform-modules-umd': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-named-capturing-groups-regex': 7.20.5(@babel/core@7.23.7) - '@babel/plugin-transform-new-target': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-object-super': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-parameters': 7.21.3(@babel/core@7.23.7) - '@babel/plugin-transform-property-literals': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-regenerator': 7.21.5(@babel/core@7.23.7) - '@babel/plugin-transform-reserved-words': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-shorthand-properties': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-spread': 7.20.7(@babel/core@7.23.7) - '@babel/plugin-transform-sticky-regex': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-template-literals': 7.18.9(@babel/core@7.23.7) - '@babel/plugin-transform-typeof-symbol': 7.18.9(@babel/core@7.23.7) - '@babel/plugin-transform-unicode-escapes': 7.21.5(@babel/core@7.23.7) - '@babel/plugin-transform-unicode-regex': 7.18.6(@babel/core@7.23.7) - '@babel/preset-modules': 0.1.5(@babel/core@7.23.7) - '@babel/types': 7.23.6 - babel-plugin-polyfill-corejs2: 0.3.3(@babel/core@7.23.7) - babel-plugin-polyfill-corejs3: 0.6.0(@babel/core@7.23.7) - babel-plugin-polyfill-regenerator: 0.4.1(@babel/core@7.23.7) - core-js-compat: 3.30.2 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/preset-modules@0.1.5(@babel/core@7.23.7): - resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.23.7) - '@babel/types': 7.23.6 - esutils: 2.0.3 - dev: false - - /@babel/preset-react@7.18.6(@babel/core@7.23.7): - resolution: {integrity: sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-transform-react-display-name': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-react-jsx': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-react-jsx-development': 7.18.6(@babel/core@7.23.7) - '@babel/plugin-transform-react-pure-annotations': 7.18.6(@babel/core@7.23.7) - dev: false - - /@babel/preset-typescript@7.21.5(@babel/core@7.23.7): - resolution: {integrity: sha512-iqe3sETat5EOrORXiQ6rWfoOg2y68Cs75B9wNxdPW4kixJxh7aXQE1KPdWLDniC24T/6dSnguF33W9j/ZZQcmA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.7) - '@babel/plugin-transform-modules-commonjs': 7.21.5(@babel/core@7.23.7) - '@babel/plugin-transform-typescript': 7.21.3(@babel/core@7.23.7) - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/regjsgen@0.8.0: - resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} - dev: false - - /@babel/runtime@7.23.9: - resolution: {integrity: sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.14.1 - - /@babel/template@7.22.15: - resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.23.5 - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 - - /@babel/traverse@7.23.7: - resolution: {integrity: sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.23.5 - '@babel/generator': 7.23.6 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 - debug: 4.4.0(supports-color@8.1.1) - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - - /@babel/types@7.23.6: - resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.23.4 - '@babel/helper-validator-identifier': 7.22.20 - to-fast-properties: 2.0.0 - - /@bcoe/v8-coverage@0.2.3: - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - - /@changesets/apply-release-plan@6.1.2: - resolution: {integrity: sha512-H8TV9E/WtJsDfoDVbrDGPXmkZFSv7W2KLqp4xX4MKZXshb0hsQZUNowUa8pnus9qb/5OZrFFRVsUsDCVHNW/AQ==} - dependencies: - '@babel/runtime': 7.23.9 - '@changesets/config': 2.2.0 - '@changesets/get-version-range-type': 0.3.2 - '@changesets/git': 1.5.0 - '@changesets/types': 5.2.0 - '@manypkg/get-packages': 1.1.3 - detect-indent: 6.1.0 - fs-extra: 7.0.1 - lodash.startcase: 4.4.0 - outdent: 0.5.0 - prettier: 2.8.1 - resolve-from: 5.0.0 - semver: 5.7.1 - dev: false - - /@changesets/assemble-release-plan@5.2.2(patch_hash=pkun533jr2p6iwxlsqfp6xfmxe): - resolution: {integrity: sha512-B1qxErQd85AeZgZFZw2bDKyOfdXHhG+X5S+W3Da2yCem8l/pRy4G/S7iOpEcMwg6lH8q2ZhgbZZwZ817D+aLuQ==} - dependencies: - '@babel/runtime': 7.23.9 - '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.4 - '@changesets/types': 5.2.0 - '@manypkg/get-packages': 1.1.3 - semver: 5.7.1 - dev: false - patched: true - - /@changesets/changelog-git@0.1.13: - resolution: {integrity: sha512-zvJ50Q+EUALzeawAxax6nF2WIcSsC5PwbuLeWkckS8ulWnuPYx8Fn/Sjd3rF46OzeKA8t30loYYV6TIzp4DIdg==} - dependencies: - '@changesets/types': 5.2.0 - dev: false - - /@changesets/cli@2.25.2: - resolution: {integrity: sha512-ACScBJXI3kRyMd2R8n8SzfttDHi4tmKSwVwXBazJOylQItSRSF4cGmej2E4FVf/eNfGy6THkL9GzAahU9ErZrA==} - hasBin: true - dependencies: - '@babel/runtime': 7.23.9 - '@changesets/apply-release-plan': 6.1.2 - '@changesets/assemble-release-plan': 5.2.2(patch_hash=pkun533jr2p6iwxlsqfp6xfmxe) - '@changesets/changelog-git': 0.1.13 - '@changesets/config': 2.2.0 - '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.4 - '@changesets/get-release-plan': 3.0.15 - '@changesets/git': 1.5.0 - '@changesets/logger': 0.0.5 - '@changesets/pre': 1.0.13 - '@changesets/read': 0.5.8 - '@changesets/types': 5.2.0 - '@changesets/write': 0.2.2 - '@manypkg/get-packages': 1.1.3 - '@types/is-ci': 3.0.0 - '@types/semver': 6.2.3 - ansi-colors: 4.1.3 - chalk: 2.4.2 - enquirer: 2.3.6 - external-editor: 3.1.0 - fs-extra: 7.0.1 - human-id: 1.0.2 - is-ci: 3.0.1 - meow: 6.1.1 - outdent: 0.5.0 - p-limit: 2.3.0 - preferred-pm: 3.0.3 - resolve-from: 5.0.0 - semver: 5.7.1 - spawndamnit: 2.0.0 - term-size: 2.2.1 - tty-table: 4.1.6 - dev: false - - /@changesets/config@2.2.0: - resolution: {integrity: sha512-GGaokp3nm5FEDk/Fv2PCRcQCOxGKKPRZ7prcMqxEr7VSsG75MnChQE8plaW1k6V8L2bJE+jZWiRm19LbnproOw==} - dependencies: - '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.4 - '@changesets/logger': 0.0.5 - '@changesets/types': 5.2.0 - '@manypkg/get-packages': 1.1.3 - fs-extra: 7.0.1 - micromatch: 4.0.5 - dev: false - - /@changesets/errors@0.1.4: - resolution: {integrity: sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==} - dependencies: - extendable-error: 0.1.7 - dev: false - - /@changesets/get-dependents-graph@1.3.4: - resolution: {integrity: sha512-+C4AOrrFY146ydrgKOo5vTZfj7vetNu1tWshOID+UjPUU9afYGDXI8yLnAeib1ffeBXV3TuGVcyphKpJ3cKe+A==} - dependencies: - '@changesets/types': 5.2.0 - '@manypkg/get-packages': 1.1.3 - chalk: 2.4.2 - fs-extra: 7.0.1 - semver: 5.7.1 - dev: false - - /@changesets/get-github-info@0.5.1: - resolution: {integrity: sha512-w2yl3AuG+hFuEEmT6j1zDlg7GQLM/J2UxTmk0uJBMdRqHni4zXGe/vUlPfLom5KfX3cRfHc0hzGvloDPjWFNZw==} - dependencies: - dataloader: 1.4.0 - node-fetch: 2.6.9 - transitivePeerDependencies: - - encoding - dev: false - - /@changesets/get-release-plan@3.0.15: - resolution: {integrity: sha512-W1tFwxE178/en+zSj/Nqbc3mvz88mcdqUMJhRzN1jDYqN3QI4ifVaRF9mcWUU+KI0gyYEtYR65tour690PqTcA==} - dependencies: - '@babel/runtime': 7.23.9 - '@changesets/assemble-release-plan': 5.2.2(patch_hash=pkun533jr2p6iwxlsqfp6xfmxe) - '@changesets/config': 2.2.0 - '@changesets/pre': 1.0.13 - '@changesets/read': 0.5.8 - '@changesets/types': 5.2.0 - '@manypkg/get-packages': 1.1.3 - dev: false - - /@changesets/get-version-range-type@0.3.2: - resolution: {integrity: sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==} - dev: false - - /@changesets/git@1.5.0: - resolution: {integrity: sha512-Xo8AT2G7rQJSwV87c8PwMm6BAc98BnufRMsML7m7Iw8Or18WFvFmxqG5aOL5PBvhgq9KrKvaeIBNIymracSuHg==} - dependencies: - '@babel/runtime': 7.23.9 - '@changesets/errors': 0.1.4 - '@changesets/types': 5.2.0 - '@manypkg/get-packages': 1.1.3 - is-subdir: 1.2.0 - spawndamnit: 2.0.0 - dev: false - - /@changesets/logger@0.0.5: - resolution: {integrity: sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==} - dependencies: - chalk: 2.4.2 - dev: false - - /@changesets/parse@0.3.15: - resolution: {integrity: sha512-3eDVqVuBtp63i+BxEWHPFj2P1s3syk0PTrk2d94W9JD30iG+OER0Y6n65TeLlY8T2yB9Fvj6Ev5Gg0+cKe/ZUA==} - dependencies: - '@changesets/types': 5.2.0 - js-yaml: 3.14.1 - dev: false - - /@changesets/pre@1.0.13: - resolution: {integrity: sha512-jrZc766+kGZHDukjKhpBXhBJjVQMied4Fu076y9guY1D3H622NOw8AQaLV3oQsDtKBTrT2AUFjt9Z2Y9Qx+GfA==} - dependencies: - '@babel/runtime': 7.23.9 - '@changesets/errors': 0.1.4 - '@changesets/types': 5.2.0 - '@manypkg/get-packages': 1.1.3 - fs-extra: 7.0.1 - dev: false - - /@changesets/read@0.5.8: - resolution: {integrity: sha512-eYaNfxemgX7f7ELC58e7yqQICW5FB7V+bd1lKt7g57mxUrTveYME+JPaBPpYx02nP53XI6CQp6YxnR9NfmFPKw==} - dependencies: - '@babel/runtime': 7.23.9 - '@changesets/git': 1.5.0 - '@changesets/logger': 0.0.5 - '@changesets/parse': 0.3.15 - '@changesets/types': 5.2.0 - chalk: 2.4.2 - fs-extra: 7.0.1 - p-filter: 2.1.0 - dev: false - - /@changesets/types@4.1.0: - resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} - dev: false - - /@changesets/types@5.2.0: - resolution: {integrity: sha512-km/66KOqJC+eicZXsm2oq8A8bVTSpkZJ60iPV/Nl5Z5c7p9kk8xxh6XGRTlnludHldxOOfudhnDN2qPxtHmXzA==} - dev: false - - /@changesets/write@0.2.2: - resolution: {integrity: sha512-kCYNHyF3xaId1Q/QE+DF3UTrHTyg3Cj/f++T8S8/EkC+jh1uK2LFnM9h+EzV+fsmnZDrs7r0J4LLpeI/VWC5Hg==} - dependencies: - '@babel/runtime': 7.23.9 - '@changesets/types': 5.2.0 - fs-extra: 7.0.1 - human-id: 1.0.2 - prettier: 2.8.1 - dev: false - - /@cloudflare/kv-asset-handler@0.1.3: - resolution: {integrity: sha512-FNcunDuTmEfQTLRLtA6zz+buIXUHj1soPvSWzzQFBC+n2lsy+CGf/NIrR3SEPCmsVNQj70/Jx2lViCpq+09YpQ==} - dependencies: - mime: 2.6.0 - dev: false - - /@cloudflare/kv-asset-handler@0.3.4: - resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} - engines: {node: '>=16.13'} - dependencies: - mime: 3.0.0 - - /@cloudflare/workerd-darwin-64@1.20240821.1: - resolution: {integrity: sha512-CDBpfZKrSy4YrIdqS84z67r3Tzal2pOhjCsIb63IuCnvVes59/ft1qhczBzk9EffeOE2iTCrA4YBT7Sbn7USew==} - engines: {node: '>=16'} - cpu: [x64] - os: [darwin] - requiresBuild: true - optional: true - - /@cloudflare/workerd-darwin-arm64@1.20240821.1: - resolution: {integrity: sha512-Q+9RedvNbPcEt/dKni1oN94OxbvuNAeJkgHmrLFTGF8zu21wzOhVkQeRNxcYxrMa9mfStc457NAg13OVCj2kHQ==} - engines: {node: '>=16'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - optional: true - - /@cloudflare/workerd-linux-64@1.20240821.1: - resolution: {integrity: sha512-j6z3KsPtawrscoLuP985LbqFrmsJL6q1mvSXOXTqXGODAHIzGBipHARdOjms3UQqovzvqB2lQaQsZtLBwCZxtA==} - engines: {node: '>=16'} - cpu: [x64] - os: [linux] - requiresBuild: true - optional: true - - /@cloudflare/workerd-linux-arm64@1.20240821.1: - resolution: {integrity: sha512-I9bHgZOxJQW0CV5gTdilyxzTG7ILzbTirehQWgfPx9X77E/7eIbR9sboOMgyeC69W4he0SKtpx0sYZuTJu4ERw==} - engines: {node: '>=16'} - cpu: [arm64] - os: [linux] - requiresBuild: true - optional: true - - /@cloudflare/workerd-windows-64@1.20240821.1: - resolution: {integrity: sha512-keC97QPArs6LWbPejQM7/Y8Jy8QqyaZow4/ZdsGo+QjlOLiZRDpAenfZx3CBUoWwEeFwQTl2FLO+8hV1SWFFYw==} - engines: {node: '>=16'} - cpu: [x64] - os: [win32] - requiresBuild: true - optional: true - - /@cloudflare/workers-shared@0.4.1: - resolution: {integrity: sha512-nYh4r8JwOOjYIdH2zub++CmIKlkYFlpxI1nBHimoiHcytJXD/b7ldJ21TtfzUZMCgI78mxVlymMHA/ReaOxKlA==} - engines: {node: '>=16.7.0'} - - /@cloudflare/workers-types@4.20240208.0: - resolution: {integrity: sha512-MVGTTjZpJu4kJONvai5SdJzWIhOJbuweVZ3goI7FNyG+JdoQH41OoB+nMhLsX626vPLZVWGPIWsiSo/WZHzgQw==} - - /@colors/colors@1.5.0: - resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} - engines: {node: '>=0.1.90'} - requiresBuild: true - dev: false - optional: true - - /@cspotcode/source-map-support@0.8.1: - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - - /@cypress/request@2.88.10: - resolution: {integrity: sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg==} - engines: {node: '>= 6'} - dependencies: - aws-sign2: 0.7.0 - aws4: 1.11.0 - caseless: 0.12.0 - combined-stream: 1.0.8 - extend: 3.0.2 - forever-agent: 0.6.1 - form-data: 2.3.3 - http-signature: 1.3.6 - is-typedarray: 1.0.0 - isstream: 0.1.2 - json-stringify-safe: 5.0.1 - mime-types: 2.1.35 - performance-now: 2.1.0 - qs: 6.5.3 - safe-buffer: 5.2.1 - tough-cookie: 2.5.0 - tunnel-agent: 0.6.0 - uuid: 8.3.2 - dev: false - - /@cypress/xvfb@1.2.4(supports-color@8.1.1): - resolution: {integrity: sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==} - dependencies: - debug: 3.2.7(supports-color@8.1.1) - lodash.once: 4.1.1 - transitivePeerDependencies: - - supports-color - dev: false - - /@emotion/hash@0.9.1: - resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} - - /@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19): - resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} - peerDependencies: - esbuild: '*' - dependencies: - esbuild: 0.17.19 - - /@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19): - resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} - peerDependencies: - esbuild: '*' - dependencies: - esbuild: 0.17.19 - escape-string-regexp: 4.0.0 - rollup-plugin-node-polyfills: 0.2.1 - - /@esbuild/aix-ppc64@0.19.12: - resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - requiresBuild: true - optional: true - - /@esbuild/aix-ppc64@0.24.2: - resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - requiresBuild: true - optional: true - - /@esbuild/android-arm64@0.17.19: - resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - optional: true - - /@esbuild/android-arm64@0.17.6: - resolution: {integrity: sha512-YnYSCceN/dUzUr5kdtUzB+wZprCafuD89Hs0Aqv9QSdwhYQybhXTaSTcrl6X/aWThn1a/j0eEpUBGOE7269REg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - optional: true - - /@esbuild/android-arm64@0.19.12: - resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - optional: true - - /@esbuild/android-arm64@0.24.2: - resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - requiresBuild: true - optional: true - - /@esbuild/android-arm@0.17.19: - resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - optional: true - - /@esbuild/android-arm@0.17.6: - resolution: {integrity: sha512-bSC9YVUjADDy1gae8RrioINU6e1lCkg3VGVwm0QQ2E1CWcC4gnMce9+B6RpxuSsrsXsk1yojn7sp1fnG8erE2g==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - optional: true - - /@esbuild/android-arm@0.19.12: - resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - optional: true - - /@esbuild/android-arm@0.24.2: - resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - requiresBuild: true - optional: true - - /@esbuild/android-x64@0.17.19: - resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - optional: true - - /@esbuild/android-x64@0.17.6: - resolution: {integrity: sha512-MVcYcgSO7pfu/x34uX9u2QIZHmXAB7dEiLQC5bBl5Ryqtpj9lT2sg3gNDEsrPEmimSJW2FXIaxqSQ501YLDsZQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - optional: true - - /@esbuild/android-x64@0.19.12: - resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - optional: true - - /@esbuild/android-x64@0.24.2: - resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - requiresBuild: true - optional: true - - /@esbuild/darwin-arm64@0.17.19: - resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - optional: true - - /@esbuild/darwin-arm64@0.17.6: - resolution: {integrity: sha512-bsDRvlbKMQMt6Wl08nHtFz++yoZHsyTOxnjfB2Q95gato+Yi4WnRl13oC2/PJJA9yLCoRv9gqT/EYX0/zDsyMA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - optional: true - - /@esbuild/darwin-arm64@0.19.12: - resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - optional: true - - /@esbuild/darwin-arm64@0.24.2: - resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - optional: true - - /@esbuild/darwin-x64@0.17.19: - resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - optional: true - - /@esbuild/darwin-x64@0.17.6: - resolution: {integrity: sha512-xh2A5oPrYRfMFz74QXIQTQo8uA+hYzGWJFoeTE8EvoZGHb+idyV4ATaukaUvnnxJiauhs/fPx3vYhU4wiGfosg==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - optional: true - - /@esbuild/darwin-x64@0.19.12: - resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - optional: true - - /@esbuild/darwin-x64@0.24.2: - resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - requiresBuild: true - optional: true - - /@esbuild/freebsd-arm64@0.17.19: - resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - optional: true - - /@esbuild/freebsd-arm64@0.17.6: - resolution: {integrity: sha512-EnUwjRc1inT4ccZh4pB3v1cIhohE2S4YXlt1OvI7sw/+pD+dIE4smwekZlEPIwY6PhU6oDWwITrQQm5S2/iZgg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - optional: true - - /@esbuild/freebsd-arm64@0.19.12: - resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - optional: true - - /@esbuild/freebsd-arm64@0.24.2: - resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - optional: true - - /@esbuild/freebsd-x64@0.17.19: - resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - optional: true - - /@esbuild/freebsd-x64@0.17.6: - resolution: {integrity: sha512-Uh3HLWGzH6FwpviUcLMKPCbZUAFzv67Wj5MTwK6jn89b576SR2IbEp+tqUHTr8DIl0iDmBAf51MVaP7pw6PY5Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - optional: true - - /@esbuild/freebsd-x64@0.19.12: - resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - optional: true - - /@esbuild/freebsd-x64@0.24.2: - resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - optional: true - - /@esbuild/linux-arm64@0.17.19: - resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-arm64@0.17.6: - resolution: {integrity: sha512-bUR58IFOMJX523aDVozswnlp5yry7+0cRLCXDsxnUeQYJik1DukMY+apBsLOZJblpH+K7ox7YrKrHmJoWqVR9w==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-arm64@0.19.12: - resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-arm64@0.24.2: - resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-arm@0.17.19: - resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-arm@0.17.6: - resolution: {integrity: sha512-7YdGiurNt7lqO0Bf/U9/arrPWPqdPqcV6JCZda4LZgEn+PTQ5SMEI4MGR52Bfn3+d6bNEGcWFzlIxiQdS48YUw==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-arm@0.19.12: - resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-arm@0.24.2: - resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-ia32@0.17.19: - resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-ia32@0.17.6: - resolution: {integrity: sha512-ujp8uoQCM9FRcbDfkqECoARsLnLfCUhKARTP56TFPog8ie9JG83D5GVKjQ6yVrEVdMie1djH86fm98eY3quQkQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-ia32@0.19.12: - resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-ia32@0.24.2: - resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-loong64@0.17.19: - resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-loong64@0.17.6: - resolution: {integrity: sha512-y2NX1+X/Nt+izj9bLoiaYB9YXT/LoaQFYvCkVD77G/4F+/yuVXYCWz4SE9yr5CBMbOxOfBcy/xFL4LlOeNlzYQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-loong64@0.19.12: - resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-loong64@0.24.2: - resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-mips64el@0.17.19: - resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-mips64el@0.17.6: - resolution: {integrity: sha512-09AXKB1HDOzXD+j3FdXCiL/MWmZP0Ex9eR8DLMBVcHorrWJxWmY8Nms2Nm41iRM64WVx7bA/JVHMv081iP2kUA==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-mips64el@0.19.12: - resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-mips64el@0.24.2: - resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-ppc64@0.17.19: - resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-ppc64@0.17.6: - resolution: {integrity: sha512-AmLhMzkM8JuqTIOhxnX4ubh0XWJIznEynRnZAVdA2mMKE6FAfwT2TWKTwdqMG+qEaeyDPtfNoZRpJbD4ZBv0Tg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-ppc64@0.19.12: - resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-ppc64@0.24.2: - resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-riscv64@0.17.19: - resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-riscv64@0.17.6: - resolution: {integrity: sha512-Y4Ri62PfavhLQhFbqucysHOmRamlTVK10zPWlqjNbj2XMea+BOs4w6ASKwQwAiqf9ZqcY9Ab7NOU4wIgpxwoSQ==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-riscv64@0.19.12: - resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-riscv64@0.24.2: - resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-s390x@0.17.19: - resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-s390x@0.17.6: - resolution: {integrity: sha512-SPUiz4fDbnNEm3JSdUW8pBJ/vkop3M1YwZAVwvdwlFLoJwKEZ9L98l3tzeyMzq27CyepDQ3Qgoba44StgbiN5Q==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-s390x@0.19.12: - resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-s390x@0.24.2: - resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-x64@0.17.19: - resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-x64@0.17.6: - resolution: {integrity: sha512-a3yHLmOodHrzuNgdpB7peFGPx1iJ2x6m+uDvhP2CKdr2CwOaqEFMeSqYAHU7hG+RjCq8r2NFujcd/YsEsFgTGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-x64@0.19.12: - resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/linux-x64@0.24.2: - resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - requiresBuild: true - optional: true - - /@esbuild/netbsd-arm64@0.24.2: - resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - requiresBuild: true - optional: true - - /@esbuild/netbsd-x64@0.17.19: - resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - optional: true - - /@esbuild/netbsd-x64@0.17.6: - resolution: {integrity: sha512-EanJqcU/4uZIBreTrnbnre2DXgXSa+Gjap7ifRfllpmyAU7YMvaXmljdArptTHmjrkkKm9BK6GH5D5Yo+p6y5A==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - optional: true - - /@esbuild/netbsd-x64@0.19.12: - resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - optional: true - - /@esbuild/netbsd-x64@0.24.2: - resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - optional: true - - /@esbuild/openbsd-arm64@0.24.2: - resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - requiresBuild: true - optional: true - - /@esbuild/openbsd-x64@0.17.19: - resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - optional: true - - /@esbuild/openbsd-x64@0.17.6: - resolution: {integrity: sha512-xaxeSunhQRsTNGFanoOkkLtnmMn5QbA0qBhNet/XLVsc+OVkpIWPHcr3zTW2gxVU5YOHFbIHR9ODuaUdNza2Vw==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - optional: true - - /@esbuild/openbsd-x64@0.19.12: - resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - optional: true - - /@esbuild/openbsd-x64@0.24.2: - resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - optional: true - - /@esbuild/sunos-x64@0.17.19: - resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - optional: true - - /@esbuild/sunos-x64@0.17.6: - resolution: {integrity: sha512-gnMnMPg5pfMkZvhHee21KbKdc6W3GR8/JuE0Da1kjwpK6oiFU3nqfHuVPgUX2rsOx9N2SadSQTIYV1CIjYG+xw==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - optional: true - - /@esbuild/sunos-x64@0.19.12: - resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - optional: true - - /@esbuild/sunos-x64@0.24.2: - resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - requiresBuild: true - optional: true - - /@esbuild/win32-arm64@0.17.19: - resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - optional: true - - /@esbuild/win32-arm64@0.17.6: - resolution: {integrity: sha512-G95n7vP1UnGJPsVdKXllAJPtqjMvFYbN20e8RK8LVLhlTiSOH1sd7+Gt7rm70xiG+I5tM58nYgwWrLs6I1jHqg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - optional: true - - /@esbuild/win32-arm64@0.19.12: - resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - optional: true - - /@esbuild/win32-arm64@0.24.2: - resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - requiresBuild: true - optional: true - - /@esbuild/win32-ia32@0.17.19: - resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - optional: true - - /@esbuild/win32-ia32@0.17.6: - resolution: {integrity: sha512-96yEFzLhq5bv9jJo5JhTs1gI+1cKQ83cUpyxHuGqXVwQtY5Eq54ZEsKs8veKtiKwlrNimtckHEkj4mRh4pPjsg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - optional: true - - /@esbuild/win32-ia32@0.19.12: - resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - optional: true - - /@esbuild/win32-ia32@0.24.2: - resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - requiresBuild: true - optional: true - - /@esbuild/win32-x64@0.17.19: - resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - optional: true - - /@esbuild/win32-x64@0.17.6: - resolution: {integrity: sha512-n6d8MOyUrNp6G4VSpRcgjs5xj4A91svJSaiwLIDWVWEsZtpN5FA9NlBbZHDmAJc2e8e6SF4tkBD3HAvPF+7igA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - optional: true - - /@esbuild/win32-x64@0.19.12: - resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - optional: true - - /@esbuild/win32-x64@0.24.2: - resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - requiresBuild: true - optional: true - - /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - dependencies: - eslint: 8.56.0 - eslint-visitor-keys: 3.4.3 - - /@eslint-community/regexpp@4.10.0: - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - /@eslint/eslintrc@2.1.4: - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - ajv: 6.12.6 - debug: 4.4.0(supports-color@8.1.1) - espree: 9.6.1 - globals: 13.20.0 - ignore: 5.3.1 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - /@eslint/js@8.56.0: - resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - /@extra-number/significant-digits@1.3.9: - resolution: {integrity: sha512-E5PY/bCwrNqEHh4QS6AQBinLZ+sxM1lT8tsSVYk8VwhWIPp6fCU/BMRVq0V8iJ8LwS3FHmaA4vUzb78s4BIIyA==} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - dev: true - - /@fastify/busboy@2.1.0: - resolution: {integrity: sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==} - engines: {node: '>=14'} - - /@hapi/hoek@9.3.0: - resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} - dev: false - - /@hapi/topo@5.1.0: - resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} - dependencies: - '@hapi/hoek': 9.3.0 - dev: false - - /@humanwhocodes/config-array@0.11.14: - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} - engines: {node: '>=10.10.0'} - deprecated: Use @eslint/config-array instead - dependencies: - '@humanwhocodes/object-schema': 2.0.2 - debug: 4.4.0(supports-color@8.1.1) - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - /@humanwhocodes/module-importer@1.0.1: - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - /@humanwhocodes/object-schema@2.0.2: - resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} - deprecated: Use @eslint/object-schema instead - - /@isaacs/cliui@8.0.2: - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - dependencies: - string-width: 5.1.2 - string-width-cjs: /string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: /strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: /wrap-ansi@7.0.0 - - /@istanbuljs/load-nyc-config@1.1.0: - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 - - /@istanbuljs/schema@0.1.3: - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - - /@jest/console@29.6.4: - resolution: {integrity: sha512-wNK6gC0Ha9QeEPSkeJedQuTQqxZYnDPuDcDhVuVatRvMkL4D0VTvFVZj+Yuh6caG2aOfzkUZ36KtCmLNtR02hw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.3 - '@types/node': 18.17.1 - chalk: 4.1.2 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 - - /@jest/core@29.6.4: - resolution: {integrity: sha512-U/vq5ccNTSVgYH7mHnodHmCffGWHJnz/E1BEWlLuK5pM4FZmGfBn/nrJGLjUsSmyx3otCeqc1T31F4y08AMDLg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/console': 29.6.4 - '@jest/reporters': 29.6.4 - '@jest/test-result': 29.6.4 - '@jest/transform': 29.6.4 - '@jest/types': 29.6.3 - '@types/node': 18.17.1 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.3.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.6.3 - jest-config: 29.6.4(@types/node@18.17.1) - jest-haste-map: 29.6.4 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.6.4 - jest-resolve-dependencies: 29.6.4 - jest-runner: 29.6.4 - jest-runtime: 29.6.4 - jest-snapshot: 29.6.4 - jest-util: 29.7.0 - jest-validate: 29.6.3 - jest-watcher: 29.6.4 - micromatch: 4.0.5 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node - - /@jest/environment@29.7.0: - resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 18.17.1 - jest-mock: 29.7.0 - - /@jest/expect-utils@29.6.4: - resolution: {integrity: sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-get-type: 29.6.3 - - /@jest/expect@29.6.4: - resolution: {integrity: sha512-Warhsa7d23+3X5bLbrbYvaehcgX5TLYhI03JKoedTiI8uJU4IhqYBWF7OSSgUyz4IgLpUYPkK0AehA5/fRclAA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - expect: 29.6.4 - jest-snapshot: 29.6.4 - transitivePeerDependencies: - - supports-color - - /@jest/fake-timers@29.7.0: - resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.3 - '@sinonjs/fake-timers': 10.3.0 - '@types/node': 18.17.1 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - /@jest/globals@29.6.4: - resolution: {integrity: sha512-wVIn5bdtjlChhXAzVXavcY/3PEjf4VqM174BM3eGL5kMxLiZD5CLnbmkEyA1Dwh9q8XjP6E8RwjBsY/iCWrWsA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.6.4 - '@jest/types': 29.6.3 - jest-mock: 29.7.0 - transitivePeerDependencies: - - supports-color - - /@jest/reporters@29.6.4: - resolution: {integrity: sha512-sxUjWxm7QdchdrD3NfWKrL8FBsortZeibSJv4XLjESOOjSUOkjQcb0ZHJwfhEGIvBvTluTzfG2yZWZhkrXJu8g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.6.4 - '@jest/test-result': 29.6.4 - '@jest/transform': 29.6.4 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.19 - '@types/node': 18.17.1 - chalk: 4.1.2 - collect-v8-coverage: 1.0.1 - exit: 0.1.2 - glob: 7.2.0 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.0 - istanbul-lib-instrument: 6.0.0 - istanbul-lib-report: 3.0.0 - istanbul-lib-source-maps: 4.0.0 - istanbul-reports: 3.1.4 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - jest-worker: 29.6.4 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.1.0 - transitivePeerDependencies: - - supports-color - - /@jest/schemas@29.6.3: - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@sinclair/typebox': 0.27.8 - - /@jest/source-map@29.6.3: - resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jridgewell/trace-mapping': 0.3.19 - callsites: 3.1.0 - graceful-fs: 4.2.11 - - /@jest/test-result@29.6.4: - resolution: {integrity: sha512-uQ1C0AUEN90/dsyEirgMLlouROgSY+Wc/JanVVk0OiUKa5UFh7sJpMEM3aoUBAz2BRNvUJ8j3d294WFuRxSyOQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/console': 29.6.4 - '@jest/types': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.3 - collect-v8-coverage: 1.0.1 - - /@jest/test-sequencer@29.6.4: - resolution: {integrity: sha512-E84M6LbpcRq3fT4ckfKs9ryVanwkaIB0Ws9bw3/yP4seRLg/VaCZ/LgW0MCq5wwk4/iP/qnilD41aj2fsw2RMg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/test-result': 29.6.4 - graceful-fs: 4.2.11 - jest-haste-map: 29.6.4 - slash: 3.0.0 - - /@jest/transform@29.6.4: - resolution: {integrity: sha512-8thgRSiXUqtr/pPGY/OsyHuMjGyhVnWrFAwoxmIemlBuiMyU1WFs0tXoNxzcr4A4uErs/ABre76SGmrr5ab/AA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/core': 7.23.7 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.19 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.6.4 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - micromatch: 4.0.5 - pirates: 4.0.5 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color - - /@jest/types@29.6.3: - resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.3 - '@types/istanbul-reports': 3.0.1 - '@types/node': 18.17.1 - '@types/yargs': 17.0.24 - chalk: 4.1.2 - - /@jridgewell/gen-mapping@0.1.1: - resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - - /@jridgewell/gen-mapping@0.3.2: - resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.19 - - /@jridgewell/resolve-uri@3.1.1: - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} - engines: {node: '>=6.0.0'} - - /@jridgewell/set-array@1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} - - /@jridgewell/sourcemap-codec@1.4.15: - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - - /@jridgewell/trace-mapping@0.3.19: - resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 - - /@jridgewell/trace-mapping@0.3.9: - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 - - /@jspm/core@2.0.1: - resolution: {integrity: sha512-Lg3PnLp0QXpxwLIAuuJboLeRaIhrgJjeuh797QADg3xz8wGLugQOS5DpsE8A6i6Adgzf+bacllkKZG3J0tGfDw==} - dev: false - - /@kwsites/file-exists@1.1.1: - resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} - dependencies: - debug: 4.4.0(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - dev: false - - /@kwsites/promise-deferred@1.1.1: - resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} - dev: false - - /@manypkg/find-root@1.1.0: - resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} - dependencies: - '@babel/runtime': 7.23.9 - '@types/node': 12.20.55 - find-up: 4.1.0 - fs-extra: 8.1.0 - dev: false - - /@manypkg/get-packages@1.1.3: - resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} - dependencies: - '@babel/runtime': 7.23.9 - '@changesets/types': 4.1.0 - '@manypkg/find-root': 1.1.0 - fs-extra: 8.1.0 - globby: 11.1.0 - read-yaml-file: 1.1.0 - dev: false - - /@mcansh/remark-definition-links@2.4.1: - resolution: {integrity: sha512-SMlxBrpraic11Fu+Aw6V7jh6edIShh7Ijzg1nevaUFjh1tB9hTYyIkYRXQ45w729MFoTmSNg0b/leVQcdUKr0A==} - dependencies: - '@sindresorhus/slugify': 2.1.0 - unified: 10.1.2 - unist-util-visit: 4.1.1 - dev: false - - /@mdx-js/mdx@2.3.0: - resolution: {integrity: sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==} - dependencies: - '@types/estree-jsx': 1.0.0 - '@types/mdx': 2.0.5 - estree-util-build-jsx: 2.2.2 - estree-util-is-identifier-name: 2.1.0 - estree-util-to-js: 1.2.0 - estree-walker: 3.0.0 - hast-util-to-estree: 2.3.3 - markdown-extensions: 1.1.1 - periscopic: 3.0.4 - remark-mdx: 2.3.0 - remark-parse: 10.0.1 - remark-rehype: 10.1.0 - unified: 10.1.2 - unist-util-position-from-estree: 1.1.2 - unist-util-stringify-position: 3.0.0 - unist-util-visit: 4.1.1 - vfile: 5.3.2 - transitivePeerDependencies: - - supports-color - dev: false - - /@mdx-js/mdx@3.0.0: - resolution: {integrity: sha512-Icm0TBKBLYqroYbNW3BPnzMGn+7mwpQOK310aZ7+fkCtiU3aqv2cdcX+nd0Ydo3wI5Rx8bX2Z2QmGb/XcAClCw==} - dependencies: - '@types/estree': 1.0.6 - '@types/estree-jsx': 1.0.0 - '@types/hast': 3.0.3 - '@types/mdx': 2.0.5 - collapse-white-space: 2.1.0 - devlop: 1.1.0 - estree-util-build-jsx: 3.0.1 - estree-util-is-identifier-name: 3.0.0 - estree-util-to-js: 2.0.0 - estree-walker: 3.0.0 - hast-util-to-estree: 3.1.0 - hast-util-to-jsx-runtime: 2.2.0 - markdown-extensions: 2.0.0 - periscopic: 3.0.4 - remark-mdx: 3.0.0 - remark-parse: 11.0.0 - remark-rehype: 11.0.0 - source-map: 0.7.3 - unified: 11.0.4 - unist-util-position-from-estree: 2.0.0 - unist-util-stringify-position: 4.0.0 - unist-util-visit: 5.0.0 - vfile: 6.0.1 - transitivePeerDependencies: - - supports-color - dev: false - - /@mdx-js/rollup@3.0.0(rollup@2.79.2): - resolution: {integrity: sha512-ITvGiwPGEBW+D7CCnpSA9brzAosIWHAi4y+Air8wgfLnez8aWue50avHtWMfnFLCp7vt+JQ9UM8nwfuQuuydxw==} - peerDependencies: - rollup: '>=2' - dependencies: - '@mdx-js/mdx': 3.0.0 - '@rollup/pluginutils': 5.0.5(rollup@2.79.2) - rollup: 2.79.2 - source-map: 0.7.3 - vfile: 6.0.1 - transitivePeerDependencies: - - supports-color - dev: false - - /@mswjs/cookies@0.2.2: - resolution: {integrity: sha512-mlN83YSrcFgk7Dm1Mys40DLssI1KdJji2CMKN8eOlBqsTADYzj2+jWzsANsUTFbxDMWPD5e9bfA1RGqBpS3O1g==} - engines: {node: '>=14'} - dependencies: - '@types/set-cookie-parser': 2.4.7 - set-cookie-parser: 2.6.0 - dev: true - - /@mswjs/interceptors@0.17.10: - resolution: {integrity: sha512-N8x7eSLGcmUFNWZRxT1vsHvypzIRgQYdG0rJey/rZCy6zT/30qDt8Joj7FxzGNLSwXbeZqJOMqDurp7ra4hgbw==} - engines: {node: '>=14'} - dependencies: - '@open-draft/until': 1.0.3 - '@types/debug': 4.1.8 - '@xmldom/xmldom': 0.8.10 - debug: 4.4.0(supports-color@8.1.1) - headers-polyfill: 3.2.5 - outvariant: 1.4.2 - strict-event-emitter: 0.2.8 - web-encoding: 1.1.5 - transitivePeerDependencies: - - supports-color - dev: true - - /@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1: - resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} - dependencies: - eslint-scope: 5.1.1 - dev: false - - /@nodelib/fs.scandir@2.1.5: - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - /@nodelib/fs.stat@2.0.5: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - /@nodelib/fs.walk@1.2.8: - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.13.0 - - /@npmcli/fs@3.1.0: - resolution: {integrity: sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - semver: 7.5.4 - dev: false - - /@npmcli/git@4.1.0: - resolution: {integrity: sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - '@npmcli/promise-spawn': 6.0.2 - lru-cache: 7.18.3 - npm-pick-manifest: 8.0.2 - proc-log: 3.0.0 - promise-inflight: 1.0.1 - promise-retry: 2.0.1 - semver: 7.5.4 - which: 3.0.1 - transitivePeerDependencies: - - bluebird - dev: false - - /@npmcli/package-json@4.0.1: - resolution: {integrity: sha512-lRCEGdHZomFsURroh522YvA/2cVb9oPIJrjHanCJZkiasz1BzcnLr3tBJhlV7S86MBJBuAQ33is2D60YitZL2Q==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - '@npmcli/git': 4.1.0 - glob: 10.3.10 - hosted-git-info: 6.1.1 - json-parse-even-better-errors: 3.0.1 - normalize-package-data: 5.0.0 - proc-log: 3.0.0 - semver: 7.5.4 - transitivePeerDependencies: - - bluebird - dev: false - - /@npmcli/promise-spawn@6.0.2: - resolution: {integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - which: 3.0.1 - dev: false - - /@octokit/auth-token@2.5.0: - resolution: {integrity: sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==} - dependencies: - '@octokit/types': 6.34.0 - dev: false - - /@octokit/core@3.6.0: - resolution: {integrity: sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==} - dependencies: - '@octokit/auth-token': 2.5.0 - '@octokit/graphql': 4.8.0 - '@octokit/request': 5.6.3 - '@octokit/request-error': 2.1.0 - '@octokit/types': 6.34.0 - before-after-hook: 2.2.2 - universal-user-agent: 6.0.0 - transitivePeerDependencies: - - encoding - dev: false - - /@octokit/endpoint@6.0.12: - resolution: {integrity: sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==} - dependencies: - '@octokit/types': 6.34.0 - is-plain-object: 5.0.0 - universal-user-agent: 6.0.0 - dev: false - - /@octokit/graphql@4.8.0: - resolution: {integrity: sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==} - dependencies: - '@octokit/request': 5.6.3 - '@octokit/types': 6.34.0 - universal-user-agent: 6.0.0 - transitivePeerDependencies: - - encoding - dev: false - - /@octokit/openapi-types@11.2.0: - resolution: {integrity: sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==} - dev: false - - /@octokit/plugin-paginate-rest@2.17.0(@octokit/core@3.6.0): - resolution: {integrity: sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==} - peerDependencies: - '@octokit/core': '>=2' - dependencies: - '@octokit/core': 3.6.0 - '@octokit/types': 6.34.0 - dev: false - - /@octokit/plugin-request-log@1.0.4(@octokit/core@3.6.0): - resolution: {integrity: sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==} - peerDependencies: - '@octokit/core': '>=3' - dependencies: - '@octokit/core': 3.6.0 - dev: false - - /@octokit/plugin-rest-endpoint-methods@5.13.0(@octokit/core@3.6.0): - resolution: {integrity: sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==} - peerDependencies: - '@octokit/core': '>=3' - dependencies: - '@octokit/core': 3.6.0 - '@octokit/types': 6.34.0 - deprecation: 2.3.1 - dev: false - - /@octokit/request-error@2.1.0: - resolution: {integrity: sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==} - dependencies: - '@octokit/types': 6.34.0 - deprecation: 2.3.1 - once: 1.4.0 - dev: false - - /@octokit/request@5.6.3: - resolution: {integrity: sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==} - dependencies: - '@octokit/endpoint': 6.0.12 - '@octokit/request-error': 2.1.0 - '@octokit/types': 6.34.0 - is-plain-object: 5.0.0 - node-fetch: 2.6.9 - universal-user-agent: 6.0.0 - transitivePeerDependencies: - - encoding - dev: false - - /@octokit/rest@18.12.0: - resolution: {integrity: sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==} - dependencies: - '@octokit/core': 3.6.0 - '@octokit/plugin-paginate-rest': 2.17.0(@octokit/core@3.6.0) - '@octokit/plugin-request-log': 1.0.4(@octokit/core@3.6.0) - '@octokit/plugin-rest-endpoint-methods': 5.13.0(@octokit/core@3.6.0) - transitivePeerDependencies: - - encoding - dev: false - - /@octokit/types@6.34.0: - resolution: {integrity: sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==} - dependencies: - '@octokit/openapi-types': 11.2.0 - dev: false - - /@open-draft/until@1.0.3: - resolution: {integrity: sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q==} - dev: true - - /@pkgjs/parseargs@0.11.0: - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - requiresBuild: true - optional: true - - /@playwright/test@1.49.1: - resolution: {integrity: sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==} - engines: {node: '>=18'} - hasBin: true - dependencies: - playwright: 1.49.1 - dev: false - - /@remix-run/changelog-github@0.0.5: - resolution: {integrity: sha512-43tqwUqWqirbv6D9uzo55ASPsCJ61Ein1k/M8qn+Qpros0MmbmuzjLVPmtaxfxfe2ANX0LefLvCD0pAgr1tp4g==} - dependencies: - '@changesets/errors': 0.1.4 - '@changesets/get-github-info': 0.5.1 - '@changesets/types': 5.2.0 - dotenv: 8.6.0 - transitivePeerDependencies: - - encoding - dev: false - - /@remix-run/router@1.23.0: - resolution: {integrity: sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==} - engines: {node: '>=14.0.0'} - dev: false - - /@remix-run/web-blob@3.1.0: - resolution: {integrity: sha512-owGzFLbqPH9PlKb8KvpNJ0NO74HWE2euAn61eEiyCXX/oteoVzTVSN8mpLgDjaxBf2btj5/nUllSUgpyd6IH6g==} - dependencies: - '@remix-run/web-stream': 1.1.0 - web-encoding: 1.1.5 - dev: false - - /@remix-run/web-fetch@4.4.2: - resolution: {integrity: sha512-jgKfzA713/4kAW/oZ4bC3MoLWyjModOVDjFPNseVqcJKSafgIscrYL9G50SurEYLswPuoU3HzSbO0jQCMYWHhA==} - engines: {node: ^10.17 || >=12.3} - dependencies: - '@remix-run/web-blob': 3.1.0 - '@remix-run/web-file': 3.1.0 - '@remix-run/web-form-data': 3.1.0 - '@remix-run/web-stream': 1.1.0 - '@web3-storage/multipart-parser': 1.0.0 - abort-controller: 3.0.0 - data-uri-to-buffer: 3.0.1 - mrmime: 1.0.1 - dev: false - - /@remix-run/web-file@3.1.0: - resolution: {integrity: sha512-dW2MNGwoiEYhlspOAXFBasmLeYshyAyhIdrlXBi06Duex5tDr3ut2LFKVj7tyHLmn8nnNwFf1BjNbkQpygC2aQ==} - dependencies: - '@remix-run/web-blob': 3.1.0 - dev: false - - /@remix-run/web-form-data@3.1.0: - resolution: {integrity: sha512-NdeohLMdrb+pHxMQ/Geuzdp0eqPbea+Ieo8M8Jx2lGC6TBHsgHzYcBvr0LyPdPVycNRDEpWpiDdCOdCryo3f9A==} - dependencies: - web-encoding: 1.1.5 - dev: false - - /@remix-run/web-stream@1.1.0: - resolution: {integrity: sha512-KRJtwrjRV5Bb+pM7zxcTJkhIqWWSy+MYsIxHK+0m5atcznsf15YwUBWHWulZerV2+vvHH1Lp1DD7pw6qKW8SgA==} - dependencies: - web-streams-polyfill: 3.2.0 - dev: false - - /@rollup/plugin-babel@5.3.1(@babel/core@7.23.7)(rollup@2.79.2): - resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} - engines: {node: '>= 10.0.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@types/babel__core': ^7.1.9 - rollup: ^1.20.0||^2.0.0 - peerDependenciesMeta: - '@types/babel__core': - optional: true - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-module-imports': 7.22.15 - '@rollup/pluginutils': 3.1.0(rollup@2.79.2) - rollup: 2.79.2 - dev: false - - /@rollup/plugin-commonjs@21.1.0(rollup@2.79.2): - resolution: {integrity: sha512-6ZtHx3VHIp2ReNNDxHjuUml6ur+WcQ28N1yHgCQwsbNkQg2suhxGMDQGJOn/KuDxKtd1xuZP5xSTwBA4GQ8hbA==} - engines: {node: '>= 8.0.0'} - peerDependencies: - rollup: ^2.38.3 - dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.79.2) - commondir: 1.0.1 - estree-walker: 2.0.2 - glob: 7.2.0 - is-reference: 1.2.1 - magic-string: 0.25.9 - resolve: 1.22.8 - rollup: 2.79.2 - dev: false - - /@rollup/plugin-json@5.0.2(rollup@2.79.2): - resolution: {integrity: sha512-D1CoOT2wPvadWLhVcmpkDnesTzjhNIQRWLsc3fA49IFOP2Y84cFOOJ+nKGYedvXHKUsPeq07HR4hXpBBr+CHlA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - '@rollup/pluginutils': 5.0.5(rollup@2.79.2) - rollup: 2.79.2 - dev: false - - /@rollup/plugin-node-resolve@11.2.1(rollup@2.79.2): - resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==} - engines: {node: '>= 10.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.79.2) - '@types/resolve': 1.17.1 - builtin-modules: 3.3.0 - deepmerge: 4.2.2 - is-module: 1.0.0 - resolve: 1.22.8 - rollup: 2.79.2 - dev: false - - /@rollup/plugin-replace@5.0.2(rollup@2.79.2): - resolution: {integrity: sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - '@rollup/pluginutils': 5.0.5(rollup@2.79.2) - magic-string: 0.27.0 - rollup: 2.79.2 - dev: false - - /@rollup/pluginutils@3.1.0(rollup@2.79.2): - resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} - engines: {node: '>= 8.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - dependencies: - '@types/estree': 0.0.39 - estree-walker: 1.0.1 - picomatch: 2.3.1 - rollup: 2.79.2 - dev: false - - /@rollup/pluginutils@5.0.5(rollup@2.79.2): - resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - '@types/estree': 1.0.6 - estree-walker: 2.0.2 - picomatch: 2.3.1 - rollup: 2.79.2 - dev: false - - /@rollup/rollup-android-arm-eabi@4.29.1: - resolution: {integrity: sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==} - cpu: [arm] - os: [android] - requiresBuild: true - optional: true - - /@rollup/rollup-android-arm64@4.29.1: - resolution: {integrity: sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==} - cpu: [arm64] - os: [android] - requiresBuild: true - optional: true - - /@rollup/rollup-darwin-arm64@4.29.1: - resolution: {integrity: sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==} - cpu: [arm64] - os: [darwin] - requiresBuild: true - optional: true - - /@rollup/rollup-darwin-x64@4.29.1: - resolution: {integrity: sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==} - cpu: [x64] - os: [darwin] - requiresBuild: true - optional: true - - /@rollup/rollup-freebsd-arm64@4.29.1: - resolution: {integrity: sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - optional: true - - /@rollup/rollup-freebsd-x64@4.29.1: - resolution: {integrity: sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==} - cpu: [x64] - os: [freebsd] - requiresBuild: true - optional: true - - /@rollup/rollup-linux-arm-gnueabihf@4.29.1: - resolution: {integrity: sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==} - cpu: [arm] - os: [linux] - requiresBuild: true - optional: true - - /@rollup/rollup-linux-arm-musleabihf@4.29.1: - resolution: {integrity: sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==} - cpu: [arm] - os: [linux] - requiresBuild: true - optional: true - - /@rollup/rollup-linux-arm64-gnu@4.29.1: - resolution: {integrity: sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==} - cpu: [arm64] - os: [linux] - requiresBuild: true - optional: true - - /@rollup/rollup-linux-arm64-musl@4.29.1: - resolution: {integrity: sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==} - cpu: [arm64] - os: [linux] - requiresBuild: true - optional: true - - /@rollup/rollup-linux-loongarch64-gnu@4.29.1: - resolution: {integrity: sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==} - cpu: [loong64] - os: [linux] - requiresBuild: true - optional: true - - /@rollup/rollup-linux-powerpc64le-gnu@4.29.1: - resolution: {integrity: sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==} - cpu: [ppc64] - os: [linux] - requiresBuild: true - optional: true - - /@rollup/rollup-linux-riscv64-gnu@4.29.1: - resolution: {integrity: sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==} - cpu: [riscv64] - os: [linux] - requiresBuild: true - optional: true - - /@rollup/rollup-linux-s390x-gnu@4.29.1: - resolution: {integrity: sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==} - cpu: [s390x] - os: [linux] - requiresBuild: true - optional: true - - /@rollup/rollup-linux-x64-gnu@4.29.1: - resolution: {integrity: sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==} - cpu: [x64] - os: [linux] - requiresBuild: true - optional: true - - /@rollup/rollup-linux-x64-musl@4.29.1: - resolution: {integrity: sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==} - cpu: [x64] - os: [linux] - requiresBuild: true - optional: true - - /@rollup/rollup-win32-arm64-msvc@4.29.1: - resolution: {integrity: sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==} - cpu: [arm64] - os: [win32] - requiresBuild: true - optional: true - - /@rollup/rollup-win32-ia32-msvc@4.29.1: - resolution: {integrity: sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==} - cpu: [ia32] - os: [win32] - requiresBuild: true - optional: true - - /@rollup/rollup-win32-x64-msvc@4.29.1: - resolution: {integrity: sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==} - cpu: [x64] - os: [win32] - requiresBuild: true - optional: true - - /@rushstack/eslint-patch@1.7.2: - resolution: {integrity: sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA==} - dev: false - - /@sideway/address@4.1.4: - resolution: {integrity: sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==} - dependencies: - '@hapi/hoek': 9.3.0 - dev: false - - /@sideway/formula@3.0.1: - resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} - dev: false - - /@sideway/pinpoint@2.0.0: - resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} - dev: false - - /@sinclair/typebox@0.27.8: - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - - /@sindresorhus/slugify@2.1.0: - resolution: {integrity: sha512-gU3Gdm/V167BmUwIn8APHZ3SeeRVRUSOdXxnt7Q/JkUHLXaaTA/prYmoRumwsSitJZWUDYMzDWdWgrOdvE8IRQ==} - engines: {node: '>=12'} - dependencies: - '@sindresorhus/transliterate': 1.5.0 - escape-string-regexp: 5.0.0 - dev: false - - /@sindresorhus/transliterate@1.5.0: - resolution: {integrity: sha512-/sfSkoNelLq5riqNRp5uBjHIKBi1MWZk9ubRT1WiBQuTfmDf7BeQkph2DJzRB83QagMPHk2VDjuvpy0VuwyzdA==} - engines: {node: '>=12'} - dependencies: - escape-string-regexp: 5.0.0 - lodash.deburr: 4.1.0 - dev: false - - /@sinonjs/commons@3.0.0: - resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} - dependencies: - type-detect: 4.0.8 - - /@sinonjs/fake-timers@10.3.0: - resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} - dependencies: - '@sinonjs/commons': 3.0.0 - - /@testing-library/cypress@8.0.2(cypress@9.6.0): - resolution: {integrity: sha512-KVdm7n37sg/A4e3wKMD4zUl0NpzzVhx06V9Tf0hZHZ7nrZ4yFva6Zwg2EFF1VzHkEfN/ahUzRtT1qiW+vuWnJw==} - engines: {node: '>=12', npm: '>=6'} - peerDependencies: - cypress: ^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 - dependencies: - '@babel/runtime': 7.23.9 - '@testing-library/dom': 8.16.0 - cypress: 9.6.0 - dev: false - - /@testing-library/dom@8.16.0: - resolution: {integrity: sha512-uxF4zmnLHHDlmW4l+0WDjcgLVwCvH+OVLpD8Dfp+Bjfz85prwxWGbwXgJdLtkgjD0qfOzkJF9SmA6YZPsMYX4w==} - engines: {node: '>=12'} - dependencies: - '@babel/code-frame': 7.23.5 - '@babel/runtime': 7.23.9 - '@types/aria-query': 4.2.2 - aria-query: 5.3.0 - chalk: 4.1.2 - dom-accessibility-api: 0.5.16 - lz-string: 1.5.0 - pretty-format: 27.5.1 - - /@testing-library/dom@9.3.4: - resolution: {integrity: sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==} - engines: {node: '>=14'} - dependencies: - '@babel/code-frame': 7.23.5 - '@babel/runtime': 7.23.9 - '@types/aria-query': 5.0.4 - aria-query: 5.1.3 - chalk: 4.1.2 - dom-accessibility-api: 0.5.16 - lz-string: 1.5.0 - pretty-format: 27.5.1 - dev: false - - /@testing-library/jest-dom@5.17.0: - resolution: {integrity: sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==} - engines: {node: '>=8', npm: '>=6', yarn: '>=1'} - dependencies: - '@adobe/css-tools': 4.3.3 - '@babel/runtime': 7.23.9 - '@types/testing-library__jest-dom': 5.14.2 - aria-query: 5.3.0 - chalk: 3.0.0 - css.escape: 1.5.1 - dom-accessibility-api: 0.5.16 - lodash: 4.17.21 - redent: 3.0.0 - - /@testing-library/react@13.3.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-DB79aA426+deFgGSjnf5grczDPiL4taK3hFaa+M5q7q20Kcve9eQottOG5kZ74KEr55v0tU2CQormSSDK87zYQ==} - engines: {node: '>=12'} - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - dependencies: - '@babel/runtime': 7.23.9 - '@testing-library/dom': 8.16.0 - '@types/react-dom': 18.2.7 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - - /@testing-library/user-event@14.5.1(@testing-library/dom@9.3.4): - resolution: {integrity: sha512-UCcUKrUYGj7ClomOo2SpNVvx4/fkd/2BbIHDCle8A0ax+P3bU7yJwDBDrS6ZwdTMARWTGODX1hEsCcO+7beJjg==} - engines: {node: '>=12', npm: '>=6'} - peerDependencies: - '@testing-library/dom': '>=7.21.4' - dependencies: - '@testing-library/dom': 9.3.4 - dev: false - - /@tootallnate/once@2.0.0: - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} - dev: true - - /@tootallnate/quickjs-emscripten@0.23.0: - resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} - dev: false - - /@types/acorn@4.0.6: - resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} - dependencies: - '@types/estree': 1.0.6 - dev: false - - /@types/aria-query@4.2.2: - resolution: {integrity: sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==} - - /@types/aria-query@5.0.4: - resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} - dev: false - - /@types/aws-lambda@8.10.133: - resolution: {integrity: sha512-sr852MAL/79rjDelXP6ZuJ6GwOvXIRrFAoC8a+w91mZ5XR71CuzSgo1d0+pG1qgfPhjFgaibu7SWaoC5BA7pyQ==} - - /@types/babel__core@7.20.5: - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - dependencies: - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 - '@types/babel__generator': 7.6.8 - '@types/babel__template': 7.4.1 - '@types/babel__traverse': 7.20.5 - - /@types/babel__generator@7.6.8: - resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} - dependencies: - '@babel/types': 7.23.6 - - /@types/babel__template@7.4.1: - resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} - dependencies: - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 - - /@types/babel__traverse@7.20.5: - resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} - dependencies: - '@babel/types': 7.23.6 - - /@types/body-parser@1.19.5: - resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} - dependencies: - '@types/connect': 3.4.38 - '@types/node': 18.17.1 - - /@types/cacache@17.0.2: - resolution: {integrity: sha512-IrqHzVX2VRMDQQKa7CtKRnuoCLdRJiLW6hWU+w7i7+AaQ0Ii5bKwJxd5uRK4zBCyrHd3tG6G8zOm2LplxbSfQg==} - dependencies: - '@types/node': 18.17.1 - dev: true - - /@types/chalk@2.2.0: - resolution: {integrity: sha512-1zzPV9FDe1I/WHhRkf9SNgqtRJWZqrBWgu7JGveuHmmyR9CnAPCie2N/x+iHrgnpYBIcCJWHBoMRv2TRWktsvw==} - deprecated: This is a stub types definition for chalk (https://github.com/chalk/chalk). chalk provides its own type definitions, so you don't need @types/chalk installed! - dependencies: - chalk: 4.1.2 - dev: false - - /@types/cheerio@0.22.30: - resolution: {integrity: sha512-t7ZVArWZlq3dFa9Yt33qFBQIK4CQd1Q3UJp0V+UhP6vgLWLM6Qug7vZuRSGXg45zXeB1Fm5X2vmBkEX58LV2Tw==} - dependencies: - '@types/node': 18.17.1 - dev: false - - /@types/compression@1.7.5: - resolution: {integrity: sha512-AAQvK5pxMpaT+nDvhHrsBhLSYG5yQdtkaJE1WYieSNY2mVFKAgmU4ks65rkZD5oqnGCFLyQpUr1CqI4DmUMyDg==} - dependencies: - '@types/express': 4.17.21 - dev: true - - /@types/connect@3.4.38: - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - dependencies: - '@types/node': 18.17.1 - - /@types/cookie-signature@1.1.2: - resolution: {integrity: sha512-2OhrZV2LVnUAXklUFwuYUTokalh/dUb8rqt70OW6ByMSxYpauPZ+kfNLknX3aJyjY5iu8i3cUyoLZP9Fn37tTg==} - dependencies: - '@types/node': 18.17.1 - dev: true - - /@types/cookie@0.4.1: - resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} - dev: true - - /@types/cookie@0.6.0: - resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} - dev: false - - /@types/cookiejar@2.1.5: - resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} - dev: true - - /@types/cross-spawn@6.0.2: - resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==} - dependencies: - '@types/node': 18.17.1 - - /@types/debug@4.1.8: - resolution: {integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==} - dependencies: - '@types/ms': 0.7.31 - - /@types/dedent@0.7.0: - resolution: {integrity: sha512-EGlKlgMhnLt/cM4DbUSafFdrkeJoC9Mvnj0PUCU7tFmTjMjNRT957kXCx0wYm3JuEq4o4ZsS5vG+NlkM2DMd2A==} - dev: false - - /@types/eslint@8.56.2: - resolution: {integrity: sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==} - dependencies: - '@types/estree': 1.0.6 - '@types/json-schema': 7.0.15 - dev: true - - /@types/estree-jsx@1.0.0: - resolution: {integrity: sha512-3qvGd0z8F2ENTGr/GG1yViqfiKmRfrXVx5sJyHGFu3z7m5g5utCQtGp/g29JnjflhtQJBv1WDQukHiT58xPcYQ==} - dependencies: - '@types/estree': 1.0.6 - dev: false - - /@types/estree@0.0.39: - resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} - dev: false - - /@types/estree@1.0.6: - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - - /@types/express-serve-static-core@4.17.43: - resolution: {integrity: sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==} - dependencies: - '@types/node': 18.17.1 - '@types/qs': 6.9.11 - '@types/range-parser': 1.2.7 - '@types/send': 0.17.4 - - /@types/express@4.17.21: - resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} - dependencies: - '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 4.17.43 - '@types/qs': 6.9.11 - '@types/serve-static': 1.15.5 - - /@types/fs-extra@8.1.2: - resolution: {integrity: sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==} - dependencies: - '@types/node': 18.17.1 - dev: false - - /@types/glob@7.2.0: - resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} - dependencies: - '@types/minimatch': 3.0.5 - '@types/node': 18.17.1 - - /@types/graceful-fs@4.1.6: - resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} - dependencies: - '@types/node': 18.17.1 - - /@types/gunzip-maybe@1.4.2: - resolution: {integrity: sha512-2uqXZg1jTCKE1Pjbab8qb74+f2+i9h/jz8rQ+jRR+zaNJF75zWwrpbX8/TjF4m56m3KFOg9umHdCJ074KwiVxg==} - dependencies: - '@types/node': 18.17.1 - dev: true - - /@types/hast@2.3.10: - resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} - dependencies: - '@types/unist': 2.0.6 - dev: false - - /@types/hast@3.0.3: - resolution: {integrity: sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==} - dependencies: - '@types/unist': 3.0.2 - dev: false - - /@types/http-errors@2.0.4: - resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} - - /@types/is-ci@3.0.0: - resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==} - dependencies: - ci-info: 3.3.2 - dev: false - - /@types/istanbul-lib-coverage@2.0.3: - resolution: {integrity: sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==} - - /@types/istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} - dependencies: - '@types/istanbul-lib-coverage': 2.0.3 - - /@types/istanbul-reports@3.0.1: - resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} - dependencies: - '@types/istanbul-lib-report': 3.0.0 - - /@types/jest@29.5.4: - resolution: {integrity: sha512-PhglGmhWeD46FYOVLt3X7TiWjzwuVGW9wG/4qocPevXMjCmrIc5b6db9WjeGE4QYVpUAWMDv3v0IiBwObY289A==} - dependencies: - expect: 29.6.4 - pretty-format: 29.7.0 - - /@types/js-levenshtein@1.1.3: - resolution: {integrity: sha512-jd+Q+sD20Qfu9e2aEXogiO3vpOC1PYJOUdyN9gvs4Qrvkg4wF43L5OhqrPeokdv8TL0/mXoYfpkcoGZMNN2pkQ==} - dev: true - - /@types/jsdom@20.0.1: - resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} - dependencies: - '@types/node': 18.17.1 - '@types/tough-cookie': 4.0.5 - parse5: 7.1.2 - dev: true - - /@types/jsesc@3.0.3: - resolution: {integrity: sha512-YZZ9ZOAiiSVC6KApWd/fTCDTdTOOMiRU4Lq3/VSmXNPse8IvCVOn5kYRRLu900Ub1lTPurVZFI5unEqLDJR7wg==} - dev: true - - /@types/json-schema@7.0.15: - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - /@types/json5@0.0.29: - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - dev: false - - /@types/jsonfile@6.1.0: - resolution: {integrity: sha512-zQPywzif9EycCkvECjYT9dbbttT0dkk657zcLb/803ZOXHsBA963jzEPF/Jnh1zOdBbgFJvUE8kcvZverAoK1w==} - dependencies: - '@types/node': 18.17.1 - dev: false - - /@types/lambda-tester@3.6.2: - resolution: {integrity: sha512-nQRUx0AuvTq5KOz1SaxMOOFJvnybo1oAzvSy/p9bVGthZVvg1Dar/051mhMuzdN1DWg++bs+eGq1MdCbm6wjSQ==} - dependencies: - '@types/aws-lambda': 8.10.133 - dev: true - - /@types/lodash.debounce@4.0.9: - resolution: {integrity: sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ==} - dependencies: - '@types/lodash': 4.14.182 - dev: true - - /@types/lodash@4.14.182: - resolution: {integrity: sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==} - - /@types/mdast@3.0.10: - resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==} - dependencies: - '@types/unist': 3.0.2 - dev: false - - /@types/mdast@4.0.3: - resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} - dependencies: - '@types/unist': 3.0.2 - dev: false - - /@types/mdx@2.0.5: - resolution: {integrity: sha512-76CqzuD6Q7LC+AtbPqrvD9AqsN0k8bsYo2bM2J8pmNldP1aIPAbzUQ7QbobyXL4eLr1wK5x8FZFe8eF/ubRuBg==} - dev: false - - /@types/methods@1.1.4: - resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==} - dev: true - - /@types/mime@1.3.5: - resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - - /@types/mime@2.0.3: - resolution: {integrity: sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==} - - /@types/minimatch@3.0.5: - resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} - - /@types/minimist@1.2.2: - resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} - dev: false - - /@types/morgan@1.9.9: - resolution: {integrity: sha512-iRYSDKVaC6FkGSpEVVIvrRGw0DfJMiQzIn3qr2G5B3C//AWkulhXgaBd7tS9/J79GWSYMTHGs7PfI5b3Y8m+RQ==} - dependencies: - '@types/node': 18.17.1 - dev: true - - /@types/ms@0.7.31: - resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} - - /@types/node-forge@1.3.11: - resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} - dependencies: - '@types/node': 18.17.1 - - /@types/node@12.20.55: - resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - dev: false - - /@types/node@14.18.33: - resolution: {integrity: sha512-qelS/Ra6sacc4loe/3MSjXNL1dNQ/GjxNHVzuChwMfmk7HuycRLVQN2qNY3XahK+fZc5E2szqQSKUyAF0E+2bg==} - dev: false - - /@types/node@18.17.1: - resolution: {integrity: sha512-xlR1jahfizdplZYRU59JlUx9uzF1ARa8jbhM11ccpCJya8kvos5jwdm2ZAgxSCwOl0fq21svP18EVwPBXMQudw==} - - /@types/node@20.11.17: - resolution: {integrity: sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==} - dependencies: - undici-types: 5.26.5 - dev: true - - /@types/normalize-package-data@2.4.1: - resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} - dev: false - - /@types/npmcli__package-json@4.0.4: - resolution: {integrity: sha512-6QjlFUSHBmZJWuC08bz1ZCx6tm4t+7+OJXAdvM6tL2pI7n6Bh5SIp/YxQvnOLFf8MzCXs2ijyFgrzaiu1UFBGA==} - dev: true - - /@types/picomatch@2.3.3: - resolution: {integrity: sha512-Yll76ZHikRFCyz/pffKGjrCwe/le2CDwOP5F210KQo27kpRE46U2rDnzikNlVn6/ezH3Mhn46bJMTfeVTtcYMg==} - dev: true - - /@types/prettier@2.7.3: - resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} - dev: true - - /@types/prop-types@15.7.4: - resolution: {integrity: sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==} - - /@types/qs@6.9.11: - resolution: {integrity: sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==} - - /@types/range-parser@1.2.7: - resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - - /@types/react-dom@18.2.7: - resolution: {integrity: sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==} - dependencies: - '@types/react': 18.2.20 - - /@types/react-test-renderer@18.0.0: - resolution: {integrity: sha512-C7/5FBJ3g3sqUahguGi03O79b8afNeSD6T8/GU50oQrJCU0bVCCGQHaGKUbg2Ce8VQEEqTw8/HiS6lXHHdgkdQ==} - dependencies: - '@types/react': 18.2.20 - dev: false - - /@types/react@18.2.20: - resolution: {integrity: sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw==} - dependencies: - '@types/prop-types': 15.7.4 - '@types/scheduler': 0.16.2 - csstype: 3.1.1 - - /@types/recursive-readdir@2.2.4: - resolution: {integrity: sha512-84REEGT3lcgopvpkmGApzmU5UEG0valme5rQS/KGiguTkJ70/Au8UYZTyrzoZnY9svuX9351+1uvrRPzWDD/uw==} - dependencies: - '@types/node': 18.17.1 - dev: true - - /@types/resolve@1.17.1: - resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} - dependencies: - '@types/node': 18.17.1 - dev: false - - /@types/retry@0.12.1: - resolution: {integrity: sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==} - dev: false - - /@types/scheduler@0.16.2: - resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} - - /@types/semver@6.2.3: - resolution: {integrity: sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==} - dev: false - - /@types/semver@7.3.13: - resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==} - dev: false - - /@types/send@0.17.4: - resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} - dependencies: - '@types/mime': 1.3.5 - '@types/node': 18.17.1 - - /@types/serialize-javascript@5.0.2: - resolution: {integrity: sha512-BRLlwZzRoZukGaBtcUxkLsZsQfWZpvog6MZk3PWQO9Q6pXmXFzjU5iGzZ+943evp6tkkbN98N1Z31KT0UG1yRw==} - dev: false - - /@types/serve-static@1.15.5: - resolution: {integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==} - dependencies: - '@types/http-errors': 2.0.4 - '@types/mime': 2.0.3 - '@types/node': 18.17.1 - - /@types/set-cookie-parser@2.4.7: - resolution: {integrity: sha512-+ge/loa0oTozxip6zmhRIk8Z/boU51wl9Q6QdLZcokIGMzY5lFXYy/x7Htj2HTC6/KZP1hUbZ1ekx8DYXICvWg==} - dependencies: - '@types/node': 18.17.1 - dev: true - - /@types/shelljs@0.8.15: - resolution: {integrity: sha512-vzmnCHl6hViPu9GNLQJ+DZFd6BQI2DBTUeOvYHqkWQLMfKAAQYMb/xAmZkTogZI/vqXHCWkqDRymDI5p0QTi5Q==} - dependencies: - '@types/glob': 7.2.0 - '@types/node': 18.17.1 - - /@types/sinonjs__fake-timers@8.1.1: - resolution: {integrity: sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==} - dev: false - - /@types/sizzle@2.3.3: - resolution: {integrity: sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==} - dev: false - - /@types/source-map-support@0.5.10: - resolution: {integrity: sha512-tgVP2H469x9zq34Z0m/fgPewGhg/MLClalNOiPIzQlXrSS2YrKu/xCdSCKnEDwkFha51VKEKB6A9wW26/ZNwzA==} - dependencies: - source-map: 0.6.1 - dev: true - - /@types/ssri@7.1.1: - resolution: {integrity: sha512-DPP/jkDaqGiyU75MyMURxLWyYLwKSjnAuGe9ZCsLp9QZOpXmDfuevk769F0BS86TmRuD5krnp06qw9nSoNO+0g==} - dependencies: - '@types/node': 18.17.1 - dev: false - - /@types/stack-utils@2.0.1: - resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} - - /@types/superagent@8.1.3: - resolution: {integrity: sha512-R/CfN6w2XsixLb1Ii8INfn+BT9sGPvw74OavfkW4SwY+jeUcAwLZv2+bXLJkndnimxjEBm0RPHgcjW9pLCa8cw==} - dependencies: - '@types/cookiejar': 2.1.5 - '@types/methods': 1.1.4 - '@types/node': 18.17.1 - dev: true - - /@types/supertest@2.0.16: - resolution: {integrity: sha512-6c2ogktZ06tr2ENoZivgm7YnprnhYE4ZoXGMY+oA7IuAf17M8FWvujXZGmxLv8y0PTyts4x5A+erSwVUFA8XSg==} - dependencies: - '@types/superagent': 8.1.3 - dev: true - - /@types/tar-fs@2.0.4: - resolution: {integrity: sha512-ipPec0CjTmVDWE+QKr9cTmIIoTl7dFG/yARCM5MqK8i6CNLIG1P8x4kwDsOQY1ChZOZjH0wO9nvfgBvWl4R3kA==} - dependencies: - '@types/node': 18.17.1 - '@types/tar-stream': 3.1.3 - dev: true - - /@types/tar-stream@3.1.3: - resolution: {integrity: sha512-Zbnx4wpkWBMBSu5CytMbrT5ZpMiF55qgM+EpHzR4yIDu7mv52cej8hTkOc6K+LzpkOAbxwn/m7j3iO+/l42YkQ==} - dependencies: - '@types/node': 18.17.1 - dev: true - - /@types/testing-library__jest-dom@5.14.2: - resolution: {integrity: sha512-vehbtyHUShPxIa9SioxDwCvgxukDMH//icJG90sXQBUm5lJOHLT5kNeU9tnivhnA/TkOFMzGIXN2cTc4hY8/kg==} - dependencies: - '@types/jest': 29.5.4 - - /@types/tough-cookie@4.0.5: - resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} - dev: true - - /@types/unist@2.0.6: - resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} - dev: false - - /@types/unist@3.0.2: - resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} - dev: false - - /@types/wait-on@5.3.2: - resolution: {integrity: sha512-7NBSJs/YvbHlaYCJ7wIUF6t7ct3OMt525NmZ+US73pPlkmpxd9ADwfNxrRAmg8nWlcTMqR0PkhW7aYk3FLlvrQ==} - dependencies: - '@types/node': 18.17.1 - dev: false - - /@types/ws@7.4.7: - resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} - dependencies: - '@types/node': 18.17.1 - dev: true - - /@types/yargs-parser@20.2.1: - resolution: {integrity: sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==} - - /@types/yargs@17.0.24: - resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==} - dependencies: - '@types/yargs-parser': 20.2.1 - - /@types/yauzl@2.10.3: - resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - requiresBuild: true - dependencies: - '@types/node': 18.17.1 - dev: false - optional: true - - /@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.56.0)(typescript@5.1.6): - resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.1.6) - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.56.0)(typescript@5.1.6) - '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@5.1.6) - debug: 4.4.0(supports-color@8.1.1) - eslint: 8.56.0 - graphemer: 1.4.0 - ignore: 5.3.1 - natural-compare-lite: 1.4.0 - semver: 7.5.4 - tsutils: 3.21.0(typescript@5.1.6) - typescript: 5.1.6 - transitivePeerDependencies: - - supports-color - dev: false - - /@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.1.6): - resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.6) - debug: 4.4.0(supports-color@8.1.1) - eslint: 8.56.0 - typescript: 5.1.6 - transitivePeerDependencies: - - supports-color - dev: false - - /@typescript-eslint/scope-manager@5.62.0: - resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 - dev: false - - /@typescript-eslint/type-utils@5.62.0(eslint@8.56.0)(typescript@5.1.6): - resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.6) - '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@5.1.6) - debug: 4.4.0(supports-color@8.1.1) - eslint: 8.56.0 - tsutils: 3.21.0(typescript@5.1.6) - typescript: 5.1.6 - transitivePeerDependencies: - - supports-color - dev: false - - /@typescript-eslint/types@5.62.0: - resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: false - - /@typescript-eslint/typescript-estree@5.62.0(typescript@5.1.6): - resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.4.0(supports-color@8.1.1) - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.5.4 - tsutils: 3.21.0(typescript@5.1.6) - typescript: 5.1.6 - transitivePeerDependencies: - - supports-color - dev: false - - /@typescript-eslint/utils@5.62.0(eslint@8.56.0)(typescript@5.1.6): - resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) - '@types/json-schema': 7.0.15 - '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.6) - eslint: 8.56.0 - eslint-scope: 5.1.1 - semver: 7.5.4 - transitivePeerDependencies: - - supports-color - - typescript - dev: false - - /@typescript-eslint/visitor-keys@5.62.0: - resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.62.0 - eslint-visitor-keys: 3.4.3 - dev: false - - /@ungap/structured-clone@1.2.0: - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - - /@vanilla-extract/babel-plugin-debug-ids@1.0.4: - resolution: {integrity: sha512-mevYcVMwsT6960xnXRw/Rr2K7SOEwzwVBApg/2SJ3eg2KGsHfj1rN0oQ12WdoTT3RzThq+0551bVQKPvQnjeaA==} - dependencies: - '@babel/core': 7.23.7 - transitivePeerDependencies: - - supports-color - - /@vanilla-extract/css@1.14.1: - resolution: {integrity: sha512-V4JUuHNjZgl64NGfkDJePqizkNgiSpphODtZEs4cCPuxLAzwOUJYATGpejwimJr1n529kq4DEKWexW22LMBokw==} - dependencies: - '@emotion/hash': 0.9.1 - '@vanilla-extract/private': 1.0.3 - chalk: 4.1.2 - css-what: 6.1.0 - cssesc: 3.0.0 - csstype: 3.1.1 - deep-object-diff: 1.1.9 - deepmerge: 4.2.2 - media-query-parser: 2.0.2 - modern-ahocorasick: 1.0.1 - outdent: 0.8.0 - - /@vanilla-extract/integration@6.5.0(@types/node@18.17.1): - resolution: {integrity: sha512-E2YcfO8vA+vs+ua+gpvy1HRqvgWbI+MTlUpxA8FvatOvybuNcWAY0CKwQ/Gpj7rswYKtC6C7+xw33emM6/ImdQ==} - dependencies: - '@babel/core': 7.23.7 - '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.23.7) - '@vanilla-extract/babel-plugin-debug-ids': 1.0.4 - '@vanilla-extract/css': 1.14.1 - esbuild: 0.17.6 - eval: 0.1.8 - find-up: 5.0.0 - javascript-stringify: 2.1.0 - lodash: 4.17.21 - mlly: 1.5.0 - outdent: 0.8.0 - vite: 5.1.8(@types/node@18.17.1) - vite-node: 1.6.1(@types/node@18.17.1) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - - /@vanilla-extract/private@1.0.3: - resolution: {integrity: sha512-17kVyLq3ePTKOkveHxXuIJZtGYs+cSoev7BlP+Lf4916qfDhk/HBjvlYDe8egrea7LNPHKwSZJK/bzZC+Q6AwQ==} - - /@vanilla-extract/vite-plugin@3.9.5(vite@5.1.8): - resolution: {integrity: sha512-CWI/CtrVW6i3HKccI6T7uGQkTJ8bd8Xl2UMBg3Pkr7dwWMmavXTeucV0I9KSbmXaYXSbEj+Q8c9y0xAZwtmTig==} - peerDependencies: - vite: ^2.2.3 || ^3.0.0 || ^4.0.3 || ^5.0.0 - dependencies: - '@vanilla-extract/integration': 6.5.0(@types/node@18.17.1) - outdent: 0.8.0 - postcss: 8.4.49 - postcss-load-config: 4.0.2(postcss@8.4.49) - vite: 5.1.8(@types/node@18.17.1) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - - ts-node - - /@vanilla-extract/vite-plugin@3.9.5(vite@6.0.6): - resolution: {integrity: sha512-CWI/CtrVW6i3HKccI6T7uGQkTJ8bd8Xl2UMBg3Pkr7dwWMmavXTeucV0I9KSbmXaYXSbEj+Q8c9y0xAZwtmTig==} - peerDependencies: - vite: ^2.2.3 || ^3.0.0 || ^4.0.3 || ^5.0.0 - dependencies: - '@vanilla-extract/integration': 6.5.0(@types/node@18.17.1) - outdent: 0.8.0 - postcss: 8.4.49 - postcss-load-config: 4.0.2(postcss@8.4.49) - vite: 6.0.6(@types/node@18.17.1) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - - ts-node - dev: false - - /@web3-storage/multipart-parser@1.0.0: - resolution: {integrity: sha512-BEO6al7BYqcnfX15W2cnGR+Q566ACXAT9UQykORCWW80lmkpWsnEob6zJS1ZVBKsSJC8+7vJkHwlp+lXG1UCdw==} - dev: false - - /@xmldom/xmldom@0.8.10: - resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} - engines: {node: '>=10.0.0'} - dev: true - - /@zxing/text-encoding@0.9.0: - resolution: {integrity: sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==} - requiresBuild: true - optional: true - - /abab@2.0.6: - resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} - deprecated: Use your platform's native atob() and btoa() methods instead - dev: true - - /abort-controller@3.0.0: - resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} - engines: {node: '>=6.5'} - dependencies: - event-target-shim: 5.0.1 - dev: false - - /accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} - dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 - - /acorn-jsx@5.3.2(acorn@8.11.3): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 8.11.3 - - /acorn-walk@8.3.2: - resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} - engines: {node: '>=0.4.0'} - - /acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} - engines: {node: '>=0.4.0'} - hasBin: true - - /agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - dependencies: - debug: 4.4.0(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - dev: true - - /agent-base@7.1.0: - resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} - engines: {node: '>= 14'} - dependencies: - debug: 4.4.0(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - dev: false - - /aggregate-error@3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} - dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 - dev: false - - /ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - /ansi-bgblack@0.1.1: - resolution: {integrity: sha512-tp8M/NCmSr6/skdteeo9UgJ2G1rG88X3ZVNZWXUxFw4Wh0PAGaAAWQS61sfBt/1QNcwMTY3EBKOMPujwioJLaw==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-bgblue@0.1.1: - resolution: {integrity: sha512-R8JmX2Xv3+ichUQE99oL+LvjsyK+CDWo/BtVb4QUz3hOfmf2bdEmiDot3fQcpn2WAHW3toSRdjSLm6bgtWRDlA==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-bgcyan@0.1.1: - resolution: {integrity: sha512-6SByK9q2H978bmqzuzA5NPT1lRDXl3ODLz/DjC4URO5f/HqK7dnRKfoO/xQLx/makOz7zWIbRf6+Uf7bmaPSkQ==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-bggreen@0.1.1: - resolution: {integrity: sha512-8TRtOKmIPOuxjpklrkhUbqD2NnVb4WZQuIjXrT+TGKFKzl7NrL7wuNvEap3leMt2kQaCngIN1ZzazSbJNzF+Aw==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-bgmagenta@0.1.1: - resolution: {integrity: sha512-UZYhobiGAlV4NiwOlKAKbkCyxOl1PPZNvdIdl/Ce5by45vwiyNdBetwHk/AjIpo1Ji9z+eE29PUBAjjfVmz5SA==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-bgred@0.1.1: - resolution: {integrity: sha512-BpPHMnYmRBhcjY5knRWKjQmPDPvYU7wrgBSW34xj7JCH9+a/SEIV7+oSYVOgMFopRIadOz9Qm4zIy+mEBvUOPA==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-bgwhite@0.1.1: - resolution: {integrity: sha512-KIF19t+HOYOorUnHTOhZpeZ3bJsjzStBG2hSGM0WZ8YQQe4c7lj9CtwnucscJDPrNwfdz6GBF+pFkVfvHBq6uw==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-bgyellow@0.1.1: - resolution: {integrity: sha512-WyRoOFSIvOeM7e7YdlSjfAV82Z6K1+VUVbygIQ7C/VGzWYuO/d30F0PG7oXeo4uSvSywR0ozixDQvtXJEorq4Q==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-black@0.1.1: - resolution: {integrity: sha512-hl7re02lWus7lFOUG6zexhoF5gssAfG5whyr/fOWK9hxNjUFLTjhbU/b4UHWOh2dbJu9/STSUv+80uWYzYkbTQ==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-blue@0.1.1: - resolution: {integrity: sha512-8Um59dYNDdQyoczlf49RgWLzYgC2H/28W3JAIyOAU/+WkMcfZmaznm+0i1ikrE0jME6Ypk9CJ9CY2+vxbPs7Fg==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-bold@0.1.1: - resolution: {integrity: sha512-wWKwcViX1E28U6FohtWOP4sHFyArELHJ2p7+3BzbibqJiuISeskq6t7JnrLisUngMF5zMhgmXVw8Equjzz9OlA==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-colors@0.2.0: - resolution: {integrity: sha512-ScRNUT0TovnYw6+Xo3iKh6G+VXDw2Ds7ZRnMIuKBgHY02DgvT2T2K22/tc/916Fi0W/5Z1RzDaHQwnp75hqdbA==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-bgblack: 0.1.1 - ansi-bgblue: 0.1.1 - ansi-bgcyan: 0.1.1 - ansi-bggreen: 0.1.1 - ansi-bgmagenta: 0.1.1 - ansi-bgred: 0.1.1 - ansi-bgwhite: 0.1.1 - ansi-bgyellow: 0.1.1 - ansi-black: 0.1.1 - ansi-blue: 0.1.1 - ansi-bold: 0.1.1 - ansi-cyan: 0.1.1 - ansi-dim: 0.1.1 - ansi-gray: 0.1.1 - ansi-green: 0.1.1 - ansi-grey: 0.1.1 - ansi-hidden: 0.1.1 - ansi-inverse: 0.1.1 - ansi-italic: 0.1.1 - ansi-magenta: 0.1.1 - ansi-red: 0.1.1 - ansi-reset: 0.1.1 - ansi-strikethrough: 0.1.1 - ansi-underline: 0.1.1 - ansi-white: 0.1.1 - ansi-yellow: 0.1.1 - lazy-cache: 2.0.2 - dev: false - - /ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - dev: false - - /ansi-cyan@0.1.1: - resolution: {integrity: sha512-eCjan3AVo/SxZ0/MyIYRtkpxIu/H3xZN7URr1vXVrISxeyz8fUFz0FJziamK4sS8I+t35y4rHg1b2PklyBe/7A==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-dim@0.1.1: - resolution: {integrity: sha512-zAfb1fokXsq4BoZBkL0eK+6MfFctbzX3R4UMcoWrL1n2WHewFKentTvOZv2P11u6P4NtW/V47hVjaN7fJiefOg==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.21.3 - - /ansi-escapes@5.0.0: - resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} - engines: {node: '>=12'} - dependencies: - type-fest: 1.4.0 - dev: false - - /ansi-escapes@6.2.0: - resolution: {integrity: sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==} - engines: {node: '>=14.16'} - dependencies: - type-fest: 3.13.1 - dev: false - - /ansi-gray@0.1.1: - resolution: {integrity: sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-green@0.1.1: - resolution: {integrity: sha512-WJ70OI4jCaMy52vGa/ypFSKFb/TrYNPaQ2xco5nUwE0C5H8piume/uAZNNdXXiMQ6DbRmiE7l8oNBHu05ZKkrw==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-grey@0.1.1: - resolution: {integrity: sha512-+J1nM4lC+whSvf3T4jsp1KR+C63lypb+VkkwtLQMc1Dlt+nOvdZpFT0wwFTYoSlSwCcLUAaOpHF6kPkYpSa24A==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-hidden@0.1.1: - resolution: {integrity: sha512-8gB1bo9ym9qZ/Obvrse1flRsfp2RE+40B23DhQcKxY+GSeaOJblLnzBOxzvmLTWbi5jNON3as7wd9rC0fNK73Q==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-inverse@0.1.1: - resolution: {integrity: sha512-Kq8Z0dBRhQhDMN/Rso1Nu9niwiTsRkJncfJZXiyj7ApbfJrGrrubHXqXI37feJZkYcIx6SlTBdNCeK0OQ6X6ag==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-italic@0.1.1: - resolution: {integrity: sha512-jreCxifSAqbaBvcibeQxcwhQDbEj7gF69XnpA6x83qbECEBaRBD1epqskrmov1z4B+zzQuEdwbWxgzvhKa+PkA==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-magenta@0.1.1: - resolution: {integrity: sha512-A1Giu+HRwyWuiXKyXPw2AhG1yWZjNHWO+5mpt+P+VWYkmGRpLPry0O5gmlJQEvpjNpl4RjFV7DJQ4iozWOmkbQ==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-red@0.1.1: - resolution: {integrity: sha512-ewaIr5y+9CUTGFwZfpECUbFlGcC0GCw1oqR9RI6h1gQCd9Aj2GxSckCnPsVJnmfMZbwFYE+leZGASgkWl06Jow==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-regex@3.0.1: - resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} - engines: {node: '>=4'} - dev: false - - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - /ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - - /ansi-reset@0.1.1: - resolution: {integrity: sha512-n+D0qD3B+h/lP0dSwXX1SZMoXufdUVotLMwUuvXa50LtBAh3f+WV8b5nFMfLL/hgoPBUt+rG/pqqzF8krlZKcw==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-strikethrough@0.1.1: - resolution: {integrity: sha512-gWkLPDvHH2pC9YEKqp8dIl0mg3sRglMPvioqGDIOXiwxjxUwIJ1gF86E2o4R5yLNh8IAkwHbaMtASkJfkQ2hIA==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - dependencies: - color-convert: 1.9.3 - - /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - - /ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - - /ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - /ansi-underline@0.1.1: - resolution: {integrity: sha512-D+Bzwio/0/a0Fu5vJzrIT6bFk43TW46vXfSvzysOTEHcXOAUJTVMHWDbELIzGU4AVxVw2rCTb7YyWS4my2cSKQ==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-white@0.1.1: - resolution: {integrity: sha512-DJHaF2SRzBb9wZBgqIJNjjTa7JUJTO98sHeTS1sDopyKKRopL1KpaJ20R6W2f/ZGras8bYyIZDtNwYOVXNgNFg==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /ansi-wrap@0.1.0: - resolution: {integrity: sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==} - engines: {node: '>=0.10.0'} - dev: false - - /ansi-yellow@0.1.1: - resolution: {integrity: sha512-6E3D4BQLXHLl3c/NwirWVZ+BCkMq2qsYxdeAGGOijKrx09FaqU+HktFL6QwAwNvgJiMLnv6AQ2C1gFZx0h1CBg==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: false - - /any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - - /anymatch@3.1.2: - resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} - engines: {node: '>= 8'} - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - /app-root-path@3.1.0: - resolution: {integrity: sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==} - engines: {node: '>= 6.0.0'} - dev: true - - /arch@2.2.0: - resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} - dev: false - - /arg@5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - - /argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - dependencies: - sprintf-js: 1.0.3 - - /argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - /aria-query@5.1.3: - resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} - dependencies: - deep-equal: 2.2.0 - dev: false - - /aria-query@5.3.0: - resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} - dependencies: - dequal: 2.0.3 - - /arr-flatten@1.1.0: - resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} - engines: {node: '>=0.10.0'} - dev: false - - /arr-swap@1.0.1: - resolution: {integrity: sha512-SxBKd/By8+AaREcv/ZhFqmapfpqK4kyaQkUHwmJjlczI5ZtuuT5gofKHlCrSJ4oR7zXezFhv+7zsnLEdg9uGgQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-number: 3.0.0 - dev: false - - /array-buffer-byte-length@1.0.1: - resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - is-array-buffer: 3.0.4 - dev: false - - /array-flatten@1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - - /array-includes@3.1.7: - resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - get-intrinsic: 1.2.4 - is-string: 1.0.7 - dev: false - - /array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - dev: false - - /array.prototype.filter@1.0.3: - resolution: {integrity: sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - es-array-method-boxes-properly: 1.0.0 - is-string: 1.0.7 - dev: false - - /array.prototype.findlastindex@1.2.4: - resolution: {integrity: sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - es-errors: 1.3.0 - es-shim-unscopables: 1.0.2 - dev: false - - /array.prototype.flat@1.3.2: - resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - es-shim-unscopables: 1.0.2 - dev: false - - /array.prototype.flatmap@1.3.2: - resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - es-shim-unscopables: 1.0.2 - dev: false - - /array.prototype.tosorted@1.1.3: - resolution: {integrity: sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - es-errors: 1.3.0 - es-shim-unscopables: 1.0.2 - dev: false - - /arraybuffer.prototype.slice@1.0.3: - resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} - engines: {node: '>= 0.4'} - dependencies: - array-buffer-byte-length: 1.0.1 - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - es-errors: 1.3.0 - get-intrinsic: 1.2.4 - is-array-buffer: 3.0.4 - is-shared-array-buffer: 1.0.2 - dev: false - - /arrify@1.0.1: - resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} - engines: {node: '>=0.10.0'} - dev: false - - /as-table@1.0.55: - resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} - dependencies: - printable-characters: 1.0.42 - - /asap@2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - dev: true - - /asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - dependencies: - safer-buffer: 2.1.2 - dev: false - - /assert-plus@1.0.0: - resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} - engines: {node: '>=0.8'} - dev: false - - /ast-types-flow@0.0.8: - resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - dev: false - - /ast-types@0.13.4: - resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} - engines: {node: '>=4'} - dependencies: - tslib: 2.6.2 - dev: false - - /astral-regex@2.0.0: - resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} - engines: {node: '>=8'} - dev: false - - /astring@1.8.3: - resolution: {integrity: sha512-sRpyiNrx2dEYIMmUXprS8nlpRg2Drs8m9ElX9vVEXaCB4XEAJhKfs7IcX0IwShjuOAjLR6wzIrgoptz1n19i1A==} - hasBin: true - dev: false - - /async@3.2.3: - resolution: {integrity: sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==} - - /asynciterator.prototype@1.0.0: - resolution: {integrity: sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==} - dependencies: - has-symbols: 1.0.3 - dev: false - - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - /at-least-node@1.0.0: - resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} - engines: {node: '>= 4.0.0'} - dev: false - - /available-typed-arrays@1.0.6: - resolution: {integrity: sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==} - engines: {node: '>= 0.4'} - - /aws-sign2@0.7.0: - resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - dev: false - - /aws4@1.11.0: - resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==} - dev: false - - /axe-core@4.7.0: - resolution: {integrity: sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==} - engines: {node: '>=4'} - dev: false - - /axios@0.27.2: - resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} - dependencies: - follow-redirects: 1.15.6 - form-data: 4.0.0 - transitivePeerDependencies: - - debug - dev: false - - /axobject-query@3.2.1: - resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} - dependencies: - dequal: 2.0.3 - dev: false - - /babel-jest@29.6.4(@babel/core@7.23.7): - resolution: {integrity: sha512-meLj23UlSLddj6PC+YTOFRgDAtjnZom8w/ACsrx0gtPtv5cJZk0A5Unk5bV4wixD7XaPCN1fQvpww8czkZURmw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.8.0 - dependencies: - '@babel/core': 7.23.7 - '@jest/transform': 29.6.4 - '@types/babel__core': 7.20.5 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.23.7) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - - /babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} - dependencies: - '@babel/helper-plugin-utils': 7.22.5 - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.1.0 - test-exclude: 6.0.0 - transitivePeerDependencies: - - supports-color - - /babel-plugin-jest-hoist@29.6.3: - resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/template': 7.22.15 - '@babel/types': 7.23.6 - '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.20.5 - - /babel-plugin-polyfill-corejs2@0.3.3(@babel/core@7.23.7): - resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/compat-data': 7.23.5 - '@babel/core': 7.23.7 - '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.23.7) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: false - - /babel-plugin-polyfill-corejs3@0.6.0(@babel/core@7.23.7): - resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.23.7) - core-js-compat: 3.30.2 - transitivePeerDependencies: - - supports-color - dev: false - - /babel-plugin-polyfill-regenerator@0.4.1(@babel/core@7.23.7): - resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.7 - '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.23.7) - transitivePeerDependencies: - - supports-color - dev: false - - /babel-plugin-transform-remove-console@6.9.4: - resolution: {integrity: sha512-88blrUrMX3SPiGkT1GnvVY8E/7A+k6oj3MNvUtTIxJflFzXTw1bHkuJ/y039ouhFMp2prRn5cQGzokViYi1dsg==} - dev: false - - /babel-preset-current-node-syntax@1.0.1(@babel/core@7.23.7): - resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.23.7 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.7) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.23.7) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.7) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.7) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.7) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.7) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.7) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.7) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.7) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.7) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.7) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.7) - - /babel-preset-jest@29.6.3(@babel/core@7.23.7): - resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.23.7 - babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.7) - - /bail@2.0.1: - resolution: {integrity: sha512-d5FoTAr2S5DSUPKl85WNm2yUwsINN8eidIdIwsOge2t33DaOfOdSmmsI11jMN3GmALCXaw+Y6HMVHDzePshFAA==} - dev: false - - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - /base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - /basic-auth@2.0.1: - resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} - engines: {node: '>= 0.8'} - dependencies: - safe-buffer: 5.1.2 - dev: false - - /basic-ftp@5.0.4: - resolution: {integrity: sha512-8PzkB0arJFV4jJWSGOYR+OEic6aeKMu/osRhBULN6RY0ykby6LKhbmuQ5ublvaas5BOwboah5D87nrHyuh8PPA==} - engines: {node: '>=10.0.0'} - dev: false - - /bcrypt-pbkdf@1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} - dependencies: - tweetnacl: 0.14.5 - dev: false - - /before-after-hook@2.2.2: - resolution: {integrity: sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==} - dev: false - - /better-path-resolve@1.0.0: - resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} - engines: {node: '>=4'} - dependencies: - is-windows: 1.0.2 - dev: false - - /binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} - engines: {node: '>=8'} - - /bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - - /blake3-wasm@2.1.5: - resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} - - /blob-util@2.0.2: - resolution: {integrity: sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==} - dev: false - - /bluebird@3.7.2: - resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} - dev: false - - /body-parser@1.20.3: - resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.13.0 - raw-body: 2.5.2 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - - /boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - dev: false - - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - /brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - dependencies: - balanced-match: 1.0.2 - - /braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - dependencies: - fill-range: 7.0.1 - - /breakword@1.0.5: - resolution: {integrity: sha512-ex5W9DoOQ/LUEU3PMdLs9ua/CYZl1678NUkKOdUSi8Aw5F1idieaiRURCBFJCwVcrD1J8Iy3vfWSloaMwO2qFg==} - dependencies: - wcwidth: 1.0.1 - dev: false - - /browserify-zlib@0.1.4: - resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==} - dependencies: - pako: 0.2.9 - dev: false - - /browserslist@4.22.2: - resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001576 - electron-to-chromium: 1.4.626 - node-releases: 2.0.14 - update-browserslist-db: 1.0.13(browserslist@4.22.2) - - /bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - dependencies: - node-int64: 0.4.0 - - /buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - dev: false - - /buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - /buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - dependencies: - base64-js: 1.5.1 - ieee754: 1.1.13 - - /builtin-modules@3.3.0: - resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} - engines: {node: '>=6'} - dev: false - - /builtins@5.0.1: - resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} - dependencies: - semver: 7.5.4 - dev: false - - /bytes@3.0.0: - resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} - engines: {node: '>= 0.8'} - dev: false - - /bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - - /cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - - /cacache@17.1.4: - resolution: {integrity: sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - '@npmcli/fs': 3.1.0 - fs-minipass: 3.0.3 - glob: 10.3.10 - lru-cache: 7.18.3 - minipass: 7.0.4 - minipass-collect: 1.0.2 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - p-map: 4.0.0 - ssri: 10.0.5 - tar: 6.2.0 - unique-filename: 3.0.0 - dev: false - - /cachedir@2.3.0: - resolution: {integrity: sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==} - engines: {node: '>=6'} - dev: false - - /call-bind@1.0.7: - resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} - engines: {node: '>= 0.4'} - dependencies: - es-define-property: 1.0.0 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.2.4 - set-function-length: 1.2.1 - - /callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - /camelcase-css@2.0.1: - resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} - engines: {node: '>= 6'} - - /camelcase-keys@6.2.2: - resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} - engines: {node: '>=8'} - dependencies: - camelcase: 5.3.1 - map-obj: 4.3.0 - quick-lru: 4.0.1 - dev: false - - /camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - - /camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - - /caniuse-lite@1.0.30001576: - resolution: {integrity: sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==} - - /capnp-ts@0.7.0: - resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} - dependencies: - debug: 4.4.0(supports-color@8.1.1) - tslib: 2.6.2 - transitivePeerDependencies: - - supports-color - - /caseless@0.12.0: - resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - dev: false - - /ccount@2.0.1: - resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - dev: false - - /chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - - /chalk@3.0.0: - resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} - engines: {node: '>=8'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - /chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - /chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: false - - /char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} - - /char-regex@2.0.1: - resolution: {integrity: sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==} - engines: {node: '>=12.20'} - dev: false - - /character-entities-html4@2.0.0: - resolution: {integrity: sha512-dwT2xh5ZhUAjyP96k57ilMKoTQyASaw9IAMR9U5c1lCu2RUni6O6jxfpUEdO2RcPT6TJFvr8pqsbami4Jk+2oA==} - dev: false - - /character-entities-legacy@1.1.4: - resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} - dev: false - - /character-entities-legacy@2.0.0: - resolution: {integrity: sha512-YwaEtEvWLpFa6Wh3uVLrvirA/ahr9fki/NUd/Bd4OR6EdJ8D22hovYQEOUCBfQfcqnC4IAMGMsHXY1eXgL4ZZA==} - dev: false - - /character-entities-legacy@3.0.0: - resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} - dev: false - - /character-entities@1.2.4: - resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} - dev: false - - /character-entities@2.0.0: - resolution: {integrity: sha512-oHqMj3eAuJ77/P5PaIRcqk+C3hdfNwyCD2DAUcD5gyXkegAuF2USC40CEqPscDk4I8FRGMTojGJQkXDsN5QlJA==} - dev: false - - /character-reference-invalid@1.1.4: - resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} - dev: false - - /character-reference-invalid@2.0.0: - resolution: {integrity: sha512-pE3Z15lLRxDzWJy7bBHBopRwfI20sbrMVLQTC7xsPglCHf4Wv1e167OgYAFP78co2XlhojDyAqA+IAJse27//g==} - dev: false - - /chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - - /check-more-types@2.24.0: - resolution: {integrity: sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==} - engines: {node: '>= 0.8.0'} - dev: false - - /cheerio-select@2.1.0: - resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} - dependencies: - boolbase: 1.0.0 - css-select: 5.1.0 - css-what: 6.1.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.1.0 - dev: false - - /cheerio@1.0.0-rc.12: - resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} - engines: {node: '>= 6'} - dependencies: - cheerio-select: 2.1.0 - dom-serializer: 2.0.0 - domhandler: 5.0.3 - domutils: 3.1.0 - htmlparser2: 8.0.2 - parse5: 7.1.2 - parse5-htmlparser2-tree-adapter: 7.0.0 - dev: false - - /choices-separator@2.0.0: - resolution: {integrity: sha512-BCKlzRcP2V6X+85TSKn09oGZkO2zK2zytGyZeHvM2s+kv/ydAzJtsc+rZqYRWNlojIBfkOnPxgKXrBefTFZbTQ==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-dim: 0.1.1 - debug: 2.6.9 - strip-color: 0.1.0 - transitivePeerDependencies: - - supports-color - dev: false - - /chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - dependencies: - anymatch: 3.1.2 - braces: 3.0.2 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - /chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - dev: false - - /chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} - dev: false - - /ci-info@3.3.2: - resolution: {integrity: sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==} - - /cjs-module-lexer@1.2.2: - resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} - - /clean-stack@2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} - dev: false - - /cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - dependencies: - restore-cursor: 3.1.0 - - /cli-cursor@4.0.0: - resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - restore-cursor: 4.0.0 - dev: false - - /cli-spinners@2.9.2: - resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} - engines: {node: '>=6'} - - /cli-table3@0.6.2: - resolution: {integrity: sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==} - engines: {node: 10.* || >= 12.*} - dependencies: - string-width: 4.2.3 - optionalDependencies: - '@colors/colors': 1.5.0 - dev: false - - /cli-truncate@2.1.0: - resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} - engines: {node: '>=8'} - dependencies: - slice-ansi: 3.0.0 - string-width: 4.2.3 - dev: false - - /cli-width@3.0.0: - resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} - engines: {node: '>= 10'} - dev: true - - /cliui@6.0.0: - resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 6.2.0 - dev: false - - /cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - /clone-deep@1.0.0: - resolution: {integrity: sha512-hmJRX8x1QOJVV+GUjOBzi6iauhPqc9hIF6xitWRBbiPZOBb6vGo/mDRIK9P74RTKSQK7AE8B0DDWY/vpRrPmQw==} - engines: {node: '>=0.10.0'} - dependencies: - for-own: 1.0.0 - is-plain-object: 2.0.4 - kind-of: 5.1.0 - shallow-clone: 1.0.0 - dev: false - - /clone-deep@4.0.1: - resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} - engines: {node: '>=6'} - dependencies: - is-plain-object: 2.0.4 - kind-of: 6.0.3 - shallow-clone: 3.0.1 - - /clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - - /co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - - /collapse-white-space@2.1.0: - resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} - dev: false - - /collect-v8-coverage@1.0.1: - resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} - - /collection-visit@1.0.0: - resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} - engines: {node: '>=0.10.0'} - dependencies: - map-visit: 1.0.0 - object-visit: 1.0.1 - dev: false - - /color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - dependencies: - color-name: 1.1.3 - - /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - - /color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - /colorette@1.4.0: - resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} - dev: false - - /colorette@2.0.16: - resolution: {integrity: sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==} - dev: false - - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - - /comma-separated-tokens@2.0.2: - resolution: {integrity: sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==} - dev: false - - /commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - - /commander@5.1.0: - resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} - engines: {node: '>= 6'} - dev: false - - /common-tags@1.8.2: - resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} - engines: {node: '>=4.0.0'} - dev: false - - /commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - dev: false - - /component-emitter@1.3.0: - resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} - - /compressible@2.0.18: - resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: false - - /compression@1.7.4: - resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} - engines: {node: '>= 0.8.0'} - dependencies: - accepts: 1.3.8 - bytes: 3.0.0 - compressible: 2.0.18 - debug: 2.6.9 - on-headers: 1.0.2 - safe-buffer: 5.1.2 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - dev: false - - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - /concurrently@7.0.0: - resolution: {integrity: sha512-WKM7PUsI8wyXpF80H+zjHP32fsgsHNQfPLw/e70Z5dYkV7hF+rf8q3D+ScWJIEr57CpkO3OWBko6hwhQLPR8Pw==} - engines: {node: ^12.20.0 || ^14.13.0 || >=16.0.0} - hasBin: true - dependencies: - chalk: 4.1.2 - date-fns: 2.28.0 - lodash: 4.17.21 - rxjs: 6.6.7 - spawn-command: 0.0.2-1 - supports-color: 8.1.1 - tree-kill: 1.2.2 - yargs: 16.2.0 - dev: false - - /content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} - dependencies: - safe-buffer: 5.2.1 - - /content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - - /convert-source-map@1.8.0: - resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==} - dependencies: - safe-buffer: 5.1.2 - - /convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - - /cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - - /cookie-signature@1.2.1: - resolution: {integrity: sha512-78KWk9T26NhzXtuL26cIJ8/qNHANyJ/ZYrmEXFzUmhZdjpBv+DlWlOANRTGBt48YcyslsLrj0bMLFTmXvLRCOw==} - engines: {node: '>=6.6.0'} - dev: false - - /cookie@0.4.2: - resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} - engines: {node: '>= 0.6'} - dev: true - - /cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} - - /cookie@0.7.1: - resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} - engines: {node: '>= 0.6'} - - /cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} - dev: false - - /cookiejar@2.1.4: - resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} - dev: true - - /copy-descriptor@0.1.1: - resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} - engines: {node: '>=0.10.0'} - dev: false - - /core-js-compat@3.30.2: - resolution: {integrity: sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA==} - dependencies: - browserslist: 4.22.2 - dev: false - - /core-util-is@1.0.2: - resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - dev: false - - /cross-spawn@5.1.0: - resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} - dependencies: - lru-cache: 4.1.5 - shebang-command: 1.2.0 - which: 1.3.1 - dev: false - - /cross-spawn@6.0.5: - resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} - engines: {node: '>=4.8'} - dependencies: - nice-try: 1.0.5 - path-key: 2.0.1 - semver: 5.7.1 - shebang-command: 1.2.0 - which: 1.3.1 - dev: false - - /cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - /csrf@3.1.0: - resolution: {integrity: sha512-uTqEnCvWRk042asU6JtapDTcJeeailFy4ydOQS28bj1hcLnYRiqi8SsD2jS412AY1I/4qdOwWZun774iqywf9w==} - engines: {node: '>= 0.8'} - dependencies: - rndm: 1.2.0 - tsscmp: 1.0.6 - uid-safe: 2.1.5 - dev: false - - /css-select@5.1.0: - resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} - dependencies: - boolbase: 1.0.0 - css-what: 6.1.0 - domhandler: 5.0.3 - domutils: 3.1.0 - nth-check: 2.1.1 - dev: false - - /css-what@6.1.0: - resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} - engines: {node: '>= 6'} - - /css.escape@1.5.1: - resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} - - /cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - - /cssstyle@3.0.0: - resolution: {integrity: sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==} - engines: {node: '>=14'} - dependencies: - rrweb-cssom: 0.6.0 - dev: true - - /csstype@3.1.1: - resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} - - /csv-generate@3.4.3: - resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} - dev: false - - /csv-parse@4.16.3: - resolution: {integrity: sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==} - dev: false - - /csv-stringify@5.6.5: - resolution: {integrity: sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==} - dev: false - - /csv@5.5.3: - resolution: {integrity: sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==} - engines: {node: '>= 0.1.90'} - dependencies: - csv-generate: 3.4.3 - csv-parse: 4.16.3 - csv-stringify: 5.6.5 - stream-transform: 2.1.3 - dev: false - - /cypress@9.6.0: - resolution: {integrity: sha512-nNwt9eBQmSENamwa8LxvggXksfyzpyYaQ7lNBLgks3XZ6dPE/6BCQFBzeAyAPt/bNXfH3tKPkAyhiAZPYkWoEg==} - engines: {node: '>=12.0.0'} - hasBin: true - requiresBuild: true - dependencies: - '@cypress/request': 2.88.10 - '@cypress/xvfb': 1.2.4(supports-color@8.1.1) - '@types/node': 14.18.33 - '@types/sinonjs__fake-timers': 8.1.1 - '@types/sizzle': 2.3.3 - arch: 2.2.0 - blob-util: 2.0.2 - bluebird: 3.7.2 - buffer: 5.7.1 - cachedir: 2.3.0 - chalk: 4.1.2 - check-more-types: 2.24.0 - cli-cursor: 3.1.0 - cli-table3: 0.6.2 - commander: 5.1.0 - common-tags: 1.8.2 - dayjs: 1.11.1 - debug: 4.4.0(supports-color@8.1.1) - enquirer: 2.3.6 - eventemitter2: 6.4.5 - execa: 4.1.0 - executable: 4.1.1 - extract-zip: 2.0.1(supports-color@8.1.1) - figures: 3.2.0 - fs-extra: 9.1.0 - getos: 3.2.1 - is-ci: 3.0.1 - is-installed-globally: 0.4.0 - lazy-ass: 1.6.0 - listr2: 3.14.0(enquirer@2.3.6) - lodash: 4.17.21 - log-symbols: 4.1.0 - minimist: 1.2.8 - ospath: 1.2.2 - pretty-bytes: 5.6.0 - proxy-from-env: 1.0.0 - request-progress: 3.0.0 - semver: 7.5.4 - supports-color: 8.1.1 - tmp: 0.2.1 - untildify: 4.0.0 - yauzl: 2.10.0 - dev: false - - /damerau-levenshtein@1.0.8: - resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} - dev: false - - /dashdash@1.14.1: - resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} - engines: {node: '>=0.10'} - dependencies: - assert-plus: 1.0.0 - dev: false - - /data-uri-to-buffer@2.0.2: - resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} - - /data-uri-to-buffer@3.0.1: - resolution: {integrity: sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==} - engines: {node: '>= 6'} - dev: false - - /data-uri-to-buffer@6.0.2: - resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} - engines: {node: '>= 14'} - dev: false - - /data-urls@4.0.0: - resolution: {integrity: sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==} - engines: {node: '>=14'} - dependencies: - abab: 2.0.6 - whatwg-mimetype: 3.0.0 - whatwg-url: 12.0.1 - dev: true - - /dataloader@1.4.0: - resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} - dev: false - - /date-fns@2.28.0: - resolution: {integrity: sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==} - engines: {node: '>=0.11'} - dev: false - - /date-fns@3.6.0: - resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} - - /dayjs@1.11.1: - resolution: {integrity: sha512-ER7EjqVAMkRRsxNCC5YqJ9d9VQYuWdGt7aiH2qA5R5wt8ZmWaP2dLUSIK6y/kVzLMlmh1Tvu5xUf4M/wdGJ5KA==} - dev: false - - /debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - - /debug@3.2.7(supports-color@8.1.1): - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - supports-color: 8.1.1 - dev: false - - /debug@4.4.0(supports-color@8.1.1): - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - supports-color: 8.1.1 - - /decamelize-keys@1.1.0: - resolution: {integrity: sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==} - engines: {node: '>=0.10.0'} - dependencies: - decamelize: 1.2.0 - map-obj: 1.0.1 - dev: false - - /decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} - dev: false - - /decimal.js@10.4.3: - resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} - dev: true - - /decode-named-character-reference@1.0.2: - resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} - dependencies: - character-entities: 2.0.0 - dev: false - - /dedent@0.7.0: - resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} - dev: false - - /dedent@1.5.1: - resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true - - /deep-equal@2.2.0: - resolution: {integrity: sha512-RdpzE0Hv4lhowpIUKKMJfeH6C1pXdtT1/it80ubgWqwI3qpuxUBpC1S4hnHg+zjnuOoDkzUtUCEEkG+XG5l3Mw==} - dependencies: - call-bind: 1.0.7 - es-get-iterator: 1.1.3 - get-intrinsic: 1.2.4 - is-arguments: 1.1.1 - is-array-buffer: 3.0.4 - is-date-object: 1.0.5 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 - isarray: 2.0.5 - object-is: 1.1.5 - object-keys: 1.1.1 - object.assign: 4.1.5 - regexp.prototype.flags: 1.5.2 - side-channel: 1.0.6 - which-boxed-primitive: 1.0.2 - which-collection: 1.0.1 - which-typed-array: 1.1.14 - dev: false - - /deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - /deep-object-diff@1.1.9: - resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==} - - /deepmerge@4.2.2: - resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} - engines: {node: '>=0.10.0'} - - /defaults@1.0.3: - resolution: {integrity: sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==} - dependencies: - clone: 1.0.4 - - /define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - dependencies: - es-define-property: 1.0.0 - es-errors: 1.3.0 - gopd: 1.0.1 - - /define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - dev: false - - /define-property@0.2.5: - resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 0.1.6 - dev: false - - /define-property@1.0.0: - resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 1.0.2 - dev: false - - /define-property@2.0.2: - resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 1.0.2 - isobject: 3.0.1 - dev: false - - /defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - - /degenerator@5.0.1: - resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} - engines: {node: '>= 14'} - dependencies: - ast-types: 0.13.4 - escodegen: 2.1.0 - esprima: 4.0.1 - dev: false - - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - /depd@1.1.2: - resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} - engines: {node: '>= 0.6'} - dev: true - - /depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - - /deprecation@2.3.1: - resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} - dev: false - - /dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - - /destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - - /detect-indent@6.1.0: - resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} - engines: {node: '>=8'} - dev: false - - /detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} - - /devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - dependencies: - dequal: 2.0.3 - dev: false - - /dezalgo@1.0.4: - resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} - dependencies: - asap: 2.0.6 - wrappy: 1.0.2 - dev: true - - /didyoumean@1.2.2: - resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} - - /diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - /diff@5.1.0: - resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} - engines: {node: '>=0.3.1'} - dev: false - - /dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - dependencies: - path-type: 4.0.0 - dev: false - - /dlv@1.1.3: - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - - /doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - dependencies: - esutils: 2.0.3 - dev: false - - /doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dependencies: - esutils: 2.0.3 - - /dom-accessibility-api@0.5.16: - resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} - - /dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.5.0 - dev: false - - /domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - dev: false - - /domexception@4.0.0: - resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} - engines: {node: '>=12'} - deprecated: Use your platform's native DOMException instead - dependencies: - webidl-conversions: 7.0.0 - dev: true - - /domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - dependencies: - domelementtype: 2.3.0 - dev: false - - /domutils@3.1.0: - resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - dev: false - - /dotenv-json@1.0.0: - resolution: {integrity: sha512-jAssr+6r4nKhKRudQ0HOzMskOFFi9+ubXWwmrSGJFgTvpjyPXCXsCsYbjif6mXp7uxA7xY3/LGaiTQukZzSbOQ==} - dev: true - - /dotenv@16.4.4: - resolution: {integrity: sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==} - engines: {node: '>=12'} - dev: false - - /dotenv@8.6.0: - resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} - engines: {node: '>=10'} - - /duplexify@3.7.1: - resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} - dependencies: - end-of-stream: 1.4.4 - inherits: 2.0.4 - readable-stream: 2.3.8 - stream-shift: 1.0.3 - dev: false - - /eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - /ecc-jsbn@0.1.2: - resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} - dependencies: - jsbn: 0.1.1 - safer-buffer: 2.1.2 - dev: false - - /ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - - /electron-to-chromium@1.4.626: - resolution: {integrity: sha512-f7/be56VjRRQk+Ric6PmIrEtPcIqsn3tElyAu9Sh6egha2VLJ82qwkcOdcnT06W+Pb6RUulV1ckzrGbKzVcTHg==} - - /emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} - - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - /emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - /encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} - - /encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - - /end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - dependencies: - once: 1.4.0 - dev: false - - /enhanced-resolve@5.15.0: - resolution: {integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==} - engines: {node: '>=10.13.0'} - dependencies: - graceful-fs: 4.2.11 - tapable: 2.2.1 - dev: false - - /enquirer@2.3.6: - resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} - engines: {node: '>=8.6'} - dependencies: - ansi-colors: 4.1.3 - dev: false - - /entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - /err-code@2.0.3: - resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} - dev: false - - /error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - dependencies: - is-arrayish: 0.2.1 - - /error-symbol@0.1.0: - resolution: {integrity: sha512-VyjaKxUmeDX/m2lxm/aknsJ1GWDWUO2Ze2Ad8S1Pb9dykAm9TjSKp5CjrNyltYqZ5W/PO6TInAmO2/BfwMyT1g==} - engines: {node: '>=0.10.0'} - dev: false - - /es-abstract@1.22.4: - resolution: {integrity: sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==} - engines: {node: '>= 0.4'} - dependencies: - array-buffer-byte-length: 1.0.1 - arraybuffer.prototype.slice: 1.0.3 - available-typed-arrays: 1.0.6 - call-bind: 1.0.7 - es-define-property: 1.0.0 - es-errors: 1.3.0 - es-set-tostringtag: 2.0.2 - es-to-primitive: 1.2.1 - function.prototype.name: 1.1.6 - get-intrinsic: 1.2.4 - get-symbol-description: 1.0.2 - globalthis: 1.0.3 - gopd: 1.0.1 - has-property-descriptors: 1.0.2 - has-proto: 1.0.1 - has-symbols: 1.0.3 - hasown: 2.0.1 - internal-slot: 1.0.7 - is-array-buffer: 3.0.4 - is-callable: 1.2.7 - is-negative-zero: 2.0.2 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 - is-string: 1.0.7 - is-typed-array: 1.1.13 - is-weakref: 1.0.2 - object-inspect: 1.13.1 - object-keys: 1.1.1 - object.assign: 4.1.5 - regexp.prototype.flags: 1.5.2 - safe-array-concat: 1.1.0 - safe-regex-test: 1.0.3 - string.prototype.trim: 1.2.8 - string.prototype.trimend: 1.0.7 - string.prototype.trimstart: 1.0.7 - typed-array-buffer: 1.0.1 - typed-array-byte-length: 1.0.0 - typed-array-byte-offset: 1.0.0 - typed-array-length: 1.0.4 - unbox-primitive: 1.0.2 - which-typed-array: 1.1.14 - dev: false - - /es-array-method-boxes-properly@1.0.0: - resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} - dev: false - - /es-define-property@1.0.0: - resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} - engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.2.4 - - /es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - /es-get-iterator@1.1.3: - resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} - dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.4 - has-symbols: 1.0.3 - is-arguments: 1.1.1 - is-map: 2.0.2 - is-set: 2.0.2 - is-string: 1.0.7 - isarray: 2.0.5 - stop-iteration-iterator: 1.0.0 - dev: false - - /es-iterator-helpers@1.0.17: - resolution: {integrity: sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==} - engines: {node: '>= 0.4'} - dependencies: - asynciterator.prototype: 1.0.0 - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - es-errors: 1.3.0 - es-set-tostringtag: 2.0.2 - function-bind: 1.1.2 - get-intrinsic: 1.2.4 - globalthis: 1.0.3 - has-property-descriptors: 1.0.2 - has-proto: 1.0.1 - has-symbols: 1.0.3 - internal-slot: 1.0.7 - iterator.prototype: 1.1.2 - safe-array-concat: 1.1.0 - dev: false - - /es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - dev: false - - /es-set-tostringtag@2.0.2: - resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} - engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.2.4 - has-tostringtag: 1.0.2 - hasown: 2.0.1 - dev: false - - /es-shim-unscopables@1.0.2: - resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} - dependencies: - hasown: 2.0.1 - dev: false - - /es-to-primitive@1.2.1: - resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} - engines: {node: '>= 0.4'} - dependencies: - is-callable: 1.2.7 - is-date-object: 1.0.5 - is-symbol: 1.0.4 - dev: false - - /esbuild-plugins-node-modules-polyfill@1.6.2(esbuild@0.17.6): - resolution: {integrity: sha512-UwFku/RAQkKi6YsL6SkltZOz7qjmLadvT+7B46jzUqcHrQw524dn4MyMmMRUkAklBsX9nXzVt3LswQlznTJN7A==} - engines: {node: '>=14.0.0'} - peerDependencies: - esbuild: ^0.14.0 || ^0.15.0 || ^0.16.0 || ^0.17.0 || ^0.18.0 || ^0.19.0 || ^0.20.0 - dependencies: - '@jspm/core': 2.0.1 - esbuild: 0.17.6 - local-pkg: 0.5.0 - resolve.exports: 2.0.2 - dev: false - - /esbuild-register@3.5.0(esbuild@0.17.6): - resolution: {integrity: sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A==} - peerDependencies: - esbuild: '>=0.12 <1' - dependencies: - debug: 4.4.0(supports-color@8.1.1) - esbuild: 0.17.6 - transitivePeerDependencies: - - supports-color - dev: true - - /esbuild@0.17.19: - resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/android-arm': 0.17.19 - '@esbuild/android-arm64': 0.17.19 - '@esbuild/android-x64': 0.17.19 - '@esbuild/darwin-arm64': 0.17.19 - '@esbuild/darwin-x64': 0.17.19 - '@esbuild/freebsd-arm64': 0.17.19 - '@esbuild/freebsd-x64': 0.17.19 - '@esbuild/linux-arm': 0.17.19 - '@esbuild/linux-arm64': 0.17.19 - '@esbuild/linux-ia32': 0.17.19 - '@esbuild/linux-loong64': 0.17.19 - '@esbuild/linux-mips64el': 0.17.19 - '@esbuild/linux-ppc64': 0.17.19 - '@esbuild/linux-riscv64': 0.17.19 - '@esbuild/linux-s390x': 0.17.19 - '@esbuild/linux-x64': 0.17.19 - '@esbuild/netbsd-x64': 0.17.19 - '@esbuild/openbsd-x64': 0.17.19 - '@esbuild/sunos-x64': 0.17.19 - '@esbuild/win32-arm64': 0.17.19 - '@esbuild/win32-ia32': 0.17.19 - '@esbuild/win32-x64': 0.17.19 - - /esbuild@0.17.6: - resolution: {integrity: sha512-TKFRp9TxrJDdRWfSsSERKEovm6v30iHnrjlcGhLBOtReE28Yp1VSBRfO3GTaOFMoxsNerx4TjrhzSuma9ha83Q==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/android-arm': 0.17.6 - '@esbuild/android-arm64': 0.17.6 - '@esbuild/android-x64': 0.17.6 - '@esbuild/darwin-arm64': 0.17.6 - '@esbuild/darwin-x64': 0.17.6 - '@esbuild/freebsd-arm64': 0.17.6 - '@esbuild/freebsd-x64': 0.17.6 - '@esbuild/linux-arm': 0.17.6 - '@esbuild/linux-arm64': 0.17.6 - '@esbuild/linux-ia32': 0.17.6 - '@esbuild/linux-loong64': 0.17.6 - '@esbuild/linux-mips64el': 0.17.6 - '@esbuild/linux-ppc64': 0.17.6 - '@esbuild/linux-riscv64': 0.17.6 - '@esbuild/linux-s390x': 0.17.6 - '@esbuild/linux-x64': 0.17.6 - '@esbuild/netbsd-x64': 0.17.6 - '@esbuild/openbsd-x64': 0.17.6 - '@esbuild/sunos-x64': 0.17.6 - '@esbuild/win32-arm64': 0.17.6 - '@esbuild/win32-ia32': 0.17.6 - '@esbuild/win32-x64': 0.17.6 - - /esbuild@0.19.12: - resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/aix-ppc64': 0.19.12 - '@esbuild/android-arm': 0.19.12 - '@esbuild/android-arm64': 0.19.12 - '@esbuild/android-x64': 0.19.12 - '@esbuild/darwin-arm64': 0.19.12 - '@esbuild/darwin-x64': 0.19.12 - '@esbuild/freebsd-arm64': 0.19.12 - '@esbuild/freebsd-x64': 0.19.12 - '@esbuild/linux-arm': 0.19.12 - '@esbuild/linux-arm64': 0.19.12 - '@esbuild/linux-ia32': 0.19.12 - '@esbuild/linux-loong64': 0.19.12 - '@esbuild/linux-mips64el': 0.19.12 - '@esbuild/linux-ppc64': 0.19.12 - '@esbuild/linux-riscv64': 0.19.12 - '@esbuild/linux-s390x': 0.19.12 - '@esbuild/linux-x64': 0.19.12 - '@esbuild/netbsd-x64': 0.19.12 - '@esbuild/openbsd-x64': 0.19.12 - '@esbuild/sunos-x64': 0.19.12 - '@esbuild/win32-arm64': 0.19.12 - '@esbuild/win32-ia32': 0.19.12 - '@esbuild/win32-x64': 0.19.12 - - /esbuild@0.24.2: - resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} - engines: {node: '>=18'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/aix-ppc64': 0.24.2 - '@esbuild/android-arm': 0.24.2 - '@esbuild/android-arm64': 0.24.2 - '@esbuild/android-x64': 0.24.2 - '@esbuild/darwin-arm64': 0.24.2 - '@esbuild/darwin-x64': 0.24.2 - '@esbuild/freebsd-arm64': 0.24.2 - '@esbuild/freebsd-x64': 0.24.2 - '@esbuild/linux-arm': 0.24.2 - '@esbuild/linux-arm64': 0.24.2 - '@esbuild/linux-ia32': 0.24.2 - '@esbuild/linux-loong64': 0.24.2 - '@esbuild/linux-mips64el': 0.24.2 - '@esbuild/linux-ppc64': 0.24.2 - '@esbuild/linux-riscv64': 0.24.2 - '@esbuild/linux-s390x': 0.24.2 - '@esbuild/linux-x64': 0.24.2 - '@esbuild/netbsd-arm64': 0.24.2 - '@esbuild/netbsd-x64': 0.24.2 - '@esbuild/openbsd-arm64': 0.24.2 - '@esbuild/openbsd-x64': 0.24.2 - '@esbuild/sunos-x64': 0.24.2 - '@esbuild/win32-arm64': 0.24.2 - '@esbuild/win32-ia32': 0.24.2 - '@esbuild/win32-x64': 0.24.2 - - /escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} - - /escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - /escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - - /escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - - /escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - /escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} - dev: false - - /escodegen@2.1.0: - resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} - engines: {node: '>=6.0'} - hasBin: true - dependencies: - esprima: 4.0.1 - estraverse: 5.3.0 - esutils: 2.0.3 - optionalDependencies: - source-map: 0.6.1 - dev: false - - /eslint-import-resolver-node@0.3.7: - resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==} - dependencies: - debug: 3.2.7(supports-color@8.1.1) - is-core-module: 2.13.1 - resolve: 1.22.8 - transitivePeerDependencies: - - supports-color - dev: false - - /eslint-import-resolver-node@0.3.9: - resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - dependencies: - debug: 3.2.7(supports-color@8.1.1) - is-core-module: 2.13.1 - resolve: 1.22.8 - transitivePeerDependencies: - - supports-color - dev: false - - /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.29.1)(eslint@8.56.0): - resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '*' - eslint-plugin-import: '*' - dependencies: - debug: 4.4.0(supports-color@8.1.1) - enhanced-resolve: 5.15.0 - eslint: 8.56.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) - fast-glob: 3.3.2 - get-tsconfig: 4.7.2 - is-core-module: 2.13.1 - is-glob: 4.0.3 - transitivePeerDependencies: - - '@typescript-eslint/parser' - - eslint-import-resolver-node - - eslint-import-resolver-webpack - - supports-color - dev: false - - /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): - resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.1.6) - debug: 3.2.7(supports-color@8.1.1) - eslint: 8.56.0 - eslint-import-resolver-node: 0.3.7 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.29.1)(eslint@8.56.0) - transitivePeerDependencies: - - supports-color - dev: false - - /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): - resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.1.6) - debug: 3.2.7(supports-color@8.1.1) - eslint: 8.56.0 - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.29.1)(eslint@8.56.0) - transitivePeerDependencies: - - supports-color - dev: false - - /eslint-plugin-es@3.0.1(eslint@8.56.0): - resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} - engines: {node: '>=8.10.0'} - peerDependencies: - eslint: '>=4.19.1' - dependencies: - eslint: 8.56.0 - eslint-utils: 2.1.0 - regexpp: 3.2.0 - dev: false - - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): - resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.1.6) - array-includes: 3.1.7 - array.prototype.findlastindex: 1.2.4 - array.prototype.flat: 1.3.2 - array.prototype.flatmap: 1.3.2 - debug: 3.2.7(supports-color@8.1.1) - doctrine: 2.1.0 - eslint: 8.56.0 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) - hasown: 2.0.1 - is-core-module: 2.13.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.7 - object.groupby: 1.0.2 - object.values: 1.1.7 - semver: 6.3.1 - tsconfig-paths: 3.15.0 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - dev: false - - /eslint-plugin-jest-dom@4.0.3(eslint@8.56.0): - resolution: {integrity: sha512-9j+n8uj0+V0tmsoS7bYC7fLhQmIvjRqRYEcbDSi+TKPsTThLLXCyj5swMSSf/hTleeMktACnn+HFqXBr5gbcbA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6', yarn: '>=1'} - peerDependencies: - eslint: ^6.8.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@babel/runtime': 7.23.9 - '@testing-library/dom': 8.16.0 - eslint: 8.56.0 - requireindex: 1.2.0 - dev: false - - /eslint-plugin-jest@26.9.0(@typescript-eslint/eslint-plugin@5.62.0)(eslint@8.56.0)(jest@29.6.4)(typescript@5.1.6): - resolution: {integrity: sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/eslint-plugin': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - jest: '*' - peerDependenciesMeta: - '@typescript-eslint/eslint-plugin': - optional: true - jest: - optional: true - dependencies: - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.56.0)(typescript@5.1.6) - '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@5.1.6) - eslint: 8.56.0 - jest: 29.6.4 - transitivePeerDependencies: - - supports-color - - typescript - dev: false - - /eslint-plugin-jsx-a11y@6.8.0(eslint@8.56.0): - resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} - engines: {node: '>=4.0'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - dependencies: - '@babel/runtime': 7.23.9 - aria-query: 5.3.0 - array-includes: 3.1.7 - array.prototype.flatmap: 1.3.2 - ast-types-flow: 0.0.8 - axe-core: 4.7.0 - axobject-query: 3.2.1 - damerau-levenshtein: 1.0.8 - emoji-regex: 9.2.2 - es-iterator-helpers: 1.0.17 - eslint: 8.56.0 - hasown: 2.0.1 - jsx-ast-utils: 3.3.5 - language-tags: 1.0.9 - minimatch: 3.1.2 - object.entries: 1.1.7 - object.fromentries: 2.0.7 - dev: false - - /eslint-plugin-markdown@2.2.1(eslint@8.56.0): - resolution: {integrity: sha512-FgWp4iyYvTFxPwfbxofTvXxgzPsDuSKHQy2S+a8Ve6savbujey+lgrFFbXQA0HPygISpRYWYBjooPzhYSF81iA==} - engines: {node: ^8.10.0 || ^10.12.0 || >= 12.0.0} - peerDependencies: - eslint: '>=6.0.0' - dependencies: - eslint: 8.56.0 - mdast-util-from-markdown: 0.8.5 - transitivePeerDependencies: - - supports-color - dev: false - - /eslint-plugin-node@11.1.0(eslint@8.56.0): - resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} - engines: {node: '>=8.10.0'} - peerDependencies: - eslint: '>=5.16.0' - dependencies: - eslint: 8.56.0 - eslint-plugin-es: 3.0.1(eslint@8.56.0) - eslint-utils: 2.1.0 - ignore: 5.3.1 - minimatch: 3.1.2 - resolve: 1.22.8 - semver: 6.3.1 - dev: false - - /eslint-plugin-prefer-let@3.0.1: - resolution: {integrity: sha512-vbznkkBSXB63d4o1o0NIm5C2ey3V5wKr/25dAvPdydQXdowAcnr69cbLgxd2YAG81IV5eddCO55Lp6gL7wSE4w==} - engines: {node: '>=0.10.0'} - dependencies: - requireindex: 1.2.0 - dev: false - - /eslint-plugin-react-hooks@4.6.0(eslint@8.56.0): - resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - dependencies: - eslint: 8.56.0 - dev: false - - /eslint-plugin-react@7.33.2(eslint@8.56.0): - resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - dependencies: - array-includes: 3.1.7 - array.prototype.flatmap: 1.3.2 - array.prototype.tosorted: 1.1.3 - doctrine: 2.1.0 - es-iterator-helpers: 1.0.17 - eslint: 8.56.0 - estraverse: 5.3.0 - jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 - object.entries: 1.1.7 - object.fromentries: 2.0.7 - object.hasown: 1.1.3 - object.values: 1.1.7 - prop-types: 15.8.1 - resolve: 2.0.0-next.5 - semver: 6.3.1 - string.prototype.matchall: 4.0.10 - dev: false - - /eslint-plugin-testing-library@5.11.1(eslint@8.56.0)(typescript@5.1.6): - resolution: {integrity: sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6'} - peerDependencies: - eslint: ^7.5.0 || ^8.0.0 - dependencies: - '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@5.1.6) - eslint: 8.56.0 - transitivePeerDependencies: - - supports-color - - typescript - dev: false - - /eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - dev: false - - /eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - /eslint-utils@2.1.0: - resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} - engines: {node: '>=6'} - dependencies: - eslint-visitor-keys: 1.3.0 - dev: false - - /eslint-visitor-keys@1.3.0: - resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} - engines: {node: '>=4'} - dev: false - - /eslint-visitor-keys@2.1.0: - resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} - engines: {node: '>=10'} - dev: false - - /eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - /eslint@8.56.0: - resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. - hasBin: true - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) - '@eslint-community/regexpp': 4.10.0 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.56.0 - '@humanwhocodes/config-array': 0.11.14 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.4.0(supports-color@8.1.1) - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.5.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.20.0 - graphemer: 1.4.0 - ignore: 5.3.1 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.3 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - - /espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) - eslint-visitor-keys: 3.4.3 - - /esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - /esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} - dependencies: - estraverse: 5.3.0 - - /esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - dependencies: - estraverse: 5.3.0 - - /estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - dev: false - - /estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - /estree-util-attach-comments@2.1.1: - resolution: {integrity: sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w==} - dependencies: - '@types/estree': 1.0.6 - dev: false - - /estree-util-attach-comments@3.0.0: - resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} - dependencies: - '@types/estree': 1.0.6 - dev: false - - /estree-util-build-jsx@2.2.2: - resolution: {integrity: sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg==} - dependencies: - '@types/estree-jsx': 1.0.0 - estree-util-is-identifier-name: 2.1.0 - estree-walker: 3.0.0 - dev: false - - /estree-util-build-jsx@3.0.1: - resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} - dependencies: - '@types/estree-jsx': 1.0.0 - devlop: 1.1.0 - estree-util-is-identifier-name: 3.0.0 - estree-walker: 3.0.0 - dev: false - - /estree-util-is-identifier-name@1.1.0: - resolution: {integrity: sha512-OVJZ3fGGt9By77Ix9NhaRbzfbDV/2rx9EP7YIDJTmsZSEc5kYn2vWcNccYyahJL2uAQZK2a5Or2i0wtIKTPoRQ==} - dev: false - - /estree-util-is-identifier-name@2.1.0: - resolution: {integrity: sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ==} - dev: false - - /estree-util-is-identifier-name@3.0.0: - resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} - dev: false - - /estree-util-to-js@1.2.0: - resolution: {integrity: sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA==} - dependencies: - '@types/estree-jsx': 1.0.0 - astring: 1.8.3 - source-map: 0.7.3 - dev: false - - /estree-util-to-js@2.0.0: - resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} - dependencies: - '@types/estree-jsx': 1.0.0 - astring: 1.8.3 - source-map: 0.7.3 - dev: false - - /estree-util-value-to-estree@1.3.0: - resolution: {integrity: sha512-Y+ughcF9jSUJvncXwqRageavjrNPAI+1M/L3BI3PyLp1nmgYTGUXU6t5z1Y7OWuThoDdhPME07bQU+d5LxdJqw==} - engines: {node: '>=12.0.0'} - dependencies: - is-plain-obj: 3.0.0 - dev: false - - /estree-util-visit@1.2.1: - resolution: {integrity: sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw==} - dependencies: - '@types/estree-jsx': 1.0.0 - '@types/unist': 2.0.6 - dev: false - - /estree-util-visit@2.0.0: - resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} - dependencies: - '@types/estree-jsx': 1.0.0 - '@types/unist': 3.0.2 - dev: false - - /estree-walker@0.6.1: - resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} - - /estree-walker@1.0.1: - resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} - dev: false - - /estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - dev: false - - /estree-walker@3.0.0: - resolution: {integrity: sha512-s6ceX0NFiU/vKPiKvFdR83U1Zffu7upwZsGwpoqfg5rbbq1l50WQ5hCeIvM6E6oD4shUHCYMsiFPns4Jk0YfMQ==} - dev: false - - /esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - /etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - - /eval@0.1.8: - resolution: {integrity: sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==} - engines: {node: '>= 0.8'} - dependencies: - '@types/node': 18.17.1 - require-like: 0.1.2 - - /event-target-shim@5.0.1: - resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} - engines: {node: '>=6'} - dev: false - - /eventemitter2@6.4.5: - resolution: {integrity: sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw==} - dev: false - - /events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} - dev: true - - /execa@4.1.0: - resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} - engines: {node: '>=10'} - dependencies: - cross-spawn: 7.0.3 - get-stream: 5.2.0 - human-signals: 1.1.1 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - dev: false - - /execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - - /executable@4.1.1: - resolution: {integrity: sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==} - engines: {node: '>=4'} - dependencies: - pify: 2.3.0 - dev: false - - /exit-hook@2.2.1: - resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} - engines: {node: '>=6'} - - /exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} - - /expect@29.6.4: - resolution: {integrity: sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/expect-utils': 29.6.4 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.6.4 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - - /express@4.21.1: - resolution: {integrity: sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==} - engines: {node: '>= 0.10.0'} - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.3 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.7.1 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.3.1 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.3 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.10 - proxy-addr: 2.0.7 - qs: 6.13.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.19.0 - serve-static: 1.16.2 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - - /extend-shallow@2.0.1: - resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} - engines: {node: '>=0.10.0'} - dependencies: - is-extendable: 0.1.1 - dev: false - - /extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - dev: false - - /extendable-error@0.1.7: - resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} - dev: false - - /external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - - /extract-zip@2.0.1(supports-color@8.1.1): - resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} - engines: {node: '>= 10.17.0'} - hasBin: true - dependencies: - debug: 4.4.0(supports-color@8.1.1) - get-stream: 5.2.0 - yauzl: 2.10.0 - optionalDependencies: - '@types/yauzl': 2.10.3 - transitivePeerDependencies: - - supports-color - dev: false - - /extsprintf@1.3.0: - resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} - engines: {'0': node >=0.6.0} - dev: false - - /fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - /fast-glob@3.2.11: - resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==} - engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - - /fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} - engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - - /fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - /fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - /fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - dev: true - - /fastq@1.13.0: - resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} - dependencies: - reusify: 1.0.4 - - /fault@2.0.0: - resolution: {integrity: sha512-JsDj9LFcoC+4ChII1QpXPA7YIaY8zmqPYw7h9j5n7St7a0BBKfNnwEBAUQRBx70o2q4rs+BeSNHk8Exm6xE7fQ==} - dependencies: - format: 0.2.2 - dev: false - - /fb-watchman@2.0.1: - resolution: {integrity: sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==} - dependencies: - bser: 2.1.1 - - /fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - dependencies: - pend: 1.2.0 - dev: false - - /figures@3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - dependencies: - escape-string-regexp: 1.0.5 - - /file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flat-cache: 3.0.4 - - /fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} - dependencies: - to-regex-range: 5.0.1 - - /finalhandler@1.3.1: - resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} - engines: {node: '>= 0.8'} - dependencies: - debug: 2.6.9 - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - - /find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - - /find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - /find-yarn-workspace-root2@1.2.16: - resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} - dependencies: - micromatch: 4.0.5 - pkg-dir: 4.2.0 - dev: false - - /flat-cache@3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flatted: 3.2.2 - rimraf: 3.0.2 - - /flatted@3.2.2: - resolution: {integrity: sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==} - - /follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false - - /for-each@0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - dependencies: - is-callable: 1.2.7 - - /for-in@0.1.8: - resolution: {integrity: sha512-F0to7vbBSHP8E3l6dCjxNOLuSFAACIxFy3UehTUlG7svlXi37HHsDkyVcHo0Pq8QwrE+pXvWSVX3ZT1T9wAZ9g==} - engines: {node: '>=0.10.0'} - dev: false - - /for-in@1.0.2: - resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} - engines: {node: '>=0.10.0'} - dev: false - - /for-own@1.0.0: - resolution: {integrity: sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==} - engines: {node: '>=0.10.0'} - dependencies: - for-in: 1.0.2 - dev: false - - /foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} - engines: {node: '>=14'} - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - - /forever-agent@0.6.1: - resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - dev: false - - /form-data@2.3.3: - resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} - engines: {node: '>= 0.12'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - - /format@0.2.2: - resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} - engines: {node: '>=0.4.x'} - dev: false - - /formidable@2.1.2: - resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} - deprecated: 'ACTION REQUIRED: SWITCH TO v3 - v1 and v2 are VULNERABLE! v1 is DEPRECATED FOR OVER 2 YEARS! Use formidable@latest or try formidable-mini for fresh projects' - dependencies: - dezalgo: 1.0.4 - hexoid: 1.0.0 - once: 1.4.0 - qs: 6.13.0 - dev: true - - /forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - - /fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} - - /front-matter@4.0.2: - resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} - dependencies: - js-yaml: 3.14.1 - dev: false - - /fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - dev: false - - /fs-extra@10.1.0: - resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} - engines: {node: '>=12'} - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.0 - dev: false - - /fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} - engines: {node: '>=14.14'} - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.0 - dev: false - - /fs-extra@7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} - engines: {node: '>=6 <7 || >=8'} - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - dev: false - - /fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - dev: false - - /fs-extra@9.1.0: - resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} - engines: {node: '>=10'} - dependencies: - at-least-node: 1.0.0 - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.0 - dev: false - - /fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.6 - dev: false - - /fs-minipass@3.0.3: - resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - minipass: 7.0.4 - dev: false - - /fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - - /fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - dev: false - optional: true - - /fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - optional: true - - /function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - /function.prototype.name@1.1.6: - resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - functions-have-names: 1.2.3 - dev: false - - /functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - dev: false - - /generic-names@4.0.0: - resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==} - dependencies: - loader-utils: 3.2.1 - dev: false - - /gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - /get-intrinsic@1.2.4: - resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} - engines: {node: '>= 0.4'} - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - has-proto: 1.0.1 - has-symbols: 1.0.3 - hasown: 2.0.1 - - /get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - - /get-port@5.1.1: - resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} - engines: {node: '>=8'} - dev: false - - /get-source@2.0.12: - resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} - dependencies: - data-uri-to-buffer: 2.0.2 - source-map: 0.6.1 - - /get-stream@5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} - dependencies: - pump: 3.0.0 - dev: false - - /get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - - /get-symbol-description@1.0.2: - resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - get-intrinsic: 1.2.4 - dev: false - - /get-tsconfig@4.7.2: - resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} - dependencies: - resolve-pkg-maps: 1.0.0 - dev: false - - /get-uri@6.0.3: - resolution: {integrity: sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==} - engines: {node: '>= 14'} - dependencies: - basic-ftp: 5.0.4 - data-uri-to-buffer: 6.0.2 - debug: 4.4.0(supports-color@8.1.1) - fs-extra: 11.2.0 - transitivePeerDependencies: - - supports-color - dev: false - - /getos@3.2.1: - resolution: {integrity: sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==} - dependencies: - async: 3.2.3 - - /getpass@0.1.7: - resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} - dependencies: - assert-plus: 1.0.0 - dev: false - - /git-hooks-list@1.0.3: - resolution: {integrity: sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ==} - dev: false - - /glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - dependencies: - is-glob: 4.0.3 - - /glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - dependencies: - is-glob: 4.0.3 - - /glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - - /glob@10.3.10: - resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - dependencies: - foreground-child: 3.1.1 - jackspeak: 2.3.6 - minimatch: 9.0.3 - minipass: 7.0.4 - path-scurry: 1.10.1 - - /glob@7.2.0: - resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} - deprecated: Glob versions prior to v9 are no longer supported - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - /glob@8.0.3: - resolution: {integrity: sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==} - engines: {node: '>=12'} - deprecated: Glob versions prior to v9 are no longer supported - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 5.1.0 - once: 1.4.0 - dev: false - - /glob@9.3.5: - resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - fs.realpath: 1.0.0 - minimatch: 8.0.4 - minipass: 4.2.8 - path-scurry: 1.10.1 - dev: false - - /global-dirs@3.0.0: - resolution: {integrity: sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==} - engines: {node: '>=10'} - dependencies: - ini: 2.0.0 - dev: false - - /globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - - /globals@13.20.0: - resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.20.2 - - /globalthis@1.0.3: - resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} - engines: {node: '>= 0.4'} - dependencies: - define-properties: 1.2.1 - dev: false - - /globby@10.0.0: - resolution: {integrity: sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw==} - engines: {node: '>=8'} - dependencies: - '@types/glob': 7.2.0 - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.2.11 - glob: 7.2.0 - ignore: 5.3.1 - merge2: 1.4.1 - slash: 3.0.0 - dev: false - - /globby@10.0.1: - resolution: {integrity: sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==} - engines: {node: '>=8'} - dependencies: - '@types/glob': 7.2.0 - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.2.11 - glob: 7.2.0 - ignore: 5.3.1 - merge2: 1.4.1 - slash: 3.0.0 - dev: false - - /globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.2.11 - ignore: 5.3.1 - merge2: 1.4.1 - slash: 3.0.0 - dev: false - - /globrex@0.1.2: - resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} - - /gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} - dependencies: - get-intrinsic: 1.2.4 - - /graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - /grapheme-splitter@1.0.4: - resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} - dev: false - - /graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - /graphql@16.8.1: - resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} - engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - dev: true - - /gunzip-maybe@1.4.2: - resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} - hasBin: true - dependencies: - browserify-zlib: 0.1.4 - is-deflate: 1.0.0 - is-gzip: 1.0.0 - peek-stream: 1.1.3 - pumpify: 1.5.1 - through2: 2.0.5 - dev: false - - /hard-rejection@2.1.0: - resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} - engines: {node: '>=6'} - dev: false - - /has-bigints@1.0.2: - resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} - dev: false - - /has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - - /has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - /has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - dependencies: - es-define-property: 1.0.0 - - /has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} - engines: {node: '>= 0.4'} - - /has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - - /has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - - /hasown@2.0.1: - resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} - engines: {node: '>= 0.4'} - dependencies: - function-bind: 1.1.2 - - /hast-util-to-estree@2.3.3: - resolution: {integrity: sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ==} - dependencies: - '@types/estree': 1.0.6 - '@types/estree-jsx': 1.0.0 - '@types/hast': 2.3.10 - '@types/unist': 2.0.6 - comma-separated-tokens: 2.0.2 - estree-util-attach-comments: 2.1.1 - estree-util-is-identifier-name: 2.1.0 - hast-util-whitespace: 2.0.1 - mdast-util-mdx-expression: 1.3.2 - mdast-util-mdxjs-esm: 1.3.1 - property-information: 6.0.1 - space-separated-tokens: 2.0.1 - style-to-object: 0.4.4 - unist-util-position: 4.0.4 - zwitch: 2.0.2 - transitivePeerDependencies: - - supports-color - dev: false - - /hast-util-to-estree@3.1.0: - resolution: {integrity: sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==} - dependencies: - '@types/estree': 1.0.6 - '@types/estree-jsx': 1.0.0 - '@types/hast': 3.0.3 - comma-separated-tokens: 2.0.2 - devlop: 1.1.0 - estree-util-attach-comments: 3.0.0 - estree-util-is-identifier-name: 3.0.0 - hast-util-whitespace: 3.0.0 - mdast-util-mdx-expression: 2.0.0 - mdast-util-mdx-jsx: 3.0.0 - mdast-util-mdxjs-esm: 2.0.1 - property-information: 6.0.1 - space-separated-tokens: 2.0.1 - style-to-object: 0.4.4 - unist-util-position: 5.0.0 - zwitch: 2.0.2 - transitivePeerDependencies: - - supports-color - dev: false - - /hast-util-to-jsx-runtime@2.2.0: - resolution: {integrity: sha512-wSlp23N45CMjDg/BPW8zvhEi3R+8eRE1qFbjEyAUzMCzu2l1Wzwakq+Tlia9nkCtEl5mDxa7nKHsvYJ6Gfn21A==} - dependencies: - '@types/hast': 3.0.3 - '@types/unist': 3.0.2 - comma-separated-tokens: 2.0.2 - hast-util-whitespace: 3.0.0 - property-information: 6.0.1 - space-separated-tokens: 2.0.1 - style-to-object: 0.4.4 - unist-util-position: 5.0.0 - vfile-message: 4.0.2 - dev: false - - /hast-util-whitespace@2.0.1: - resolution: {integrity: sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==} - dev: false - - /hast-util-whitespace@3.0.0: - resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} - dependencies: - '@types/hast': 3.0.3 - dev: false - - /headers-polyfill@3.2.5: - resolution: {integrity: sha512-tUCGvt191vNSQgttSyJoibR+VO+I6+iCHIUdhzEMJKE+EAL8BwCN7fUOZlY4ofOelNHsK+gEjxB/B+9N3EWtdA==} - dev: true - - /hexoid@1.0.0: - resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} - engines: {node: '>=8'} - dev: true - - /hosted-git-info@2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - dev: false - - /hosted-git-info@6.1.1: - resolution: {integrity: sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - lru-cache: 7.18.3 - dev: false - - /html-encoding-sniffer@3.0.0: - resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} - engines: {node: '>=12'} - dependencies: - whatwg-encoding: 2.0.0 - dev: true - - /html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - - /htmlparser2@8.0.2: - resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.1.0 - entities: 4.5.0 - dev: false - - /http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - - /http-proxy-agent@5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} - dependencies: - '@tootallnate/once': 2.0.0 - agent-base: 6.0.2 - debug: 4.4.0(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - dev: true - - /http-proxy-agent@7.0.1: - resolution: {integrity: sha512-My1KCEPs6A0hb4qCVzYp8iEvA8j8YqcvXLZZH8C9OFuTYpYjHE7N2dtG3mRl1HMD4+VGXpF3XcDVcxGBT7yDZQ==} - engines: {node: '>= 14'} - dependencies: - agent-base: 7.1.0 - debug: 4.4.0(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - dev: false - - /http-signature@1.3.6: - resolution: {integrity: sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==} - engines: {node: '>=0.10'} - dependencies: - assert-plus: 1.0.0 - jsprim: 2.0.2 - sshpk: 1.17.0 - dev: false - - /https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - dependencies: - agent-base: 6.0.2 - debug: 4.4.0(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - dev: true - - /https-proxy-agent@7.0.3: - resolution: {integrity: sha512-kCnwztfX0KZJSLOBrcL0emLeFako55NWMovvyPP2AjsghNk9RB1yjSI+jVumPHYZsNXegNoqupSW9IY3afSH8w==} - engines: {node: '>= 14'} - dependencies: - agent-base: 7.1.0 - debug: 4.4.0(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - dev: false - - /human-id@1.0.2: - resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} - dev: false - - /human-signals@1.1.1: - resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} - engines: {node: '>=8.12.0'} - dev: false - - /human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - - /iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - - /iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: true - - /icss-utils@5.1.0(postcss@8.4.49): - resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 - dependencies: - postcss: 8.4.49 - dev: false - - /ieee754@1.1.13: - resolution: {integrity: sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==} - - /ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} - engines: {node: '>= 4'} - - /import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - /import-local@3.0.2: - resolution: {integrity: sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==} - engines: {node: '>=8'} - hasBin: true - dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - - /imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - /indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} - - /inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - /info-symbol@0.1.0: - resolution: {integrity: sha512-qkc9wjLDQ+dYYZnY5uJXGNNHyZ0UOMDUnhvy0SEZGVVYmQ5s4i8cPAin2MbU6OxJgi8dfj/AnwqPx0CJE6+Lsw==} - engines: {node: '>=0.10.0'} - dev: false - - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - /ini@2.0.0: - resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} - engines: {node: '>=10'} - dev: false - - /inline-style-parser@0.1.1: - resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} - dev: false - - /inquirer@8.2.6: - resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==} - engines: {node: '>=12.0.0'} - dependencies: - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - ora: 5.4.1 - run-async: 2.4.1 - rxjs: 7.8.1 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - wrap-ansi: 6.2.0 - dev: true - - /internal-slot@1.0.7: - resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} - engines: {node: '>= 0.4'} - dependencies: - es-errors: 1.3.0 - hasown: 2.0.1 - side-channel: 1.0.6 - dev: false - - /interpret@1.4.0: - resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} - engines: {node: '>= 0.10'} - dev: false - - /ip-address@9.0.5: - resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} - engines: {node: '>= 12'} - dependencies: - jsbn: 1.1.0 - sprintf-js: 1.1.3 - dev: false - - /ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - - /is-accessor-descriptor@0.1.6: - resolution: {integrity: sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==} - engines: {node: '>=0.10.0'} - deprecated: Please upgrade to v0.1.7 - dependencies: - kind-of: 3.2.2 - dev: false - - /is-accessor-descriptor@1.0.0: - resolution: {integrity: sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==} - engines: {node: '>=0.10.0'} - deprecated: Please upgrade to v1.0.1 - dependencies: - kind-of: 6.0.3 - dev: false - - /is-alphabetical@1.0.4: - resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} - dev: false - - /is-alphabetical@2.0.0: - resolution: {integrity: sha512-5OV8Toyq3oh4eq6sbWTYzlGdnMT/DPI5I0zxUBxjiigQsZycpkKF3kskkao3JyYGuYDHvhgJF+DrjMQp9SX86w==} - dev: false - - /is-alphanumerical@1.0.4: - resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} - dependencies: - is-alphabetical: 1.0.4 - is-decimal: 1.0.4 - dev: false - - /is-alphanumerical@2.0.0: - resolution: {integrity: sha512-t+2GlJ+hO9yagJ+jU3+HSh80VKvz/3cG2cxbGGm4S0hjKuhWQXgPVUVOZz3tqZzMjhmphZ+1TIJTlRZRoe6GCQ==} - dependencies: - is-alphabetical: 2.0.0 - is-decimal: 2.0.0 - dev: false - - /is-arguments@1.1.1: - resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 - - /is-array-buffer@3.0.4: - resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.4 - dev: false - - /is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - - /is-async-function@2.0.0: - resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.2 - dev: false - - /is-bigint@1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} - dependencies: - has-bigints: 1.0.2 - dev: false - - /is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - dependencies: - binary-extensions: 2.2.0 - - /is-boolean-object@1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 - dev: false - - /is-buffer@1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - dev: false - - /is-buffer@2.0.5: - resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} - engines: {node: '>=4'} - dev: false - - /is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - - /is-ci@3.0.1: - resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} - hasBin: true - dependencies: - ci-info: 3.3.2 - dev: false - - /is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} - dependencies: - hasown: 2.0.1 - - /is-data-descriptor@0.1.4: - resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==} - engines: {node: '>=0.10.0'} - deprecated: Please upgrade to v0.1.5 - dependencies: - kind-of: 3.2.2 - dev: false - - /is-data-descriptor@1.0.0: - resolution: {integrity: sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==} - engines: {node: '>=0.10.0'} - deprecated: Please upgrade to v1.0.1 - dependencies: - kind-of: 6.0.3 - dev: false - - /is-date-object@1.0.5: - resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.2 - dev: false - - /is-decimal@1.0.4: - resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} - dev: false - - /is-decimal@2.0.0: - resolution: {integrity: sha512-QfrfjQV0LjoWQ1K1XSoEZkTAzSa14RKVMa5zg3SdAfzEmQzRM4+tbSFWb78creCeA9rNBzaZal92opi1TwPWZw==} - dev: false - - /is-deflate@1.0.0: - resolution: {integrity: sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==} - dev: false - - /is-descriptor@0.1.6: - resolution: {integrity: sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==} - engines: {node: '>=0.10.0'} - dependencies: - is-accessor-descriptor: 0.1.6 - is-data-descriptor: 0.1.4 - kind-of: 5.1.0 - dev: false - - /is-descriptor@1.0.2: - resolution: {integrity: sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==} - engines: {node: '>=0.10.0'} - dependencies: - is-accessor-descriptor: 1.0.0 - is-data-descriptor: 1.0.0 - kind-of: 6.0.3 - dev: false - - /is-extendable@0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} - dev: false - - /is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - /is-finalizationregistry@1.0.2: - resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} - dependencies: - call-bind: 1.0.7 - dev: false - - /is-fullwidth-code-point@2.0.0: - resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} - engines: {node: '>=4'} - dev: false - - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - /is-fullwidth-code-point@4.0.0: - resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} - engines: {node: '>=12'} - dev: false - - /is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} - - /is-generator-function@1.0.10: - resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.2 - - /is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - - /is-gzip@1.0.0: - resolution: {integrity: sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==} - engines: {node: '>=0.10.0'} - dev: false - - /is-hexadecimal@1.0.4: - resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} - dev: false - - /is-hexadecimal@2.0.0: - resolution: {integrity: sha512-vGOtYkiaxwIiR0+Ng/zNId+ZZehGfINwTzdrDqc6iubbnQWhnPuYymOzOKUDqa2cSl59yHnEh2h6MvRLQsyNug==} - dev: false - - /is-installed-globally@0.4.0: - resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} - engines: {node: '>=10'} - dependencies: - global-dirs: 3.0.0 - is-path-inside: 3.0.3 - dev: false - - /is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - - /is-map@2.0.2: - resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} - dev: false - - /is-module@1.0.0: - resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - dev: false - - /is-negative-zero@2.0.2: - resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} - engines: {node: '>= 0.4'} - dev: false - - /is-node-process@1.2.0: - resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} - dev: true - - /is-number-object@1.0.6: - resolution: {integrity: sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.2 - dev: false - - /is-number@3.0.0: - resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: false - - /is-number@6.0.0: - resolution: {integrity: sha512-Wu1VHeILBK8KAWJUAiSZQX94GmOE45Rg6/538fKwiloUu21KncEkYGPqob2oSZ5mUT73vLGrHQjKw3KMPwfDzg==} - engines: {node: '>=0.10.0'} - dev: false - - /is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - /is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - - /is-plain-obj@1.1.0: - resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} - engines: {node: '>=0.10.0'} - dev: false - - /is-plain-obj@2.1.0: - resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} - engines: {node: '>=8'} - dev: false - - /is-plain-obj@3.0.0: - resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} - engines: {node: '>=10'} - dev: false - - /is-plain-obj@4.0.0: - resolution: {integrity: sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==} - engines: {node: '>=12'} - dev: false - - /is-plain-object@2.0.4: - resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - - /is-plain-object@3.0.1: - resolution: {integrity: sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==} - engines: {node: '>=0.10.0'} - dev: false - - /is-plain-object@5.0.0: - resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} - engines: {node: '>=0.10.0'} - dev: false - - /is-potential-custom-element-name@1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - dev: true - - /is-reference@1.2.1: - resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} - dependencies: - '@types/estree': 1.0.6 - dev: false - - /is-reference@3.0.0: - resolution: {integrity: sha512-Eo1W3wUoHWoCoVM4GVl/a+K0IgiqE5aIo4kJABFyMum1ZORlPkC+UC357sSQUL5w5QCE5kCC9upl75b7+7CY/Q==} - dependencies: - '@types/estree': 1.0.6 - dev: false - - /is-regex@1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 - dev: false - - /is-set@2.0.2: - resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} - dev: false - - /is-shared-array-buffer@1.0.2: - resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} - dependencies: - call-bind: 1.0.7 - dev: false - - /is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - /is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.2 - dev: false - - /is-subdir@1.2.0: - resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} - engines: {node: '>=4'} - dependencies: - better-path-resolve: 1.0.0 - dev: false - - /is-symbol@1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: false - - /is-typed-array@1.1.13: - resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} - engines: {node: '>= 0.4'} - dependencies: - which-typed-array: 1.1.14 - - /is-typedarray@1.0.0: - resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - dev: false - - /is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - - /is-weakmap@2.0.1: - resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} - dev: false - - /is-weakref@1.0.2: - resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} - dependencies: - call-bind: 1.0.7 - dev: false - - /is-weakset@2.0.2: - resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} - dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.4 - dev: false - - /is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - dev: false - - /isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - dev: false - - /isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - dev: false - - /isbot@4.4.0: - resolution: {integrity: sha512-8ZvOWUA68kyJO4hHJdWjyreq7TYNWTS9y15IzeqVdKxR9pPr3P/3r9AHcoIv9M0Rllkao5qWz2v1lmcyKIVCzQ==} - engines: {node: '>=18'} - dev: false - - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - /isobject@3.0.1: - resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} - engines: {node: '>=0.10.0'} - - /isstream@0.1.2: - resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} - dev: false - - /istanbul-lib-coverage@3.2.0: - resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} - engines: {node: '>=8'} - - /istanbul-lib-instrument@5.1.0: - resolution: {integrity: sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==} - engines: {node: '>=8'} - dependencies: - '@babel/core': 7.23.7 - '@babel/parser': 7.23.6 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.0 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - /istanbul-lib-instrument@6.0.0: - resolution: {integrity: sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==} - engines: {node: '>=10'} - dependencies: - '@babel/core': 7.23.7 - '@babel/parser': 7.23.6 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.0 - semver: 7.5.4 - transitivePeerDependencies: - - supports-color - - /istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} - engines: {node: '>=8'} - dependencies: - istanbul-lib-coverage: 3.2.0 - make-dir: 3.1.0 - supports-color: 7.2.0 - - /istanbul-lib-source-maps@4.0.0: - resolution: {integrity: sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==} - engines: {node: '>=8'} - dependencies: - debug: 4.4.0(supports-color@8.1.1) - istanbul-lib-coverage: 3.2.0 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - - /istanbul-reports@3.1.4: - resolution: {integrity: sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==} - engines: {node: '>=8'} - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.0 - - /iterator.prototype@1.1.2: - resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} - dependencies: - define-properties: 1.2.1 - get-intrinsic: 1.2.4 - has-symbols: 1.0.3 - reflect.getprototypeof: 1.0.5 - set-function-name: 2.0.1 - dev: false - - /jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} - engines: {node: '>=14'} - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - /javascript-stringify@2.1.0: - resolution: {integrity: sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==} - - /jest-changed-files@29.6.3: - resolution: {integrity: sha512-G5wDnElqLa4/c66ma5PG9eRjE342lIbF6SUnTJi26C3J28Fv2TVY2rOyKB9YGbSA5ogwevgmxc4j4aVjrEK6Yg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - execa: 5.1.1 - jest-util: 29.7.0 - p-limit: 3.1.0 - - /jest-circus@29.6.4: - resolution: {integrity: sha512-YXNrRyntVUgDfZbjXWBMPslX1mQ8MrSG0oM/Y06j9EYubODIyHWP8hMUbjbZ19M3M+zamqEur7O80HODwACoJw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.6.4 - '@jest/test-result': 29.6.4 - '@jest/types': 29.6.3 - '@types/node': 18.17.1 - chalk: 4.1.2 - co: 4.6.0 - dedent: 1.5.1 - is-generator-fn: 2.1.0 - jest-each: 29.6.3 - jest-matcher-utils: 29.6.4 - jest-message-util: 29.7.0 - jest-runtime: 29.6.4 - jest-snapshot: 29.6.4 - jest-util: 29.7.0 - p-limit: 3.1.0 - pretty-format: 29.7.0 - pure-rand: 6.0.2 - slash: 3.0.0 - stack-utils: 2.0.5 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - /jest-cli@29.6.4: - resolution: {integrity: sha512-+uMCQ7oizMmh8ZwRfZzKIEszFY9ksjjEQnTEMTaL7fYiL3Kw4XhqT9bYh+A4DQKUb67hZn2KbtEnDuHvcgK4pQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 29.6.4 - '@jest/test-result': 29.6.4 - '@jest/types': 29.6.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - import-local: 3.0.2 - jest-config: 29.6.4(@types/node@18.17.1) - jest-util: 29.7.0 - jest-validate: 29.6.3 - prompts: 2.4.2 - yargs: 17.5.1 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - /jest-config@29.6.4(@types/node@18.17.1): - resolution: {integrity: sha512-JWohr3i9m2cVpBumQFv2akMEnFEPVOh+9L2xIBJhJ0zOaci2ZXuKJj0tgMKQCBZAKA09H049IR4HVS/43Qb19A==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - dependencies: - '@babel/core': 7.23.7 - '@jest/test-sequencer': 29.6.4 - '@jest/types': 29.6.3 - '@types/node': 18.17.1 - babel-jest: 29.6.4(@babel/core@7.23.7) - chalk: 4.1.2 - ci-info: 3.3.2 - deepmerge: 4.2.2 - glob: 7.2.0 - graceful-fs: 4.2.11 - jest-circus: 29.6.4 - jest-environment-node: 29.6.4 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.6.4 - jest-runner: 29.6.4 - jest-util: 29.7.0 - jest-validate: 29.6.3 - micromatch: 4.0.5 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - /jest-diff@29.6.4: - resolution: {integrity: sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - chalk: 4.1.2 - diff-sequences: 29.6.3 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - /jest-docblock@29.6.3: - resolution: {integrity: sha512-2+H+GOTQBEm2+qFSQ7Ma+BvyV+waiIFxmZF5LdpBsAEjWX8QYjSCa4FrkIYtbfXUJJJnFCYrOtt6TZ+IAiTjBQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - detect-newline: 3.1.0 - - /jest-each@29.6.3: - resolution: {integrity: sha512-KoXfJ42k8cqbkfshW7sSHcdfnv5agDdHCPA87ZBdmHP+zJstTJc0ttQaJ/x7zK6noAL76hOuTIJ6ZkQRS5dcyg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - jest-get-type: 29.6.3 - jest-util: 29.7.0 - pretty-format: 29.7.0 - - /jest-environment-jsdom@29.7.0: - resolution: {integrity: sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true - dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/jsdom': 20.0.1 - '@types/node': 18.17.1 - jest-mock: 29.7.0 - jest-util: 29.7.0 - jsdom: 22.1.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - dev: true - - /jest-environment-node@29.6.4: - resolution: {integrity: sha512-i7SbpH2dEIFGNmxGCpSc2w9cA4qVD+wfvg2ZnfQ7XVrKL0NA5uDVBIiGH8SR4F0dKEv/0qI5r+aDomDf04DpEQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 18.17.1 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - /jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - /jest-haste-map@29.6.4: - resolution: {integrity: sha512-12Ad+VNTDHxKf7k+M65sviyynRoZYuL1/GTuhEVb8RYsNSNln71nANRb/faSyWvx0j+gHcivChXHIoMJrGYjog==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.3 - '@types/graceful-fs': 4.1.6 - '@types/node': 18.17.1 - anymatch: 3.1.2 - fb-watchman: 2.0.1 - graceful-fs: 4.2.11 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - jest-worker: 29.6.4 - micromatch: 4.0.5 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.3 - - /jest-leak-detector@29.6.3: - resolution: {integrity: sha512-0kfbESIHXYdhAdpLsW7xdwmYhLf1BRu4AA118/OxFm0Ho1b2RcTmO4oF6aAMaxpxdxnJ3zve2rgwzNBD4Zbm7Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - /jest-matcher-utils@29.6.4: - resolution: {integrity: sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - chalk: 4.1.2 - jest-diff: 29.6.4 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - /jest-message-util@29.7.0: - resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/code-frame': 7.23.5 - '@jest/types': 29.6.3 - '@types/stack-utils': 2.0.1 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.5 - pretty-format: 29.7.0 - slash: 3.0.0 - stack-utils: 2.0.5 - - /jest-mock@29.7.0: - resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.3 - '@types/node': 18.17.1 - jest-util: 29.7.0 - - /jest-pnp-resolver@1.2.2(jest-resolve@29.6.4): - resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true - dependencies: - jest-resolve: 29.6.4 - - /jest-regex-util@29.6.3: - resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - /jest-resolve-dependencies@29.6.4: - resolution: {integrity: sha512-7+6eAmr1ZBF3vOAJVsfLj1QdqeXG+WYhidfLHBRZqGN24MFRIiKG20ItpLw2qRAsW/D2ZUUmCNf6irUr/v6KHA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-regex-util: 29.6.3 - jest-snapshot: 29.6.4 - transitivePeerDependencies: - - supports-color - - /jest-resolve@29.6.4: - resolution: {integrity: sha512-fPRq+0vcxsuGlG0O3gyoqGTAxasagOxEuyoxHeyxaZbc9QNek0AmJWSkhjlMG+mTsj+8knc/mWb3fXlRNVih7Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.11 - jest-haste-map: 29.6.4 - jest-pnp-resolver: 1.2.2(jest-resolve@29.6.4) - jest-util: 29.7.0 - jest-validate: 29.6.3 - resolve: 1.22.8 - resolve.exports: 2.0.2 - slash: 3.0.0 - - /jest-runner@29.6.4: - resolution: {integrity: sha512-SDaLrMmtVlQYDuG0iSPYLycG8P9jLI+fRm8AF/xPKhYDB2g6xDWjXBrR5M8gEWsK6KVFlebpZ4QsrxdyIX1Jaw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/console': 29.6.4 - '@jest/environment': 29.7.0 - '@jest/test-result': 29.6.4 - '@jest/transform': 29.6.4 - '@jest/types': 29.6.3 - '@types/node': 18.17.1 - chalk: 4.1.2 - emittery: 0.13.1 - graceful-fs: 4.2.11 - jest-docblock: 29.6.3 - jest-environment-node: 29.6.4 - jest-haste-map: 29.6.4 - jest-leak-detector: 29.6.3 - jest-message-util: 29.7.0 - jest-resolve: 29.6.4 - jest-runtime: 29.6.4 - jest-util: 29.7.0 - jest-watcher: 29.6.4 - jest-worker: 29.6.4 - p-limit: 3.1.0 - source-map-support: 0.5.13 - transitivePeerDependencies: - - supports-color - - /jest-runtime@29.6.4: - resolution: {integrity: sha512-s/QxMBLvmwLdchKEjcLfwzP7h+jsHvNEtxGP5P+Fl1FMaJX2jMiIqe4rJw4tFprzCwuSvVUo9bn0uj4gNRXsbA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/globals': 29.6.4 - '@jest/source-map': 29.6.3 - '@jest/test-result': 29.6.4 - '@jest/transform': 29.6.4 - '@jest/types': 29.6.3 - '@types/node': 18.17.1 - chalk: 4.1.2 - cjs-module-lexer: 1.2.2 - collect-v8-coverage: 1.0.1 - glob: 7.2.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.6.4 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.6.4 - jest-snapshot: 29.6.4 - jest-util: 29.7.0 - slash: 3.0.0 - strip-bom: 4.0.0 - transitivePeerDependencies: - - supports-color - - /jest-snapshot@29.6.4: - resolution: {integrity: sha512-VC1N8ED7+4uboUKGIDsbvNAZb6LakgIPgAF4RSpF13dN6YaMokfRqO+BaqK4zIh6X3JffgwbzuGqDEjHm/MrvA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/core': 7.23.7 - '@babel/generator': 7.23.6 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.7) - '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.23.7) - '@babel/types': 7.23.6 - '@jest/expect-utils': 29.6.4 - '@jest/transform': 29.6.4 - '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.7) - chalk: 4.1.2 - expect: 29.6.4 - graceful-fs: 4.2.11 - jest-diff: 29.6.4 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.6.4 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - natural-compare: 1.4.0 - pretty-format: 29.7.0 - semver: 7.5.4 - transitivePeerDependencies: - - supports-color - - /jest-util@29.7.0: - resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.3 - '@types/node': 18.17.1 - chalk: 4.1.2 - ci-info: 3.3.2 - graceful-fs: 4.2.11 - picomatch: 2.3.1 - - /jest-validate@29.6.3: - resolution: {integrity: sha512-e7KWZcAIX+2W1o3cHfnqpGajdCs1jSM3DkXjGeLSNmCazv1EeI1ggTeK5wdZhF+7N+g44JI2Od3veojoaumlfg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.3 - camelcase: 6.3.0 - chalk: 4.1.2 - jest-get-type: 29.6.3 - leven: 3.1.0 - pretty-format: 29.7.0 - - /jest-watch-select-projects@2.0.0: - resolution: {integrity: sha512-j00nW4dXc2NiCW6znXgFLF9g8PJ0zP25cpQ1xRro/HU2GBfZQFZD0SoXnAlaoKkIY4MlfTMkKGbNXFpvCdjl1w==} - dependencies: - ansi-escapes: 4.3.2 - chalk: 3.0.0 - prompts: 2.4.2 - dev: false - - /jest-watch-typeahead@2.2.2(jest@29.6.4): - resolution: {integrity: sha512-+QgOFW4o5Xlgd6jGS5X37i08tuuXNW8X0CV9WNFi+3n8ExCIP+E1melYhvYLjv5fE6D0yyzk74vsSO8I6GqtvQ==} - engines: {node: ^14.17.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - jest: ^27.0.0 || ^28.0.0 || ^29.0.0 - dependencies: - ansi-escapes: 6.2.0 - chalk: 5.3.0 - jest: 29.6.4 - jest-regex-util: 29.6.3 - jest-watcher: 29.6.4 - slash: 5.1.0 - string-length: 5.0.1 - strip-ansi: 7.1.0 - dev: false - - /jest-watcher@29.6.4: - resolution: {integrity: sha512-oqUWvx6+On04ShsT00Ir9T4/FvBeEh2M9PTubgITPxDa739p4hoQweWPRGyYeaojgT0xTpZKF0Y/rSY1UgMxvQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/test-result': 29.6.4 - '@jest/types': 29.6.3 - '@types/node': 18.17.1 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - emittery: 0.13.1 - jest-util: 29.7.0 - string-length: 4.0.2 - - /jest-worker@29.6.4: - resolution: {integrity: sha512-6dpvFV4WjcWbDVGgHTWo/aupl8/LbBx2NSKfiwqf79xC/yeJjKHT1+StcKy/2KTmW16hE68ccKVOtXf+WZGz7Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@types/node': 18.17.1 - jest-util: 29.7.0 - merge-stream: 2.0.0 - supports-color: 8.1.1 - - /jest@29.6.4: - resolution: {integrity: sha512-tEFhVQFF/bzoYV1YuGyzLPZ6vlPrdfvDmmAxudA1dLEuiztqg2Rkx20vkKY32xiDROcD2KXlgZ7Cu8RPeEHRKw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 29.6.4 - '@jest/types': 29.6.3 - import-local: 3.0.2 - jest-cli: 29.6.4 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - /jiti@1.21.0: - resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} - hasBin: true - - /joi@17.11.0: - resolution: {integrity: sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==} - dependencies: - '@hapi/hoek': 9.3.0 - '@hapi/topo': 5.1.0 - '@sideway/address': 4.1.4 - '@sideway/formula': 3.0.1 - '@sideway/pinpoint': 2.0.0 - dev: false - - /js-levenshtein@1.1.6: - resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} - engines: {node: '>=0.10.0'} - dev: true - - /js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - /js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - /js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - dependencies: - argparse: 2.0.1 - - /jsbn@0.1.1: - resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - dev: false - - /jsbn@1.1.0: - resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} - dev: false - - /jsdom@22.1.0: - resolution: {integrity: sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==} - engines: {node: '>=16'} - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true - dependencies: - abab: 2.0.6 - cssstyle: 3.0.0 - data-urls: 4.0.0 - decimal.js: 10.4.3 - domexception: 4.0.0 - form-data: 4.0.0 - html-encoding-sniffer: 3.0.0 - http-proxy-agent: 5.0.0 - https-proxy-agent: 5.0.1 - is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.7 - parse5: 7.1.2 - rrweb-cssom: 0.6.0 - saxes: 6.0.0 - symbol-tree: 3.2.4 - tough-cookie: 4.1.3 - w3c-xmlserializer: 4.0.0 - webidl-conversions: 7.0.0 - whatwg-encoding: 2.0.0 - whatwg-mimetype: 3.0.0 - whatwg-url: 12.0.1 - ws: 8.18.0 - xml-name-validator: 4.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - dev: true - - /jsesc@0.5.0: - resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} - hasBin: true - dev: false - - /jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - - /jsesc@3.0.2: - resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} - engines: {node: '>=6'} - hasBin: true - dev: false - - /json-parse-better-errors@1.0.2: - resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} - dev: false - - /json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - - /json-parse-even-better-errors@3.0.1: - resolution: {integrity: sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dev: false - - /json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - /json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - dev: false - - /json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - /json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - dev: false - - /json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true - dependencies: - minimist: 1.2.8 - dev: false - - /json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - /jsonc-parser@3.2.1: - resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} - - /jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - optionalDependencies: - graceful-fs: 4.2.11 - dev: false - - /jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - dependencies: - universalify: 2.0.0 - optionalDependencies: - graceful-fs: 4.2.11 - dev: false - - /jsprim@2.0.2: - resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==} - engines: {'0': node >=0.6.0} - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 - dev: false - - /jsx-ast-utils@3.3.5: - resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} - engines: {node: '>=4.0'} - dependencies: - array-includes: 3.1.7 - array.prototype.flat: 1.3.2 - object.assign: 4.1.5 - object.values: 1.1.7 - dev: false - - /kind-of@3.2.2: - resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - dev: false - - /kind-of@5.1.0: - resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} - engines: {node: '>=0.10.0'} - dev: false - - /kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - - /kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - - /kleur@4.1.4: - resolution: {integrity: sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==} - engines: {node: '>=6'} - dev: false - - /koalas@1.0.2: - resolution: {integrity: sha512-RYhBbYaTTTHId3l6fnMZc3eGQNW6FVCqMG6AMwA5I1Mafr6AflaXeoi6x3xQuATRotGYRLk6+1ELZH4dstFNOA==} - engines: {node: '>=0.10.0'} - dev: false - - /lambda-event-mock@1.5.0: - resolution: {integrity: sha512-vx1d+vZqi7FF6B3+mAfHnY/6Tlp6BheL2ta0MJS0cIRB3Rc4I5cviHTkiJxHdE156gXx3ZjlQRJrS4puXvtrhA==} - engines: {node: '>=12.13'} - dependencies: - '@extra-number/significant-digits': 1.3.9 - clone-deep: 4.0.1 - uuid: 3.4.0 - vandium-utils: 1.2.0 - dev: true - - /lambda-leak@2.0.0: - resolution: {integrity: sha512-2c9jwUN3ZLa2GEiOhObbx2BMGQplEUCDHSIkhDtYwUjsTfiV/3jCF6ThIuEXfsvqbUK+0QpZcugIKB8YMbSevQ==} - engines: {node: '>=6.10.0'} - dev: true - - /lambda-tester@4.0.1: - resolution: {integrity: sha512-ft6XHk84B6/dYEzyI3anKoGWz08xQ5allEHiFYDUzaYTymgVK7tiBkCEbuWx+MFvH7OpFNsJXVtjXm0X8iH3Iw==} - engines: {node: '>=10.0'} - dependencies: - app-root-path: 3.1.0 - dotenv: 8.6.0 - dotenv-json: 1.0.0 - lambda-event-mock: 1.5.0 - lambda-leak: 2.0.0 - semver: 6.3.1 - uuid: 3.4.0 - vandium-utils: 2.0.0 - dev: true - - /language-subtag-registry@0.3.22: - resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} - dev: false - - /language-tags@1.0.9: - resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} - engines: {node: '>=0.10'} - dependencies: - language-subtag-registry: 0.3.22 - dev: false - - /lazy-ass@1.6.0: - resolution: {integrity: sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==} - engines: {node: '> 0.8'} - dev: false - - /lazy-cache@2.0.2: - resolution: {integrity: sha512-7vp2Acd2+Kz4XkzxGxaB1FWOi8KjWIWsgdfD5MCb86DWvlLqhRPM+d6Pro3iNEL5VT9mstz5hKAlcd+QR6H3aA==} - engines: {node: '>=0.10.0'} - dependencies: - set-getter: 0.1.1 - dev: false - - /leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - - /levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - /lilconfig@2.1.0: - resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} - engines: {node: '>=10'} - - /lilconfig@3.0.0: - resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} - engines: {node: '>=14'} - - /lines-and-columns@1.1.6: - resolution: {integrity: sha512-8ZmlJFVK9iCmtLz19HpSsR8HaAMWBT284VMNednLwlIMDP2hJDCIhUp0IZ2xUcZ+Ob6BM0VvCSJwzASDM45NLQ==} - - /listr2@3.14.0(enquirer@2.3.6): - resolution: {integrity: sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==} - engines: {node: '>=10.0.0'} - peerDependencies: - enquirer: '>= 2.3.0 < 3' - peerDependenciesMeta: - enquirer: - optional: true - dependencies: - cli-truncate: 2.1.0 - colorette: 2.0.16 - enquirer: 2.3.6 - log-update: 4.0.0 - p-map: 4.0.0 - rfdc: 1.3.0 - rxjs: 7.8.1 - through: 2.3.8 - wrap-ansi: 7.0.0 - dev: false - - /load-json-file@4.0.0: - resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} - engines: {node: '>=4'} - dependencies: - graceful-fs: 4.2.11 - parse-json: 4.0.0 - pify: 3.0.0 - strip-bom: 3.0.0 - dev: false - - /load-yaml-file@0.2.0: - resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} - engines: {node: '>=6'} - dependencies: - graceful-fs: 4.2.11 - js-yaml: 3.14.1 - pify: 4.0.1 - strip-bom: 3.0.0 - dev: false - - /loader-utils@3.2.1: - resolution: {integrity: sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==} - engines: {node: '>= 12.13.0'} - dev: false - - /local-pkg@0.5.0: - resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} - engines: {node: '>=14'} - dependencies: - mlly: 1.5.0 - pkg-types: 1.0.3 - dev: false - - /locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - dependencies: - p-locate: 4.1.0 - - /locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - dependencies: - p-locate: 5.0.0 - - /lodash.camelcase@4.3.0: - resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - dev: false - - /lodash.debounce@4.0.8: - resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - dev: false - - /lodash.deburr@4.1.0: - resolution: {integrity: sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==} - dev: false - - /lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - /lodash.once@4.1.1: - resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} - dev: false - - /lodash.startcase@4.4.0: - resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} - dev: false - - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - /log-ok@0.1.1: - resolution: {integrity: sha512-cc8VrkS6C+9TFuYAwuHpshrcrGRAv7d0tUJ0GdM72ZBlKXtlgjUZF84O+OhQUdiVHoF7U/nVxwpjOdwUJ8d3Vg==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-green: 0.1.1 - success-symbol: 0.1.0 - dev: false - - /log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - - /log-update@4.0.0: - resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} - engines: {node: '>=10'} - dependencies: - ansi-escapes: 4.3.2 - cli-cursor: 3.1.0 - slice-ansi: 4.0.0 - wrap-ansi: 6.2.0 - dev: false - - /log-update@5.0.1: - resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - ansi-escapes: 5.0.0 - cli-cursor: 4.0.0 - slice-ansi: 5.0.0 - strip-ansi: 7.1.0 - wrap-ansi: 8.1.0 - dev: false - - /log-utils@0.2.1: - resolution: {integrity: sha512-udyegKoMz9eGfpKAX//Khy7sVAZ8b1F7oLDnepZv/1/y8xTvsyPgqQrM94eG8V0vcc2BieYI2kVW4+aa6m+8Qw==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-colors: 0.2.0 - error-symbol: 0.1.0 - info-symbol: 0.1.0 - log-ok: 0.1.1 - success-symbol: 0.1.0 - time-stamp: 1.1.0 - warning-symbol: 0.1.0 - dev: false - - /longest-streak@3.0.0: - resolution: {integrity: sha512-XhUjWR5CFaQ03JOP+iSDS9koy8T5jfoImCZ4XprElw3BXsSk4MpVYOLw/6LTDKZhO13PlAXnB5gS4MHQTpkSOw==} - dev: false - - /loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - dependencies: - js-tokens: 4.0.0 - - /lru-cache@10.2.0: - resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} - engines: {node: 14 || >=16.14} - - /lru-cache@4.1.5: - resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} - dependencies: - pseudomap: 1.0.2 - yallist: 2.1.2 - dev: false - - /lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - dependencies: - yallist: 3.1.1 - - /lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - dependencies: - yallist: 4.0.0 - - /lru-cache@7.18.3: - resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} - engines: {node: '>=12'} - dev: false - - /lz-string@1.5.0: - resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} - hasBin: true - - /magic-string@0.25.9: - resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} - dependencies: - sourcemap-codec: 1.4.8 - - /magic-string@0.27.0: - resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 - dev: false - - /make-dir@3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} - dependencies: - semver: 6.3.1 - - /makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} - dependencies: - tmpl: 1.0.5 - - /map-obj@1.0.1: - resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} - engines: {node: '>=0.10.0'} - dev: false - - /map-obj@4.3.0: - resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} - engines: {node: '>=8'} - dev: false - - /map-visit@1.0.0: - resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} - engines: {node: '>=0.10.0'} - dependencies: - object-visit: 1.0.1 - dev: false - - /markdown-extensions@1.1.1: - resolution: {integrity: sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==} - engines: {node: '>=0.10.0'} - dev: false - - /markdown-extensions@2.0.0: - resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} - engines: {node: '>=16'} - dev: false - - /markdown-table@3.0.2: - resolution: {integrity: sha512-y8j3a5/DkJCmS5x4dMCQL+OR0+2EAq3DOtio1COSHsmW2BGXnNCK3v12hJt1LrUz5iZH5g0LmuYOjDdI+czghA==} - dev: false - - /mdast-util-definitions@5.1.2: - resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==} - dependencies: - '@types/mdast': 3.0.10 - '@types/unist': 2.0.6 - unist-util-visit: 4.1.1 - dev: false - - /mdast-util-find-and-replace@2.2.0: - resolution: {integrity: sha512-bz8hUWkMX7UcasORORcyBEsTKJ+dBiFwRPrm43hHC9NMRylIMLbfO5rwfeCN+UtY4AAi7s8WqXftb9eX6ZsqCg==} - dependencies: - escape-string-regexp: 5.0.0 - unist-util-is: 5.1.1 - unist-util-visit-parents: 5.1.1 - dev: false - - /mdast-util-from-markdown@0.8.5: - resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} - dependencies: - '@types/mdast': 3.0.10 - mdast-util-to-string: 2.0.0 - micromark: 2.11.4 - parse-entities: 2.0.0 - unist-util-stringify-position: 2.0.3 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-from-markdown@1.3.1: - resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==} - dependencies: - '@types/mdast': 3.0.10 - '@types/unist': 2.0.6 - decode-named-character-reference: 1.0.2 - mdast-util-to-string: 3.1.0 - micromark: 3.0.5 - micromark-util-decode-numeric-character-reference: 1.0.0 - micromark-util-decode-string: 1.0.0 - micromark-util-normalize-identifier: 1.0.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - unist-util-stringify-position: 3.0.0 - uvu: 0.5.3 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-from-markdown@2.0.0: - resolution: {integrity: sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==} - dependencies: - '@types/mdast': 4.0.3 - '@types/unist': 3.0.2 - decode-named-character-reference: 1.0.2 - devlop: 1.1.0 - mdast-util-to-string: 4.0.0 - micromark: 4.0.0 - micromark-util-decode-numeric-character-reference: 2.0.1 - micromark-util-decode-string: 2.0.0 - micromark-util-normalize-identifier: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - unist-util-stringify-position: 4.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-frontmatter@1.0.0: - resolution: {integrity: sha512-7itKvp0arEVNpCktOET/eLFAYaZ+0cNjVtFtIPxgQ5tV+3i+D4SDDTjTzPWl44LT59PC+xdx+glNTawBdF98Mw==} - dependencies: - micromark-extension-frontmatter: 1.0.0 - dev: false - - /mdast-util-gfm-autolink-literal@1.0.2: - resolution: {integrity: sha512-FzopkOd4xTTBeGXhXSBU0OCDDh5lUj2rd+HQqG92Ld+jL4lpUfgX2AT2OHAVP9aEeDKp7G92fuooSZcYJA3cRg==} - dependencies: - '@types/mdast': 3.0.10 - ccount: 2.0.1 - mdast-util-find-and-replace: 2.2.0 - micromark-util-character: 1.1.0 - dev: false - - /mdast-util-gfm-footnote@1.0.1: - resolution: {integrity: sha512-p+PrYlkw9DeCRkTVw1duWqPRHX6Ywh2BNKJQcZbCwAuP/59B0Lk9kakuAd7KbQprVO4GzdW8eS5++A9PUSqIyw==} - dependencies: - '@types/mdast': 3.0.10 - mdast-util-to-markdown: 1.3.0 - micromark-util-normalize-identifier: 1.0.0 - dev: false - - /mdast-util-gfm-strikethrough@1.0.1: - resolution: {integrity: sha512-zKJbEPe+JP6EUv0mZ0tQUyLQOC+FADt0bARldONot/nefuISkaZFlmVK4tU6JgfyZGrky02m/I6PmehgAgZgqg==} - dependencies: - '@types/mdast': 3.0.10 - mdast-util-to-markdown: 1.3.0 - dev: false - - /mdast-util-gfm-table@1.0.4: - resolution: {integrity: sha512-aEuoPwZyP4iIMkf2cLWXxx3EQ6Bmh2yKy9MVCg4i6Sd3cX80dcLEfXO/V4ul3pGH9czBK4kp+FAl+ZHmSUt9/w==} - dependencies: - markdown-table: 3.0.2 - mdast-util-from-markdown: 1.3.1 - mdast-util-to-markdown: 1.3.0 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-gfm-task-list-item@1.0.1: - resolution: {integrity: sha512-KZ4KLmPdABXOsfnM6JHUIjxEvcx2ulk656Z/4Balw071/5qgnhz+H1uGtf2zIGnrnvDC8xR4Fj9uKbjAFGNIeA==} - dependencies: - '@types/mdast': 3.0.10 - mdast-util-to-markdown: 1.3.0 - dev: false - - /mdast-util-gfm@2.0.1: - resolution: {integrity: sha512-42yHBbfWIFisaAfV1eixlabbsa6q7vHeSPY+cg+BBjX51M8xhgMacqH9g6TftB/9+YkcI0ooV4ncfrJslzm/RQ==} - dependencies: - mdast-util-from-markdown: 1.3.1 - mdast-util-gfm-autolink-literal: 1.0.2 - mdast-util-gfm-footnote: 1.0.1 - mdast-util-gfm-strikethrough: 1.0.1 - mdast-util-gfm-table: 1.0.4 - mdast-util-gfm-task-list-item: 1.0.1 - mdast-util-to-markdown: 1.3.0 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-mdx-expression@1.3.2: - resolution: {integrity: sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA==} - dependencies: - '@types/estree-jsx': 1.0.0 - '@types/hast': 2.3.10 - '@types/mdast': 3.0.10 - mdast-util-from-markdown: 1.3.1 - mdast-util-to-markdown: 1.3.0 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-mdx-expression@2.0.0: - resolution: {integrity: sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==} - dependencies: - '@types/estree-jsx': 1.0.0 - '@types/hast': 3.0.3 - '@types/mdast': 4.0.3 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.0 - mdast-util-to-markdown: 2.1.0 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-mdx-jsx@2.1.4: - resolution: {integrity: sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA==} - dependencies: - '@types/estree-jsx': 1.0.0 - '@types/hast': 2.3.10 - '@types/mdast': 3.0.10 - '@types/unist': 2.0.6 - ccount: 2.0.1 - mdast-util-from-markdown: 1.3.1 - mdast-util-to-markdown: 1.3.0 - parse-entities: 4.0.0 - stringify-entities: 4.0.1 - unist-util-remove-position: 4.0.2 - unist-util-stringify-position: 3.0.0 - vfile-message: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-mdx-jsx@3.0.0: - resolution: {integrity: sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==} - dependencies: - '@types/estree-jsx': 1.0.0 - '@types/hast': 3.0.3 - '@types/mdast': 4.0.3 - '@types/unist': 3.0.2 - ccount: 2.0.1 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.0 - mdast-util-to-markdown: 2.1.0 - parse-entities: 4.0.0 - stringify-entities: 4.0.1 - unist-util-remove-position: 5.0.0 - unist-util-stringify-position: 4.0.0 - vfile-message: 4.0.2 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-mdx@2.0.1: - resolution: {integrity: sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw==} - dependencies: - mdast-util-from-markdown: 1.3.1 - mdast-util-mdx-expression: 1.3.2 - mdast-util-mdx-jsx: 2.1.4 - mdast-util-mdxjs-esm: 1.3.1 - mdast-util-to-markdown: 1.3.0 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-mdx@3.0.0: - resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} - dependencies: - mdast-util-from-markdown: 2.0.0 - mdast-util-mdx-expression: 2.0.0 - mdast-util-mdx-jsx: 3.0.0 - mdast-util-mdxjs-esm: 2.0.1 - mdast-util-to-markdown: 2.1.0 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-mdxjs-esm@1.3.1: - resolution: {integrity: sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w==} - dependencies: - '@types/estree-jsx': 1.0.0 - '@types/hast': 2.3.10 - '@types/mdast': 3.0.10 - mdast-util-from-markdown: 1.3.1 - mdast-util-to-markdown: 1.3.0 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-mdxjs-esm@2.0.1: - resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} - dependencies: - '@types/estree-jsx': 1.0.0 - '@types/hast': 3.0.3 - '@types/mdast': 4.0.3 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.0 - mdast-util-to-markdown: 2.1.0 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-phrasing@4.0.0: - resolution: {integrity: sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==} - dependencies: - '@types/mdast': 4.0.3 - unist-util-is: 6.0.0 - dev: false - - /mdast-util-to-hast@12.3.0: - resolution: {integrity: sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==} - dependencies: - '@types/hast': 2.3.10 - '@types/mdast': 3.0.10 - mdast-util-definitions: 5.1.2 - micromark-util-sanitize-uri: 1.2.0 - trim-lines: 3.0.1 - unist-util-generated: 2.0.1 - unist-util-position: 4.0.4 - unist-util-visit: 4.1.1 - dev: false - - /mdast-util-to-hast@13.0.2: - resolution: {integrity: sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==} - dependencies: - '@types/hast': 3.0.3 - '@types/mdast': 4.0.3 - '@ungap/structured-clone': 1.2.0 - devlop: 1.1.0 - micromark-util-sanitize-uri: 2.0.0 - trim-lines: 3.0.1 - unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 - dev: false - - /mdast-util-to-markdown@1.3.0: - resolution: {integrity: sha512-6tUSs4r+KK4JGTTiQ7FfHmVOaDrLQJPmpjD6wPMlHGUVXoG9Vjc3jIeP+uyBWRf8clwB2blM+W7+KrlMYQnftA==} - dependencies: - '@types/mdast': 3.0.10 - '@types/unist': 2.0.6 - longest-streak: 3.0.0 - mdast-util-to-string: 3.1.0 - micromark-util-decode-string: 1.0.0 - unist-util-visit: 4.1.1 - zwitch: 2.0.2 - dev: false - - /mdast-util-to-markdown@2.1.0: - resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} - dependencies: - '@types/mdast': 4.0.3 - '@types/unist': 3.0.2 - longest-streak: 3.0.0 - mdast-util-phrasing: 4.0.0 - mdast-util-to-string: 4.0.0 - micromark-util-decode-string: 2.0.0 - unist-util-visit: 5.0.0 - zwitch: 2.0.2 - dev: false - - /mdast-util-to-string@2.0.0: - resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} - dev: false - - /mdast-util-to-string@3.1.0: - resolution: {integrity: sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==} - dev: false - - /mdast-util-to-string@4.0.0: - resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} - dependencies: - '@types/mdast': 4.0.3 - dev: false - - /media-query-parser@2.0.2: - resolution: {integrity: sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==} - dependencies: - '@babel/runtime': 7.23.9 - - /media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - - /memorystream@0.3.1: - resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} - engines: {node: '>= 0.10.0'} - dev: false - - /meow@6.1.1: - resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==} - engines: {node: '>=8'} - dependencies: - '@types/minimist': 1.2.2 - camelcase-keys: 6.2.2 - decamelize-keys: 1.1.0 - hard-rejection: 2.1.0 - minimist-options: 4.1.0 - normalize-package-data: 2.5.0 - read-pkg-up: 7.0.1 - redent: 3.0.0 - trim-newlines: 3.0.1 - type-fest: 0.13.1 - yargs-parser: 18.1.3 - dev: false - - /merge-descriptors@1.0.3: - resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} - - /merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - - /merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - /methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} - - /micromark-core-commonmark@1.0.1: - resolution: {integrity: sha512-vEOw8hcQ3nwHkKKNIyP9wBi8M50zjNajtmI+cCUWcVfJS+v5/3WCh4PLKf7PPRZFUutjzl4ZjlHwBWUKfb/SkA==} - dependencies: - micromark-factory-destination: 1.0.0 - micromark-factory-label: 1.0.0 - micromark-factory-space: 1.0.0 - micromark-factory-title: 1.0.0 - micromark-factory-whitespace: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-chunked: 1.0.0 - micromark-util-classify-character: 1.0.0 - micromark-util-html-tag-name: 1.0.0 - micromark-util-normalize-identifier: 1.0.0 - micromark-util-resolve-all: 1.0.0 - micromark-util-subtokenize: 1.0.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - parse-entities: 3.0.0 - dev: false - - /micromark-core-commonmark@2.0.0: - resolution: {integrity: sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==} - dependencies: - decode-named-character-reference: 1.0.2 - devlop: 1.1.0 - micromark-factory-destination: 2.0.0 - micromark-factory-label: 2.0.0 - micromark-factory-space: 2.0.0 - micromark-factory-title: 2.0.0 - micromark-factory-whitespace: 2.0.0 - micromark-util-character: 2.0.1 - micromark-util-chunked: 2.0.0 - micromark-util-classify-character: 2.0.0 - micromark-util-html-tag-name: 2.0.0 - micromark-util-normalize-identifier: 2.0.0 - micromark-util-resolve-all: 2.0.0 - micromark-util-subtokenize: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - dev: false - - /micromark-extension-frontmatter@1.0.0: - resolution: {integrity: sha512-EXjmRnupoX6yYuUJSQhrQ9ggK0iQtQlpi6xeJzVD5xscyAI+giqco5fdymayZhJMbIFecjnE2yz85S9NzIgQpg==} - dependencies: - fault: 2.0.0 - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.0 - dev: false - - /micromark-extension-gfm-autolink-literal@1.0.3: - resolution: {integrity: sha512-i3dmvU0htawfWED8aHMMAzAVp/F0Z+0bPh3YrbTPPL1v4YAlCZpy5rBO5p0LPYiZo0zFVkoYh7vDU7yQSiCMjg==} - dependencies: - micromark-util-character: 1.1.0 - micromark-util-sanitize-uri: 1.2.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - uvu: 0.5.3 - dev: false - - /micromark-extension-gfm-footnote@1.0.4: - resolution: {integrity: sha512-E/fmPmDqLiMUP8mLJ8NbJWJ4bTw6tS+FEQS8CcuDtZpILuOb2kjLqPEeAePF1djXROHXChM/wPJw0iS4kHCcIg==} - dependencies: - micromark-core-commonmark: 1.0.1 - micromark-factory-space: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-normalize-identifier: 1.0.0 - micromark-util-sanitize-uri: 1.2.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - uvu: 0.5.3 - dev: false - - /micromark-extension-gfm-strikethrough@1.0.4: - resolution: {integrity: sha512-/vjHU/lalmjZCT5xt7CcHVJGq8sYRm80z24qAKXzaHzem/xsDYb2yLL+NNVbYvmpLx3O7SYPuGL5pzusL9CLIQ==} - dependencies: - micromark-util-chunked: 1.0.0 - micromark-util-classify-character: 1.0.0 - micromark-util-resolve-all: 1.0.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - uvu: 0.5.3 - dev: false - - /micromark-extension-gfm-table@1.0.5: - resolution: {integrity: sha512-xAZ8J1X9W9K3JTJTUL7G6wSKhp2ZYHrFk5qJgY/4B33scJzE2kpfRL6oiw/veJTbt7jiM/1rngLlOKPWr1G+vg==} - dependencies: - micromark-factory-space: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - uvu: 0.5.3 - dev: false - - /micromark-extension-gfm-tagfilter@1.0.1: - resolution: {integrity: sha512-Ty6psLAcAjboRa/UKUbbUcwjVAv5plxmpUTy2XC/3nJFL37eHej8jrHrRzkqcpipJliuBH30DTs7+3wqNcQUVA==} - dependencies: - micromark-util-types: 1.0.1 - dev: false - - /micromark-extension-gfm-task-list-item@1.0.3: - resolution: {integrity: sha512-PpysK2S1Q/5VXi72IIapbi/jliaiOFzv7THH4amwXeYXLq3l1uo8/2Be0Ac1rEwK20MQEsGH2ltAZLNY2KI/0Q==} - dependencies: - micromark-factory-space: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - uvu: 0.5.3 - dev: false - - /micromark-extension-gfm@2.0.1: - resolution: {integrity: sha512-p2sGjajLa0iYiGQdT0oelahRYtMWvLjy8J9LOCxzIQsllMCGLbsLW+Nc+N4vi02jcRJvedVJ68cjelKIO6bpDA==} - dependencies: - micromark-extension-gfm-autolink-literal: 1.0.3 - micromark-extension-gfm-footnote: 1.0.4 - micromark-extension-gfm-strikethrough: 1.0.4 - micromark-extension-gfm-table: 1.0.5 - micromark-extension-gfm-tagfilter: 1.0.1 - micromark-extension-gfm-task-list-item: 1.0.3 - micromark-util-combine-extensions: 1.0.0 - micromark-util-types: 1.0.1 - dev: false - - /micromark-extension-mdx-expression@1.0.8: - resolution: {integrity: sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw==} - dependencies: - '@types/estree': 1.0.6 - micromark-factory-mdx-expression: 1.0.9 - micromark-factory-space: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-events-to-acorn: 1.2.3 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - uvu: 0.5.3 - dev: false - - /micromark-extension-mdx-expression@3.0.0: - resolution: {integrity: sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==} - dependencies: - '@types/estree': 1.0.6 - devlop: 1.1.0 - micromark-factory-mdx-expression: 2.0.1 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.0.1 - micromark-util-events-to-acorn: 2.0.2 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - dev: false - - /micromark-extension-mdx-jsx@1.0.5: - resolution: {integrity: sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA==} - dependencies: - '@types/acorn': 4.0.6 - '@types/estree': 1.0.6 - estree-util-is-identifier-name: 2.1.0 - micromark-factory-mdx-expression: 1.0.9 - micromark-factory-space: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - uvu: 0.5.3 - vfile-message: 3.0.2 - dev: false - - /micromark-extension-mdx-jsx@3.0.0: - resolution: {integrity: sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==} - dependencies: - '@types/acorn': 4.0.6 - '@types/estree': 1.0.6 - devlop: 1.1.0 - estree-util-is-identifier-name: 3.0.0 - micromark-factory-mdx-expression: 2.0.1 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.0.1 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - vfile-message: 4.0.2 - dev: false - - /micromark-extension-mdx-md@1.0.1: - resolution: {integrity: sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA==} - dependencies: - micromark-util-types: 1.0.1 - dev: false - - /micromark-extension-mdx-md@2.0.0: - resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} - dependencies: - micromark-util-types: 2.0.0 - dev: false - - /micromark-extension-mdxjs-esm@1.0.5: - resolution: {integrity: sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w==} - dependencies: - '@types/estree': 1.0.6 - micromark-core-commonmark: 1.0.1 - micromark-util-character: 1.1.0 - micromark-util-events-to-acorn: 1.2.3 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - unist-util-position-from-estree: 1.1.2 - uvu: 0.5.3 - vfile-message: 3.0.2 - dev: false - - /micromark-extension-mdxjs-esm@3.0.0: - resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} - dependencies: - '@types/estree': 1.0.6 - devlop: 1.1.0 - micromark-core-commonmark: 2.0.0 - micromark-util-character: 2.0.1 - micromark-util-events-to-acorn: 2.0.2 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - unist-util-position-from-estree: 2.0.0 - vfile-message: 4.0.2 - dev: false - - /micromark-extension-mdxjs@1.0.1: - resolution: {integrity: sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q==} - dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) - micromark-extension-mdx-expression: 1.0.8 - micromark-extension-mdx-jsx: 1.0.5 - micromark-extension-mdx-md: 1.0.1 - micromark-extension-mdxjs-esm: 1.0.5 - micromark-util-combine-extensions: 1.0.0 - micromark-util-types: 1.0.1 - dev: false - - /micromark-extension-mdxjs@3.0.0: - resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} - dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) - micromark-extension-mdx-expression: 3.0.0 - micromark-extension-mdx-jsx: 3.0.0 - micromark-extension-mdx-md: 2.0.0 - micromark-extension-mdxjs-esm: 3.0.0 - micromark-util-combine-extensions: 2.0.0 - micromark-util-types: 2.0.0 - dev: false - - /micromark-factory-destination@1.0.0: - resolution: {integrity: sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==} - dependencies: - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - dev: false - - /micromark-factory-destination@2.0.0: - resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} - dependencies: - micromark-util-character: 2.0.1 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - dev: false - - /micromark-factory-label@1.0.0: - resolution: {integrity: sha512-XWEucVZb+qBCe2jmlOnWr6sWSY6NHx+wtpgYFsm4G+dufOf6tTQRRo0bdO7XSlGPu5fyjpJenth6Ksnc5Mwfww==} - dependencies: - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - dev: false - - /micromark-factory-label@2.0.0: - resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} - dependencies: - devlop: 1.1.0 - micromark-util-character: 2.0.1 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - dev: false - - /micromark-factory-mdx-expression@1.0.9: - resolution: {integrity: sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==} - dependencies: - '@types/estree': 1.0.6 - micromark-util-character: 1.1.0 - micromark-util-events-to-acorn: 1.2.3 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - unist-util-position-from-estree: 1.1.2 - uvu: 0.5.3 - vfile-message: 3.0.2 - dev: false - - /micromark-factory-mdx-expression@2.0.1: - resolution: {integrity: sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==} - dependencies: - '@types/estree': 1.0.6 - devlop: 1.1.0 - micromark-util-character: 2.0.1 - micromark-util-events-to-acorn: 2.0.2 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - unist-util-position-from-estree: 2.0.0 - vfile-message: 4.0.2 - dev: false - - /micromark-factory-space@1.0.0: - resolution: {integrity: sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==} - dependencies: - micromark-util-character: 1.1.0 - micromark-util-types: 1.0.1 - dev: false - - /micromark-factory-space@2.0.0: - resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} - dependencies: - micromark-util-character: 2.0.1 - micromark-util-types: 2.0.0 - dev: false - - /micromark-factory-title@1.0.0: - resolution: {integrity: sha512-flvC7Gx0dWVWorXuBl09Cr3wB5FTuYec8pMGVySIp2ZlqTcIjN/lFohZcP0EG//krTptm34kozHk7aK/CleCfA==} - dependencies: - micromark-factory-space: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - dev: false - - /micromark-factory-title@2.0.0: - resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==} - dependencies: - micromark-factory-space: 2.0.0 - micromark-util-character: 2.0.1 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - dev: false - - /micromark-factory-whitespace@1.0.0: - resolution: {integrity: sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==} - dependencies: - micromark-factory-space: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - dev: false - - /micromark-factory-whitespace@2.0.0: - resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} - dependencies: - micromark-factory-space: 2.0.0 - micromark-util-character: 2.0.1 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - dev: false - - /micromark-util-character@1.1.0: - resolution: {integrity: sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==} - dependencies: - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - dev: false - - /micromark-util-character@2.0.1: - resolution: {integrity: sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==} - dependencies: - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - dev: false - - /micromark-util-chunked@1.0.0: - resolution: {integrity: sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==} - dependencies: - micromark-util-symbol: 1.0.0 - dev: false - - /micromark-util-chunked@2.0.0: - resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} - dependencies: - micromark-util-symbol: 2.0.0 - dev: false - - /micromark-util-classify-character@1.0.0: - resolution: {integrity: sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==} - dependencies: - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - dev: false - - /micromark-util-classify-character@2.0.0: - resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==} - dependencies: - micromark-util-character: 2.0.1 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - dev: false - - /micromark-util-combine-extensions@1.0.0: - resolution: {integrity: sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==} - dependencies: - micromark-util-chunked: 1.0.0 - micromark-util-types: 1.0.1 - dev: false - - /micromark-util-combine-extensions@2.0.0: - resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==} - dependencies: - micromark-util-chunked: 2.0.0 - micromark-util-types: 2.0.0 - dev: false - - /micromark-util-decode-numeric-character-reference@1.0.0: - resolution: {integrity: sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==} - dependencies: - micromark-util-symbol: 1.0.0 - dev: false - - /micromark-util-decode-numeric-character-reference@2.0.1: - resolution: {integrity: sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==} - dependencies: - micromark-util-symbol: 2.0.0 - dev: false - - /micromark-util-decode-string@1.0.0: - resolution: {integrity: sha512-4g5UJ8P/J8wuRKUXCcB7udQuOBXpLyvBQSLSuznfBLCG+thKG6UTwFnXfHkrr/1wddprkUbPatCzxDjrJ+5zDg==} - dependencies: - micromark-util-character: 1.1.0 - micromark-util-decode-numeric-character-reference: 1.0.0 - parse-entities: 3.0.0 - dev: false - - /micromark-util-decode-string@2.0.0: - resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==} - dependencies: - decode-named-character-reference: 1.0.2 - micromark-util-character: 2.0.1 - micromark-util-decode-numeric-character-reference: 2.0.1 - micromark-util-symbol: 2.0.0 - dev: false - - /micromark-util-encode@1.0.0: - resolution: {integrity: sha512-cJpFVM768h6zkd8qJ1LNRrITfY4gwFt+tziPcIf71Ui8yFzY9wG3snZQqiWVq93PG4Sw6YOtcNiKJfVIs9qfGg==} - dev: false - - /micromark-util-encode@2.0.0: - resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} - dev: false - - /micromark-util-events-to-acorn@1.2.3: - resolution: {integrity: sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w==} - dependencies: - '@types/acorn': 4.0.6 - '@types/estree': 1.0.6 - '@types/unist': 2.0.6 - estree-util-visit: 1.2.1 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - uvu: 0.5.3 - vfile-message: 3.0.2 - dev: false - - /micromark-util-events-to-acorn@2.0.2: - resolution: {integrity: sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==} - dependencies: - '@types/acorn': 4.0.6 - '@types/estree': 1.0.6 - '@types/unist': 3.0.2 - devlop: 1.1.0 - estree-util-visit: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - vfile-message: 4.0.2 - dev: false - - /micromark-util-html-tag-name@1.0.0: - resolution: {integrity: sha512-NenEKIshW2ZI/ERv9HtFNsrn3llSPZtY337LID/24WeLqMzeZhBEE6BQ0vS2ZBjshm5n40chKtJ3qjAbVV8S0g==} - dev: false - - /micromark-util-html-tag-name@2.0.0: - resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==} - dev: false - - /micromark-util-normalize-identifier@1.0.0: - resolution: {integrity: sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==} - dependencies: - micromark-util-symbol: 1.0.0 - dev: false - - /micromark-util-normalize-identifier@2.0.0: - resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==} - dependencies: - micromark-util-symbol: 2.0.0 - dev: false - - /micromark-util-resolve-all@1.0.0: - resolution: {integrity: sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==} - dependencies: - micromark-util-types: 1.0.1 - dev: false - - /micromark-util-resolve-all@2.0.0: - resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==} - dependencies: - micromark-util-types: 2.0.0 - dev: false - - /micromark-util-sanitize-uri@1.2.0: - resolution: {integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==} - dependencies: - micromark-util-character: 1.1.0 - micromark-util-encode: 1.0.0 - micromark-util-symbol: 1.0.0 - dev: false - - /micromark-util-sanitize-uri@2.0.0: - resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} - dependencies: - micromark-util-character: 2.0.1 - micromark-util-encode: 2.0.0 - micromark-util-symbol: 2.0.0 - dev: false - - /micromark-util-subtokenize@1.0.0: - resolution: {integrity: sha512-EsnG2qscmcN5XhkqQBZni/4oQbLFjz9yk3ZM/P8a3YUjwV6+6On2wehr1ALx0MxK3+XXXLTzuBKHDFeDFYRdgQ==} - dependencies: - micromark-util-chunked: 1.0.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - dev: false - - /micromark-util-subtokenize@2.0.0: - resolution: {integrity: sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==} - dependencies: - devlop: 1.1.0 - micromark-util-chunked: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - dev: false - - /micromark-util-symbol@1.0.0: - resolution: {integrity: sha512-NZA01jHRNCt4KlOROn8/bGi6vvpEmlXld7EHcRH+aYWUfL3Wc8JLUNNlqUMKa0hhz6GrpUWsHtzPmKof57v0gQ==} - dev: false - - /micromark-util-symbol@2.0.0: - resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} - dev: false - - /micromark-util-types@1.0.1: - resolution: {integrity: sha512-UT0ylWEEy80RFYzK9pEaugTqaxoD/j0Y9WhHpSyitxd99zjoQz7JJ+iKuhPAgOW2MiPSUAx+c09dcqokeyaROA==} - dev: false - - /micromark-util-types@2.0.0: - resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} - dev: false - - /micromark@2.11.4: - resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} - dependencies: - debug: 4.4.0(supports-color@8.1.1) - parse-entities: 2.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /micromark@3.0.5: - resolution: {integrity: sha512-QfjERBnPw0G9mxhOCkkbRP0n8SX8lIBLrEKeEVceviUukqVMv3hWE4AgNTOK/W6GWqtPvvIHg2Apl3j1Dxm6aQ==} - dependencies: - '@types/debug': 4.1.8 - debug: 4.4.0(supports-color@8.1.1) - micromark-core-commonmark: 1.0.1 - micromark-factory-space: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-chunked: 1.0.0 - micromark-util-combine-extensions: 1.0.0 - micromark-util-decode-numeric-character-reference: 1.0.0 - micromark-util-encode: 1.0.0 - micromark-util-normalize-identifier: 1.0.0 - micromark-util-resolve-all: 1.0.0 - micromark-util-sanitize-uri: 1.2.0 - micromark-util-subtokenize: 1.0.0 - micromark-util-symbol: 1.0.0 - micromark-util-types: 1.0.1 - parse-entities: 3.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /micromark@4.0.0: - resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} - dependencies: - '@types/debug': 4.1.8 - debug: 4.4.0(supports-color@8.1.1) - decode-named-character-reference: 1.0.2 - devlop: 1.1.0 - micromark-core-commonmark: 2.0.0 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.0.1 - micromark-util-chunked: 2.0.0 - micromark-util-combine-extensions: 2.0.0 - micromark-util-decode-numeric-character-reference: 2.0.1 - micromark-util-encode: 2.0.0 - micromark-util-normalize-identifier: 2.0.0 - micromark-util-resolve-all: 2.0.0 - micromark-util-sanitize-uri: 2.0.0 - micromark-util-subtokenize: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - - /mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - - /mime@2.6.0: - resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} - engines: {node: '>=4.0.0'} - hasBin: true - - /mime@3.0.0: - resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} - engines: {node: '>=10.0.0'} - hasBin: true - - /mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - /min-indent@1.0.1: - resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} - engines: {node: '>=4'} - - /miniflare@3.20240821.1: - resolution: {integrity: sha512-81qdiryDG7VXzZuoa0EwhkaIYYrn7+StRIrd/2i7SPqPUNICUBjbhFFKqTnvE1+fqIPPB6l8ShKFaFvmnZOASg==} - engines: {node: '>=16.13'} - hasBin: true - dependencies: - '@cspotcode/source-map-support': 0.8.1 - acorn: 8.11.3 - acorn-walk: 8.3.2 - capnp-ts: 0.7.0 - exit-hook: 2.2.1 - glob-to-regexp: 0.4.1 - stoppable: 1.1.0 - undici: 5.28.4 - workerd: 1.20240821.1 - ws: 8.18.0 - youch: 3.3.3 - zod: 3.22.4 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.11 - - /minimatch@5.1.0: - resolution: {integrity: sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==} - engines: {node: '>=10'} - dependencies: - brace-expansion: 2.0.1 - dev: false - - /minimatch@8.0.4: - resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - brace-expansion: 2.0.1 - dev: false - - /minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - brace-expansion: 2.0.1 - - /minimist-options@4.1.0: - resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} - engines: {node: '>= 6'} - dependencies: - arrify: 1.0.1 - is-plain-obj: 1.1.0 - kind-of: 6.0.3 - dev: false - - /minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: false - - /minipass-collect@1.0.2: - resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.6 - dev: false - - /minipass-flush@1.0.5: - resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.6 - dev: false - - /minipass-pipeline@1.2.4: - resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} - engines: {node: '>=8'} - dependencies: - minipass: 3.3.6 - dev: false - - /minipass@3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} - dependencies: - yallist: 4.0.0 - dev: false - - /minipass@4.2.8: - resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} - engines: {node: '>=8'} - dev: false - - /minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - dev: false - - /minipass@7.0.4: - resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} - engines: {node: '>=16 || 14 >=14.17'} - - /minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.6 - yallist: 4.0.0 - dev: false - - /mixin-object@2.0.1: - resolution: {integrity: sha512-ALGF1Jt9ouehcaXaHhn6t1yGWRqGaHkPFndtFVHfZXOvkIZ/yoGaSi0AHVTafb3ZBGg4dr/bDwnaEKqCXzchMA==} - engines: {node: '>=0.10.0'} - dependencies: - for-in: 0.1.8 - is-extendable: 0.1.1 - dev: false - - /mixme@0.5.4: - resolution: {integrity: sha512-3KYa4m4Vlqx98GPdOHghxSdNtTvcP8E0kkaJ5Dlh+h2DRzF7zpuVVcA8B0QpKd11YJeP9QQ7ASkKzOeu195Wzw==} - engines: {node: '>= 8.0.0'} - dev: false - - /mkdirp-classic@0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - dev: false - - /mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - dev: false - - /mlly@1.5.0: - resolution: {integrity: sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==} - dependencies: - acorn: 8.11.3 - pathe: 1.1.2 - pkg-types: 1.0.3 - ufo: 1.5.4 - - /modern-ahocorasick@1.0.1: - resolution: {integrity: sha512-yoe+JbhTClckZ67b2itRtistFKf8yPYelHLc7e5xAwtNAXxM6wJTUx2C7QeVSJFDzKT7bCIFyBVybPMKvmB9AA==} - - /morgan@1.10.0: - resolution: {integrity: sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==} - engines: {node: '>= 0.8.0'} - dependencies: - basic-auth: 2.0.1 - debug: 2.6.9 - depd: 2.0.0 - on-finished: 2.3.0 - on-headers: 1.0.2 - transitivePeerDependencies: - - supports-color - dev: false - - /mri@1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} - dev: false - - /mrmime@1.0.1: - resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==} - engines: {node: '>=10'} - dev: false - - /ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - /msw@1.3.2(typescript@5.1.6): - resolution: {integrity: sha512-wKLhFPR+NitYTkQl5047pia0reNGgf0P6a1eTnA5aNlripmiz0sabMvvHcicE8kQ3/gZcI0YiPFWmYfowfm3lA==} - engines: {node: '>=14'} - hasBin: true - requiresBuild: true - peerDependencies: - typescript: '>= 4.4.x <= 5.2.x' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@mswjs/cookies': 0.2.2 - '@mswjs/interceptors': 0.17.10 - '@open-draft/until': 1.0.3 - '@types/cookie': 0.4.1 - '@types/js-levenshtein': 1.1.3 - chalk: 4.1.2 - chokidar: 3.6.0 - cookie: 0.4.2 - graphql: 16.8.1 - headers-polyfill: 3.2.5 - inquirer: 8.2.6 - is-node-process: 1.2.0 - js-levenshtein: 1.1.6 - node-fetch: 2.6.9 - outvariant: 1.4.2 - path-to-regexp: 6.2.1 - strict-event-emitter: 0.4.6 - type-fest: 2.19.0 - typescript: 5.1.6 - yargs: 17.5.1 - transitivePeerDependencies: - - encoding - - supports-color - dev: true - - /mustache@4.2.0: - resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} - hasBin: true - - /mute-stream@0.0.7: - resolution: {integrity: sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==} - dev: false - - /mute-stream@0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - dev: true - - /mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - - /nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - /natural-compare-lite@1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} - dev: false - - /natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - /negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - - /netmask@2.0.2: - resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} - engines: {node: '>= 0.4.0'} - dev: false - - /nice-try@1.0.5: - resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} - dev: false - - /node-fetch@2.6.9: - resolution: {integrity: sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - - /node-forge@1.3.1: - resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} - engines: {node: '>= 6.13.0'} - - /node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - - /node-mocks-http@1.14.1: - resolution: {integrity: sha512-mfXuCGonz0A7uG1FEjnypjm34xegeN5+HI6xeGhYKecfgaZhjsmYoLE9LEFmT+53G1n8IuagPZmVnEL/xNsFaA==} - engines: {node: '>=14'} - dependencies: - '@types/express': 4.17.21 - '@types/node': 20.11.17 - accepts: 1.3.8 - content-disposition: 0.5.4 - depd: 1.1.2 - fresh: 0.5.2 - merge-descriptors: 1.0.3 - methods: 1.1.2 - mime: 1.6.0 - parseurl: 1.3.3 - range-parser: 1.2.1 - type-is: 1.6.18 - dev: true - - /node-releases@2.0.14: - resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} - - /node-webtokens@1.0.4: - resolution: {integrity: sha512-Sla56CeSLWvPbwud2kogqf5edQtKNXZBtXDDpmOzAgNZjwETbK/Am6PXfs54iZPLBm8K8amZ9XWaCQwGqZmKyQ==} - engines: {node: '>=6.6.0'} - dev: false - - /normalize-package-data@2.5.0: - resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} - dependencies: - hosted-git-info: 2.8.9 - resolve: 1.22.8 - semver: 5.7.1 - validate-npm-package-license: 3.0.4 - dev: false - - /normalize-package-data@5.0.0: - resolution: {integrity: sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - hosted-git-info: 6.1.1 - is-core-module: 2.13.1 - semver: 7.5.4 - validate-npm-package-license: 3.0.4 - dev: false - - /normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - /npm-install-checks@6.3.0: - resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - semver: 7.5.4 - dev: false - - /npm-normalize-package-bin@3.0.1: - resolution: {integrity: sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dev: false - - /npm-package-arg@10.1.0: - resolution: {integrity: sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - hosted-git-info: 6.1.1 - proc-log: 3.0.0 - semver: 7.5.4 - validate-npm-package-name: 5.0.0 - dev: false - - /npm-pick-manifest@8.0.2: - resolution: {integrity: sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - npm-install-checks: 6.3.0 - npm-normalize-package-bin: 3.0.1 - npm-package-arg: 10.1.0 - semver: 7.5.4 - dev: false - - /npm-run-all@4.1.5: - resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} - engines: {node: '>= 4'} - hasBin: true - dependencies: - ansi-styles: 3.2.1 - chalk: 2.4.2 - cross-spawn: 6.0.5 - memorystream: 0.3.1 - minimatch: 3.1.2 - pidtree: 0.3.1 - read-pkg: 3.0.0 - shell-quote: 1.8.1 - string.prototype.padend: 3.1.5 - dev: false - - /npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - dependencies: - path-key: 3.1.1 - - /nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - dependencies: - boolbase: 1.0.0 - dev: false - - /nwsapi@2.2.7: - resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==} - dev: true - - /object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - /object-copy@0.1.0: - resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} - engines: {node: '>=0.10.0'} - dependencies: - copy-descriptor: 0.1.1 - define-property: 0.2.5 - kind-of: 3.2.2 - dev: false - - /object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} - - /object-inspect@1.13.1: - resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} - - /object-is@1.1.5: - resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - dev: false - - /object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - dev: false - - /object-visit@1.0.1: - resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: false - - /object.assign@4.1.5: - resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - has-symbols: 1.0.3 - object-keys: 1.1.1 - dev: false - - /object.entries@1.1.7: - resolution: {integrity: sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - dev: false - - /object.fromentries@2.0.7: - resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - dev: false - - /object.groupby@1.0.2: - resolution: {integrity: sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==} - dependencies: - array.prototype.filter: 1.0.3 - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - es-errors: 1.3.0 - dev: false - - /object.hasown@1.1.3: - resolution: {integrity: sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==} - dependencies: - define-properties: 1.2.1 - es-abstract: 1.22.4 - dev: false - - /object.values@1.1.7: - resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - dev: false - - /ohash@1.1.3: - resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==} - - /on-finished@2.3.0: - resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} - engines: {node: '>= 0.8'} - dependencies: - ee-first: 1.1.1 - dev: false - - /on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - dependencies: - ee-first: 1.1.1 - - /on-headers@1.0.2: - resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} - engines: {node: '>= 0.8'} - dev: false - - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - - /onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - dependencies: - mimic-fn: 2.1.0 - - /optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} - engines: {node: '>= 0.8.0'} - dependencies: - '@aashutoshrathi/word-wrap': 1.2.6 - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - - /ora@5.4.1: - resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} - engines: {node: '>=10'} - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.9.2 - is-interactive: 1.0.0 - is-unicode-supported: 0.1.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - - /os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - - /ospath@1.2.2: - resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==} - dev: false - - /outdent@0.5.0: - resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} - dev: false - - /outdent@0.8.0: - resolution: {integrity: sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==} - - /outvariant@1.4.2: - resolution: {integrity: sha512-Ou3dJ6bA/UJ5GVHxah4LnqDwZRwAmWxrG3wtrHrbGnP4RnLCtA64A4F+ae7Y8ww660JaddSoArUR5HjipWSHAQ==} - dev: true - - /p-filter@2.1.0: - resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} - engines: {node: '>=8'} - dependencies: - p-map: 2.1.0 - dev: false - - /p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - dependencies: - p-try: 2.2.0 - - /p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - dependencies: - yocto-queue: 0.1.0 - - /p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - dependencies: - p-limit: 2.3.0 - - /p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - dependencies: - p-limit: 3.1.0 - - /p-map@2.1.0: - resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} - engines: {node: '>=6'} - dev: false - - /p-map@4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} - engines: {node: '>=10'} - dependencies: - aggregate-error: 3.1.0 - dev: false - - /p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - - /pac-proxy-agent@7.0.1: - resolution: {integrity: sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==} - engines: {node: '>= 14'} - dependencies: - '@tootallnate/quickjs-emscripten': 0.23.0 - agent-base: 7.1.0 - debug: 4.4.0(supports-color@8.1.1) - get-uri: 6.0.3 - http-proxy-agent: 7.0.1 - https-proxy-agent: 7.0.3 - pac-resolver: 7.0.1 - socks-proxy-agent: 8.0.2 - transitivePeerDependencies: - - supports-color - dev: false - - /pac-resolver@7.0.1: - resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} - engines: {node: '>= 14'} - dependencies: - degenerator: 5.0.1 - netmask: 2.0.2 - dev: false - - /pako@0.2.9: - resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} - dev: false - - /parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - dependencies: - callsites: 3.1.0 - - /parse-entities@2.0.0: - resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} - dependencies: - character-entities: 1.2.4 - character-entities-legacy: 1.1.4 - character-reference-invalid: 1.1.4 - is-alphanumerical: 1.0.4 - is-decimal: 1.0.4 - is-hexadecimal: 1.0.4 - dev: false - - /parse-entities@3.0.0: - resolution: {integrity: sha512-AJlcIFDNPEP33KyJLguv0xJc83BNvjxwpuUIcetyXUsLpVXAUCePJ5kIoYtEN2R1ac0cYaRu/vk9dVFkewHQhQ==} - dependencies: - character-entities: 2.0.0 - character-entities-legacy: 2.0.0 - character-reference-invalid: 2.0.0 - is-alphanumerical: 2.0.0 - is-decimal: 2.0.0 - is-hexadecimal: 2.0.0 - dev: false - - /parse-entities@4.0.0: - resolution: {integrity: sha512-5nk9Fn03x3rEhGaX1FU6IDwG/k+GxLXlFAkgrbM1asuAFl3BhdQWvASaIsmwWypRNcZKHPYnIuOSfIWEyEQnPQ==} - dependencies: - '@types/unist': 2.0.6 - character-entities: 2.0.0 - character-entities-legacy: 3.0.0 - character-reference-invalid: 2.0.0 - decode-named-character-reference: 1.0.2 - is-alphanumerical: 2.0.0 - is-decimal: 2.0.0 - is-hexadecimal: 2.0.0 - dev: false - - /parse-json@4.0.0: - resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} - engines: {node: '>=4'} - dependencies: - error-ex: 1.3.2 - json-parse-better-errors: 1.0.2 - dev: false - - /parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - dependencies: - '@babel/code-frame': 7.23.5 - error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.1.6 - - /parse-ms@2.1.0: - resolution: {integrity: sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==} - engines: {node: '>=6'} - dev: false - - /parse5-htmlparser2-tree-adapter@7.0.0: - resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} - dependencies: - domhandler: 5.0.3 - parse5: 7.1.2 - dev: false - - /parse5@7.1.2: - resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} - dependencies: - entities: 4.5.0 - - /parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - - /path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - - /path-key@2.0.1: - resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} - engines: {node: '>=4'} - dev: false - - /path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - /path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - /path-scurry@1.10.1: - resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - lru-cache: 10.2.0 - minipass: 7.0.4 - - /path-to-regexp@0.1.10: - resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} - - /path-to-regexp@6.2.1: - resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} - - /path-type@3.0.0: - resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} - engines: {node: '>=4'} - dependencies: - pify: 3.0.0 - dev: false - - /path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - dev: false - - /pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - - /pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - dev: false - - /peek-stream@1.1.3: - resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==} - dependencies: - buffer-from: 1.1.2 - duplexify: 3.7.1 - through2: 2.0.5 - dev: false - - /pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - dev: false - - /performance-now@2.1.0: - resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} - dev: false - - /periscopic@3.0.4: - resolution: {integrity: sha512-SFx68DxCv0Iyo6APZuw/AKewkkThGwssmU0QWtTlvov3VAtPX+QJ4CadwSaz8nrT5jPIuxdvJWB4PnD2KNDxQg==} - dependencies: - estree-walker: 3.0.0 - is-reference: 3.0.0 - dev: false - - /picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - /picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - /pidtree@0.3.1: - resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} - engines: {node: '>=0.10'} - hasBin: true - dev: false - - /pidtree@0.6.0: - resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} - engines: {node: '>=0.10'} - hasBin: true - dev: false - - /pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - - /pify@3.0.0: - resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} - engines: {node: '>=4'} - dev: false - - /pify@4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} - dev: false - - /pirates@4.0.5: - resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} - engines: {node: '>= 6'} - - /pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - dependencies: - find-up: 4.1.0 - - /pkg-types@1.0.3: - resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} - dependencies: - jsonc-parser: 3.2.1 - mlly: 1.5.0 - pathe: 1.1.2 - - /playwright-core@1.49.1: - resolution: {integrity: sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==} - engines: {node: '>=18'} - hasBin: true - dev: false - - /playwright@1.49.1: - resolution: {integrity: sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==} - engines: {node: '>=18'} - hasBin: true - dependencies: - playwright-core: 1.49.1 - optionalDependencies: - fsevents: 2.3.2 - dev: false - - /pointer-symbol@1.0.0: - resolution: {integrity: sha512-pozTTFO3kG9HQWXCSTJkCgq4fBF8lUQf+5bLddTEW6v4zdjQhcBVfLmKzABEMJMA7s8jhzi0sgANIwdrf4kq+A==} - engines: {node: '>=4'} - dev: false - - /postcss-discard-duplicates@5.1.0(postcss@8.4.49): - resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==} - engines: {node: ^10 || ^12 || >=14.0} - peerDependencies: - postcss: ^8.2.15 - dependencies: - postcss: 8.4.49 - dev: false - - /postcss-import@15.1.0(postcss@8.4.49): - resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} - engines: {node: '>=14.0.0'} - peerDependencies: - postcss: ^8.0.0 - dependencies: - postcss: 8.4.49 - postcss-value-parser: 4.2.0 - read-cache: 1.0.0 - resolve: 1.22.8 - - /postcss-js@4.0.1(postcss@8.4.49): - resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} - engines: {node: ^12 || ^14 || >= 16} - peerDependencies: - postcss: ^8.4.21 - dependencies: - camelcase-css: 2.0.1 - postcss: 8.4.49 - - /postcss-load-config@4.0.2(postcss@8.4.49): - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - dependencies: - lilconfig: 3.0.0 - postcss: 8.4.49 - yaml: 2.3.4 - - /postcss-modules-extract-imports@3.0.0(postcss@8.4.49): - resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 - dependencies: - postcss: 8.4.49 - dev: false - - /postcss-modules-local-by-default@4.0.4(postcss@8.4.49): - resolution: {integrity: sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 - dependencies: - icss-utils: 5.1.0(postcss@8.4.49) - postcss: 8.4.49 - postcss-selector-parser: 6.0.15 - postcss-value-parser: 4.2.0 - dev: false - - /postcss-modules-scope@3.1.1(postcss@8.4.49): - resolution: {integrity: sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 - dependencies: - postcss: 8.4.49 - postcss-selector-parser: 6.0.15 - dev: false - - /postcss-modules-values@4.0.0(postcss@8.4.49): - resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 - dependencies: - icss-utils: 5.1.0(postcss@8.4.49) - postcss: 8.4.49 - dev: false - - /postcss-modules@6.0.0(postcss@8.4.49): - resolution: {integrity: sha512-7DGfnlyi/ju82BRzTIjWS5C4Tafmzl3R79YP/PASiocj+aa6yYphHhhKUOEoXQToId5rgyFgJ88+ccOUydjBXQ==} - peerDependencies: - postcss: ^8.0.0 - dependencies: - generic-names: 4.0.0 - icss-utils: 5.1.0(postcss@8.4.49) - lodash.camelcase: 4.3.0 - postcss: 8.4.49 - postcss-modules-extract-imports: 3.0.0(postcss@8.4.49) - postcss-modules-local-by-default: 4.0.4(postcss@8.4.49) - postcss-modules-scope: 3.1.1(postcss@8.4.49) - postcss-modules-values: 4.0.0(postcss@8.4.49) - string-hash: 1.1.3 - dev: false - - /postcss-nested@6.0.1(postcss@8.4.49): - resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.2.14 - dependencies: - postcss: 8.4.49 - postcss-selector-parser: 6.0.15 - - /postcss-selector-parser@6.0.15: - resolution: {integrity: sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==} - engines: {node: '>=4'} - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - - /postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - - /postcss@8.4.49: - resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} - engines: {node: ^10 || ^12 || >=14} - dependencies: - nanoid: 3.3.7 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - /preferred-pm@3.0.3: - resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==} - engines: {node: '>=10'} - dependencies: - find-up: 5.0.0 - find-yarn-workspace-root2: 1.2.16 - path-exists: 4.0.0 - which-pm: 2.0.0 - dev: false - - /prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - /prettier@2.8.1: - resolution: {integrity: sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==} - engines: {node: '>=10.13.0'} - hasBin: true - dev: false - - /pretty-bytes@5.6.0: - resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} - engines: {node: '>=6'} - dev: false - - /pretty-format@27.5.1: - resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} - engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} - dependencies: - ansi-regex: 5.0.1 - ansi-styles: 5.2.0 - react-is: 17.0.2 - - /pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.2.0 - - /pretty-ms@7.0.1: - resolution: {integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==} - engines: {node: '>=10'} - dependencies: - parse-ms: 2.1.0 - dev: false - - /printable-characters@1.0.42: - resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} - - /proc-log@3.0.0: - resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dev: false - - /process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - dev: false - - /promise-inflight@1.0.1: - resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} - peerDependencies: - bluebird: '*' - peerDependenciesMeta: - bluebird: - optional: true - dev: false - - /promise-retry@2.0.1: - resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} - engines: {node: '>=10'} - dependencies: - err-code: 2.0.3 - retry: 0.12.0 - dev: false - - /prompt-actions@3.0.2: - resolution: {integrity: sha512-dhz2Fl7vK+LPpmnQ/S/eSut4BnH4NZDLyddHKi5uTU/2PDn3grEMGkgsll16V5RpVUh/yxdiam0xsM0RD4xvtg==} - engines: {node: '>=4'} - dependencies: - debug: 2.6.9 - transitivePeerDependencies: - - supports-color - dev: false - - /prompt-base@4.1.0: - resolution: {integrity: sha512-svGzgLUKZoqomz9SGMkf1hBG8Wl3K7JGuRCXc/Pv7xw8239hhaTBXrmjt7EXA9P/QZzdyT8uNWt9F/iJTXq75g==} - engines: {node: '>=5.0'} - dependencies: - component-emitter: 1.3.0 - debug: 3.2.7(supports-color@8.1.1) - koalas: 1.0.2 - log-utils: 0.2.1 - prompt-actions: 3.0.2 - prompt-question: 5.0.2 - readline-ui: 2.2.3 - readline-utils: 2.2.3 - static-extend: 0.1.2 - transitivePeerDependencies: - - supports-color - dev: false - - /prompt-choices@4.1.0: - resolution: {integrity: sha512-ZNYLv6rW9z9n0WdwCkEuS+w5nUAGzRgtRt6GQ5aFNFz6MIcU7nHFlHOwZtzy7RQBk80KzUGPSRQphvMiQzB8pg==} - engines: {node: '>=4.0.0'} - dependencies: - arr-flatten: 1.1.0 - arr-swap: 1.0.1 - choices-separator: 2.0.0 - clone-deep: 4.0.1 - collection-visit: 1.0.0 - define-property: 2.0.2 - is-number: 6.0.0 - kind-of: 6.0.3 - koalas: 1.0.2 - log-utils: 0.2.1 - pointer-symbol: 1.0.0 - radio-symbol: 2.0.0 - set-value: 3.0.3 - strip-color: 0.1.0 - terminal-paginator: 2.0.2 - toggle-array: 1.0.1 - transitivePeerDependencies: - - supports-color - dev: false - - /prompt-confirm@2.0.4: - resolution: {integrity: sha512-X5lzbC8/kMNHdPOqQPfMKpH4VV2f7v2OTRJoN69ZYBirSwTeQaf9ZhmzPEO9ybMA0YV2Pha5MV27u2/U4ahWfg==} - engines: {node: '>=6.0'} - dependencies: - ansi-cyan: 0.1.1 - prompt-base: 4.1.0 - transitivePeerDependencies: - - supports-color - dev: false - - /prompt-question@5.0.2: - resolution: {integrity: sha512-wreaLbbu8f5+7zXds199uiT11Ojp59Z4iBi6hONlSLtsKGTvL2UY8VglcxQ3t/X4qWIxsNCg6aT4O8keO65v6Q==} - engines: {node: '>=4.0.0'} - dependencies: - clone-deep: 1.0.0 - debug: 3.2.7(supports-color@8.1.1) - define-property: 1.0.0 - isobject: 3.0.1 - kind-of: 5.1.0 - koalas: 1.0.2 - prompt-choices: 4.1.0 - transitivePeerDependencies: - - supports-color - dev: false - - /prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - - /prop-types@15.8.1: - resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - dependencies: - loose-envify: 1.4.0 - object-assign: 4.1.1 - react-is: 16.13.1 - dev: false - - /property-information@6.0.1: - resolution: {integrity: sha512-F4WUUAF7fMeF4/JUFHNBWDaKDXi2jbvqBW/y6o5wsf3j19wTZ7S60TmtB5HoBhtgw7NKQRMWuz5vk2PR0CygUg==} - dev: false - - /proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - - /proxy-agent@6.4.0: - resolution: {integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==} - engines: {node: '>= 14'} - dependencies: - agent-base: 7.1.0 - debug: 4.4.0(supports-color@8.1.1) - http-proxy-agent: 7.0.1 - https-proxy-agent: 7.0.3 - lru-cache: 7.18.3 - pac-proxy-agent: 7.0.1 - proxy-from-env: 1.1.0 - socks-proxy-agent: 8.0.2 - transitivePeerDependencies: - - supports-color - dev: false - - /proxy-from-env@1.0.0: - resolution: {integrity: sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==} - dev: false - - /proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: false - - /pseudomap@1.0.2: - resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} - dev: false - - /psl@1.8.0: - resolution: {integrity: sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==} - - /pump@2.0.1: - resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - dev: false - - /pump@3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - dev: false - - /pumpify@1.5.1: - resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} - dependencies: - duplexify: 3.7.1 - inherits: 2.0.4 - pump: 2.0.1 - dev: false - - /punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - /pure-rand@6.0.2: - resolution: {integrity: sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==} - - /qs@6.13.0: - resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} - engines: {node: '>=0.6'} - dependencies: - side-channel: 1.0.6 - - /qs@6.5.3: - resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} - engines: {node: '>=0.6'} - dev: false - - /querystringify@2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - dev: true - - /queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - /quick-lru@4.0.1: - resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} - engines: {node: '>=8'} - dev: false - - /radio-symbol@2.0.0: - resolution: {integrity: sha512-fpuWhwGD4XG1BfUWKXhCqdguCXzGi/DDb6RzmAGZo9R75enjlx0l+ZhHF93KNG7iNpT0Vi7wEqbf8ZErbe+JtQ==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-gray: 0.1.1 - ansi-green: 0.1.1 - is-windows: 1.0.2 - dev: false - - /random-bytes@1.0.0: - resolution: {integrity: sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==} - engines: {node: '>= 0.8'} - dev: false - - /randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - dependencies: - safe-buffer: 5.2.1 - dev: false - - /range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - - /raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - - /react-dom@18.2.0(react@18.2.0): - resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} - peerDependencies: - react: ^18.2.0 - dependencies: - loose-envify: 1.4.0 - react: 18.2.0 - scheduler: 0.23.0 - - /react-is@16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - dev: false - - /react-is@17.0.2: - resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} - - /react-is@18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - - /react-refresh@0.14.0: - resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} - engines: {node: '>=0.10.0'} - dev: false - - /react-router-dom@6.30.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-x30B78HV5tFk8ex0ITwzC9TTZMua4jGyA9IUlH1JLQYQTFyxr/ZxwOJq7evg1JX1qGVUcvhsmQSKdPncQrjTgA==} - engines: {node: '>=14.0.0'} - peerDependencies: - react: '>=16.8' - react-dom: '>=16.8' - dependencies: - '@remix-run/router': 1.23.0 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-router: 6.30.0(react@18.2.0) - dev: false - - /react-router@6.30.0(react@18.2.0): - resolution: {integrity: sha512-D3X8FyH9nBcTSHGdEKurK7r8OYE1kKFn3d/CF+CoxbSHkxU7o37+Uh7eAHRXr6k2tSExXYO++07PeXJtA/dEhQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - react: '>=16.8' - dependencies: - '@remix-run/router': 1.23.0 - react: 18.2.0 - dev: false - - /react@18.2.0: - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} - engines: {node: '>=0.10.0'} - dependencies: - loose-envify: 1.4.0 - - /read-cache@1.0.0: - resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} - dependencies: - pify: 2.3.0 - - /read-pkg-up@7.0.1: - resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} - engines: {node: '>=8'} - dependencies: - find-up: 4.1.0 - read-pkg: 5.2.0 - type-fest: 0.8.1 - dev: false - - /read-pkg@3.0.0: - resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} - engines: {node: '>=4'} - dependencies: - load-json-file: 4.0.0 - normalize-package-data: 2.5.0 - path-type: 3.0.0 - dev: false - - /read-pkg@5.2.0: - resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} - engines: {node: '>=8'} - dependencies: - '@types/normalize-package-data': 2.4.1 - normalize-package-data: 2.5.0 - parse-json: 5.2.0 - type-fest: 0.6.0 - dev: false - - /read-yaml-file@1.1.0: - resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} - engines: {node: '>=6'} - dependencies: - graceful-fs: 4.2.11 - js-yaml: 3.14.1 - pify: 4.0.1 - strip-bom: 3.0.0 - dev: false - - /readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - dependencies: - core-util-is: 1.0.2 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - dev: false - - /readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - - /readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - dependencies: - picomatch: 2.3.1 - - /readline-ui@2.2.3: - resolution: {integrity: sha512-ix7jz0PxqQqcIuq3yQTHv1TOhlD2IHO74aNO+lSuXsRYm1d+pdyup1yF3zKyLK1wWZrVNGjkzw5tUegO2IDy+A==} - engines: {node: '>=4.0'} - dependencies: - component-emitter: 1.3.0 - debug: 2.6.9 - readline-utils: 2.2.3 - string-width: 2.1.1 - transitivePeerDependencies: - - supports-color - dev: false - - /readline-utils@2.2.3: - resolution: {integrity: sha512-cjFo7R7e7AaFOz2JLQ4EgsHh4+l7mw29Eu3DAEPgGeWbYQFKqyxWsL61/McC6b2oJAvn14Ea8eUms9o8ZFC1iQ==} - engines: {node: '>=4.0'} - dependencies: - arr-flatten: 1.1.0 - extend-shallow: 2.0.1 - is-buffer: 1.1.6 - is-number: 3.0.0 - is-windows: 1.0.2 - koalas: 1.0.2 - mute-stream: 0.0.7 - strip-color: 0.1.0 - window-size: 1.1.1 - dev: false - - /rechoir@0.6.2: - resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} - engines: {node: '>= 0.10'} - dependencies: - resolve: 1.22.8 - dev: false - - /recursive-readdir@2.2.3: - resolution: {integrity: sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==} - engines: {node: '>=6.0.0'} - dependencies: - minimatch: 3.1.2 - dev: false - - /redent@3.0.0: - resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} - engines: {node: '>=8'} - dependencies: - indent-string: 4.0.0 - strip-indent: 3.0.0 - - /reflect.getprototypeof@1.0.5: - resolution: {integrity: sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - es-errors: 1.3.0 - get-intrinsic: 1.2.4 - globalthis: 1.0.3 - which-builtin-type: 1.1.3 - dev: false - - /regenerate-unicode-properties@10.1.0: - resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} - engines: {node: '>=4'} - dependencies: - regenerate: 1.4.2 - dev: false - - /regenerate@1.4.2: - resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} - dev: false - - /regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - - /regenerator-transform@0.15.1: - resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} - dependencies: - '@babel/runtime': 7.23.9 - dev: false - - /regexp.prototype.flags@1.5.2: - resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-errors: 1.3.0 - set-function-name: 2.0.1 - dev: false - - /regexpp@3.2.0: - resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} - engines: {node: '>=8'} - dev: false - - /regexpu-core@5.3.2: - resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} - engines: {node: '>=4'} - dependencies: - '@babel/regjsgen': 0.8.0 - regenerate: 1.4.2 - regenerate-unicode-properties: 10.1.0 - regjsparser: 0.9.1 - unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.1.0 - dev: false - - /regjsparser@0.9.1: - resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} - hasBin: true - dependencies: - jsesc: 0.5.0 - dev: false - - /remark-frontmatter@4.0.1: - resolution: {integrity: sha512-38fJrB0KnmD3E33a5jZC/5+gGAC2WKNiPw1/fdXJvijBlhA7RCsvJklrYJakS0HedninvaCYW8lQGf9C918GfA==} - dependencies: - '@types/mdast': 3.0.10 - mdast-util-frontmatter: 1.0.0 - micromark-extension-frontmatter: 1.0.0 - unified: 10.1.2 - dev: false - - /remark-gfm@3.0.1: - resolution: {integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==} - dependencies: - '@types/mdast': 3.0.10 - mdast-util-gfm: 2.0.1 - micromark-extension-gfm: 2.0.1 - unified: 10.1.2 - transitivePeerDependencies: - - supports-color - dev: false - - /remark-mdx-frontmatter@1.1.1: - resolution: {integrity: sha512-7teX9DW4tI2WZkXS4DBxneYSY7NHiXl4AKdWDO9LXVweULlCT8OPWsOjLEnMIXViN1j+QcY8mfbq3k0EK6x3uA==} - engines: {node: '>=12.2.0'} - dependencies: - estree-util-is-identifier-name: 1.1.0 - estree-util-value-to-estree: 1.3.0 - js-yaml: 4.1.0 - toml: 3.0.0 - dev: false - - /remark-mdx@2.3.0: - resolution: {integrity: sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g==} - dependencies: - mdast-util-mdx: 2.0.1 - micromark-extension-mdxjs: 1.0.1 - transitivePeerDependencies: - - supports-color - dev: false - - /remark-mdx@3.0.0: - resolution: {integrity: sha512-O7yfjuC6ra3NHPbRVxfflafAj3LTwx3b73aBvkEFU5z4PsD6FD4vrqJAkE5iNGLz71GdjXfgRqm3SQ0h0VuE7g==} - dependencies: - mdast-util-mdx: 3.0.0 - micromark-extension-mdxjs: 3.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /remark-parse@10.0.1: - resolution: {integrity: sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==} - dependencies: - '@types/mdast': 3.0.10 - mdast-util-from-markdown: 1.3.1 - unified: 10.1.2 - transitivePeerDependencies: - - supports-color - dev: false - - /remark-parse@11.0.0: - resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} - dependencies: - '@types/mdast': 4.0.3 - mdast-util-from-markdown: 2.0.0 - micromark-util-types: 2.0.0 - unified: 11.0.4 - transitivePeerDependencies: - - supports-color - dev: false - - /remark-rehype@10.1.0: - resolution: {integrity: sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==} - dependencies: - '@types/hast': 2.3.10 - '@types/mdast': 3.0.10 - mdast-util-to-hast: 12.3.0 - unified: 10.1.2 - dev: false - - /remark-rehype@11.0.0: - resolution: {integrity: sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==} - dependencies: - '@types/hast': 3.0.3 - '@types/mdast': 4.0.3 - mdast-util-to-hast: 13.0.2 - unified: 11.0.4 - vfile: 6.0.1 - dev: false - - /remark-stringify@10.0.2: - resolution: {integrity: sha512-6wV3pvbPvHkbNnWB0wdDvVFHOe1hBRAx1Q/5g/EpH4RppAII6J8Gnwe7VbHuXaoKIF6LAg6ExTel/+kNqSQ7lw==} - dependencies: - '@types/mdast': 3.0.10 - mdast-util-to-markdown: 1.3.0 - unified: 10.1.2 - dev: false - - /remark@14.0.2: - resolution: {integrity: sha512-A3ARm2V4BgiRXaUo5K0dRvJ1lbogrbXnhkJRmD0yw092/Yl0kOCZt1k9ZeElEwkZsWGsMumz6qL5MfNJH9nOBA==} - dependencies: - '@types/mdast': 3.0.10 - remark-parse: 10.0.1 - remark-stringify: 10.0.2 - unified: 10.1.2 - transitivePeerDependencies: - - supports-color - dev: false - - /request-progress@3.0.0: - resolution: {integrity: sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==} - dependencies: - throttleit: 1.0.0 - dev: false - - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - /require-like@0.1.2: - resolution: {integrity: sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==} - - /require-main-filename@2.0.0: - resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} - dev: false - - /requireindex@1.2.0: - resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} - engines: {node: '>=0.10.5'} - dev: false - - /requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - dev: true - - /resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - dependencies: - resolve-from: 5.0.0 - - /resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - /resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - - /resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - dev: false - - /resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} - - /resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true - dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - /resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} - hasBin: true - dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: false - - /restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - - /restore-cursor@4.0.0: - resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - dev: false - - /retry@0.12.0: - resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} - engines: {node: '>= 4'} - dev: false - - /reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - /rfdc@1.3.0: - resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} - dev: false - - /rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - dependencies: - glob: 7.2.0 - - /rimraf@4.4.1: - resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==} - engines: {node: '>=14'} - hasBin: true - dependencies: - glob: 9.3.5 - dev: false - - /rndm@1.2.0: - resolution: {integrity: sha512-fJhQQI5tLrQvYIYFpOnFinzv9dwmR7hRnUz1XqP3OJ1jIweTNOd6aTO4jwQSgcBSFUB+/KHJxuGneime+FdzOw==} - dev: false - - /rollup-plugin-copy@3.4.0: - resolution: {integrity: sha512-rGUmYYsYsceRJRqLVlE9FivJMxJ7X6jDlP79fmFkL8sJs7VVMSVyA2yfyL+PGyO/vJs4A87hwhgVfz61njI+uQ==} - engines: {node: '>=8.3'} - dependencies: - '@types/fs-extra': 8.1.2 - colorette: 1.4.0 - fs-extra: 8.1.0 - globby: 10.0.1 - is-plain-object: 3.0.1 - dev: false - - /rollup-plugin-inject@3.0.2: - resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} - deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. - dependencies: - estree-walker: 0.6.1 - magic-string: 0.25.9 - rollup-pluginutils: 2.8.2 - - /rollup-plugin-node-polyfills@0.2.1: - resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} - dependencies: - rollup-plugin-inject: 3.0.2 - - /rollup-pluginutils@2.8.2: - resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} - dependencies: - estree-walker: 0.6.1 - - /rollup@2.79.2: - resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==} - engines: {node: '>=10.0.0'} - hasBin: true - optionalDependencies: - fsevents: 2.3.3 - dev: false - - /rollup@4.29.1: - resolution: {integrity: sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - dependencies: - '@types/estree': 1.0.6 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.29.1 - '@rollup/rollup-android-arm64': 4.29.1 - '@rollup/rollup-darwin-arm64': 4.29.1 - '@rollup/rollup-darwin-x64': 4.29.1 - '@rollup/rollup-freebsd-arm64': 4.29.1 - '@rollup/rollup-freebsd-x64': 4.29.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.29.1 - '@rollup/rollup-linux-arm-musleabihf': 4.29.1 - '@rollup/rollup-linux-arm64-gnu': 4.29.1 - '@rollup/rollup-linux-arm64-musl': 4.29.1 - '@rollup/rollup-linux-loongarch64-gnu': 4.29.1 - '@rollup/rollup-linux-powerpc64le-gnu': 4.29.1 - '@rollup/rollup-linux-riscv64-gnu': 4.29.1 - '@rollup/rollup-linux-s390x-gnu': 4.29.1 - '@rollup/rollup-linux-x64-gnu': 4.29.1 - '@rollup/rollup-linux-x64-musl': 4.29.1 - '@rollup/rollup-win32-arm64-msvc': 4.29.1 - '@rollup/rollup-win32-ia32-msvc': 4.29.1 - '@rollup/rollup-win32-x64-msvc': 4.29.1 - fsevents: 2.3.3 - - /rrweb-cssom@0.6.0: - resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==} - dev: true - - /run-async@2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} - engines: {node: '>=0.12.0'} - dev: true - - /run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - dependencies: - queue-microtask: 1.2.3 - - /run-waterfall@1.1.7: - resolution: {integrity: sha512-iFPgh7SatHXOG1ClcpdwHI63geV3Hc/iL6crGSyBlH2PY7Rm/za+zoKz6FfY/Qlw5K7JwSol8pseO8fN6CMhhQ==} - dev: false - - /rxjs@6.6.7: - resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} - engines: {npm: '>=2.0.0'} - dependencies: - tslib: 1.14.1 - dev: false - - /rxjs@7.8.1: - resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} - dependencies: - tslib: 2.6.2 - - /sade@1.8.1: - resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} - engines: {node: '>=6'} - dependencies: - mri: 1.2.0 - dev: false - - /safe-array-concat@1.1.0: - resolution: {integrity: sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==} - engines: {node: '>=0.4'} - dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.4 - has-symbols: 1.0.3 - isarray: 2.0.5 - dev: false - - /safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - - /safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - /safe-regex-test@1.0.3: - resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-regex: 1.1.4 - dev: false - - /safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - /saxes@6.0.0: - resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} - engines: {node: '>=v12.22.7'} - dependencies: - xmlchars: 2.2.0 - dev: true - - /scheduler@0.23.0: - resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} - dependencies: - loose-envify: 1.4.0 - - /selfsigned@2.4.1: - resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} - engines: {node: '>=10'} - dependencies: - '@types/node-forge': 1.3.11 - node-forge: 1.3.1 - - /semver@5.7.1: - resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} - hasBin: true - dev: false - - /semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - /semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - - /send@0.19.0: - resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} - engines: {node: '>= 0.8.0'} - dependencies: - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - - /serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - dependencies: - randombytes: 2.1.0 - dev: false - - /serve-static@1.16.2: - resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} - engines: {node: '>= 0.8.0'} - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.19.0 - transitivePeerDependencies: - - supports-color - - /set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - dev: false - - /set-cookie-parser@2.6.0: - resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} - - /set-function-length@1.2.1: - resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} - engines: {node: '>= 0.4'} - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.2.4 - gopd: 1.0.1 - has-property-descriptors: 1.0.2 - - /set-function-name@2.0.1: - resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} - engines: {node: '>= 0.4'} - dependencies: - define-data-property: 1.1.4 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - dev: false - - /set-getter@0.1.1: - resolution: {integrity: sha512-9sVWOy+gthr+0G9DzqqLaYNA7+5OKkSmcqjL9cBpDEaZrr3ShQlyX2cZ/O/ozE41oxn/Tt0LGEM/w4Rub3A3gw==} - engines: {node: '>=0.10.0'} - dependencies: - to-object-path: 0.3.0 - dev: false - - /set-value@3.0.3: - resolution: {integrity: sha512-Xsn/XSatoVOGBbp5hs3UylFDs5Bi9i+ArpVJKdHPniZHoEgRniXTqHWrWrGQ0PbEClVT6WtfnBwR8CAHC9sveg==} - engines: {node: '>=6.0'} - dependencies: - is-plain-object: 2.0.4 - dev: false - - /setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - - /shallow-clone@1.0.0: - resolution: {integrity: sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==} - engines: {node: '>=0.10.0'} - dependencies: - is-extendable: 0.1.1 - kind-of: 5.1.0 - mixin-object: 2.0.1 - dev: false - - /shallow-clone@3.0.1: - resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} - engines: {node: '>=8'} - dependencies: - kind-of: 6.0.3 - - /shebang-command@1.2.0: - resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} - engines: {node: '>=0.10.0'} - dependencies: - shebang-regex: 1.0.0 - dev: false - - /shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - dependencies: - shebang-regex: 3.0.0 - - /shebang-regex@1.0.0: - resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} - engines: {node: '>=0.10.0'} - dev: false - - /shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - /shell-quote@1.8.1: - resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} - dev: false - - /shelljs@0.8.5: - resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} - engines: {node: '>=4'} - hasBin: true - dependencies: - glob: 7.2.0 - interpret: 1.4.0 - rechoir: 0.6.2 - dev: false - - /side-channel@1.0.6: - resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - get-intrinsic: 1.2.4 - object-inspect: 1.13.1 - - /signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - /signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - /simple-git@3.16.0: - resolution: {integrity: sha512-zuWYsOLEhbJRWVxpjdiXl6eyAyGo/KzVW+KFhhw9MqEEJttcq+32jTWSGyxTdf9e/YCohxRE+9xpWFj9FdiJNw==} - dependencies: - '@kwsites/file-exists': 1.1.1 - '@kwsites/promise-deferred': 1.1.1 - debug: 4.4.0(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - dev: false - - /sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - - /slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - - /slash@5.1.0: - resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} - engines: {node: '>=14.16'} - dev: false - - /slice-ansi@3.0.0: - resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} - engines: {node: '>=8'} - dependencies: - ansi-styles: 4.3.0 - astral-regex: 2.0.0 - is-fullwidth-code-point: 3.0.0 - dev: false - - /slice-ansi@4.0.0: - resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - astral-regex: 2.0.0 - is-fullwidth-code-point: 3.0.0 - dev: false - - /slice-ansi@5.0.0: - resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} - engines: {node: '>=12'} - dependencies: - ansi-styles: 6.2.1 - is-fullwidth-code-point: 4.0.0 - dev: false - - /smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - dev: false - - /smartwrap@2.0.2: - resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} - engines: {node: '>=6'} - hasBin: true - dependencies: - array.prototype.flat: 1.3.2 - breakword: 1.0.5 - grapheme-splitter: 1.0.4 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - yargs: 15.4.1 - dev: false - - /socks-proxy-agent@8.0.2: - resolution: {integrity: sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==} - engines: {node: '>= 14'} - dependencies: - agent-base: 7.1.0 - debug: 4.4.0(supports-color@8.1.1) - socks: 2.7.3 - transitivePeerDependencies: - - supports-color - dev: false - - /socks@2.7.3: - resolution: {integrity: sha512-vfuYK48HXCTFD03G/1/zkIls3Ebr2YNa4qU9gHDZdblHLiqhJrJGkY3+0Nx0JpN9qBhJbVObc1CNciT1bIZJxw==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - deprecated: please use 2.7.4 or 2.8.1 to fix package-lock issue - dependencies: - ip-address: 9.0.5 - smart-buffer: 4.2.0 - dev: false - - /sort-object-keys@1.1.3: - resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==} - dev: false - - /sort-package-json@1.57.0: - resolution: {integrity: sha512-FYsjYn2dHTRb41wqnv+uEqCUvBpK3jZcTp9rbz2qDTmel7Pmdtf+i2rLaaPMRZeSVM60V3Se31GyWFpmKs4Q5Q==} - hasBin: true - dependencies: - detect-indent: 6.1.0 - detect-newline: 3.1.0 - git-hooks-list: 1.0.3 - globby: 10.0.0 - is-plain-obj: 2.1.0 - sort-object-keys: 1.1.3 - dev: false - - /source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - /source-map-support@0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - /source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: false - - /source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - /source-map@0.7.3: - resolution: {integrity: sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==} - engines: {node: '>= 8'} - dev: false - - /sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - - /space-separated-tokens@2.0.1: - resolution: {integrity: sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw==} - dev: false - - /spawn-command@0.0.2-1: - resolution: {integrity: sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==} - dev: false - - /spawndamnit@2.0.0: - resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} - dependencies: - cross-spawn: 5.1.0 - signal-exit: 3.0.7 - dev: false - - /spdx-correct@3.1.1: - resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} - dependencies: - spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.10 - dev: false - - /spdx-exceptions@2.3.0: - resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} - dev: false - - /spdx-expression-parse@3.0.1: - resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - dependencies: - spdx-exceptions: 2.3.0 - spdx-license-ids: 3.0.10 - dev: false - - /spdx-license-ids@3.0.10: - resolution: {integrity: sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==} - dev: false - - /sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - - /sprintf-js@1.1.3: - resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} - dev: false - - /sshpk@1.17.0: - resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==} - engines: {node: '>=0.10.0'} - hasBin: true - dependencies: - asn1: 0.2.6 - assert-plus: 1.0.0 - bcrypt-pbkdf: 1.0.2 - dashdash: 1.14.1 - ecc-jsbn: 0.1.2 - getpass: 0.1.7 - jsbn: 0.1.1 - safer-buffer: 2.1.2 - tweetnacl: 0.14.5 - dev: false - - /ssri@10.0.5: - resolution: {integrity: sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - minipass: 7.0.4 - dev: false - - /stack-utils@2.0.5: - resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==} - engines: {node: '>=10'} - dependencies: - escape-string-regexp: 2.0.0 - - /stacktracey@2.1.8: - resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} - dependencies: - as-table: 1.0.55 - get-source: 2.0.12 - - /static-extend@0.1.2: - resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} - engines: {node: '>=0.10.0'} - dependencies: - define-property: 0.2.5 - object-copy: 0.1.0 - dev: false - - /statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - - /stop-iteration-iterator@1.0.0: - resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} - engines: {node: '>= 0.4'} - dependencies: - internal-slot: 1.0.7 - dev: false - - /stoppable@1.1.0: - resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} - engines: {node: '>=4', npm: '>=6'} - - /stream-shift@1.0.3: - resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} - dev: false - - /stream-slice@0.1.2: - resolution: {integrity: sha512-QzQxpoacatkreL6jsxnVb7X5R/pGw9OUv2qWTYWnmLpg4NdN31snPy/f3TdQE1ZUXaThRvj1Zw4/OGg0ZkaLMA==} - dev: false - - /stream-transform@2.1.3: - resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} - dependencies: - mixme: 0.5.4 - dev: false - - /strict-event-emitter@0.2.8: - resolution: {integrity: sha512-KDf/ujU8Zud3YaLtMCcTI4xkZlZVIYxTLr+XIULexP+77EEVWixeXroLUXQXiVtH4XH2W7jr/3PT1v3zBuvc3A==} - dependencies: - events: 3.3.0 - dev: true - - /strict-event-emitter@0.4.6: - resolution: {integrity: sha512-12KWeb+wixJohmnwNFerbyiBrAlq5qJLwIt38etRtKtmmHyDSoGlIqFE9wx+4IwG0aDjI7GV8tc8ZccjWZZtTg==} - dev: true - - /string-hash@1.1.3: - resolution: {integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==} - dev: false - - /string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} - dependencies: - char-regex: 1.0.2 - strip-ansi: 6.0.1 - - /string-length@5.0.1: - resolution: {integrity: sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==} - engines: {node: '>=12.20'} - dependencies: - char-regex: 2.0.1 - strip-ansi: 7.1.0 - dev: false - - /string-width@2.1.1: - resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} - engines: {node: '>=4'} - dependencies: - is-fullwidth-code-point: 2.0.0 - strip-ansi: 4.0.0 - dev: false - - /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - /string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - /string.prototype.matchall@4.0.10: - resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - get-intrinsic: 1.2.4 - has-symbols: 1.0.3 - internal-slot: 1.0.7 - regexp.prototype.flags: 1.5.2 - set-function-name: 2.0.1 - side-channel: 1.0.6 - dev: false - - /string.prototype.padend@3.1.5: - resolution: {integrity: sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - dev: false - - /string.prototype.trim@1.2.8: - resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - dev: false - - /string.prototype.trimend@1.0.7: - resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - dev: false - - /string.prototype.trimstart@1.0.7: - resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.4 - dev: false - - /string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - dependencies: - safe-buffer: 5.1.2 - dev: false - - /string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - dependencies: - safe-buffer: 5.2.1 - - /stringify-entities@4.0.1: - resolution: {integrity: sha512-gmMQxKXPWIO3NXNSPyWNhlYcBNGpPA/487D+9dLPnU4xBnIrnHdr8cv5rGJOS/1BRxEXRb7uKwg7BA36IWV7xg==} - dependencies: - character-entities-html4: 2.0.0 - character-entities-legacy: 2.0.0 - dev: false - - /strip-ansi@4.0.0: - resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} - engines: {node: '>=4'} - dependencies: - ansi-regex: 3.0.1 - dev: false - - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - - /strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - dependencies: - ansi-regex: 6.0.1 - - /strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - dev: false - - /strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - - /strip-color@0.1.0: - resolution: {integrity: sha512-p9LsUieSjWNNAxVCXLeilaDlmuUOrDS5/dF9znM1nZc7EGX5+zEFC0bEevsNIaldjlks+2jns5Siz6F9iK6jwA==} - engines: {node: '>=0.10.0'} - dev: false - - /strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - - /strip-indent@3.0.0: - resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} - engines: {node: '>=8'} - dependencies: - min-indent: 1.0.1 - - /strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - /style-to-object@0.4.4: - resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==} - dependencies: - inline-style-parser: 0.1.1 - dev: false - - /success-symbol@0.1.0: - resolution: {integrity: sha512-7S6uOTxPklNGxOSbDIg4KlVLBQw1UiGVyfCUYgYxrZUKRblUkmGj7r8xlfQoFudvqLv6Ap5gd76/IIFfI9JG2A==} - engines: {node: '>=0.10.0'} - dev: false - - /sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - dependencies: - '@jridgewell/gen-mapping': 0.3.2 - commander: 4.1.1 - glob: 10.3.10 - lines-and-columns: 1.1.6 - mz: 2.7.0 - pirates: 4.0.5 - ts-interface-checker: 0.1.13 - - /superagent@8.1.2: - resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} - engines: {node: '>=6.4.0 <13 || >=14'} - deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net - dependencies: - component-emitter: 1.3.0 - cookiejar: 2.1.4 - debug: 4.4.0(supports-color@8.1.1) - fast-safe-stringify: 2.1.1 - form-data: 4.0.0 - formidable: 2.1.2 - methods: 1.1.2 - mime: 2.6.0 - qs: 6.13.0 - semver: 7.5.4 - transitivePeerDependencies: - - supports-color - dev: true - - /supertest@6.3.4: - resolution: {integrity: sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==} - engines: {node: '>=6.4.0'} - dependencies: - methods: 1.1.2 - superagent: 8.1.2 - transitivePeerDependencies: - - supports-color - dev: true - - /supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - dependencies: - has-flag: 3.0.0 - - /supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - - /supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - dependencies: - has-flag: 4.0.0 - - /supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - /symbol-tree@3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - dev: true - - /tailwindcss@3.4.1: - resolution: {integrity: sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==} - engines: {node: '>=14.0.0'} - hasBin: true - dependencies: - '@alloc/quick-lru': 5.2.0 - arg: 5.0.2 - chokidar: 3.6.0 - didyoumean: 1.2.2 - dlv: 1.1.3 - fast-glob: 3.3.2 - glob-parent: 6.0.2 - is-glob: 4.0.3 - jiti: 1.21.0 - lilconfig: 2.1.0 - micromatch: 4.0.5 - normalize-path: 3.0.0 - object-hash: 3.0.0 - picocolors: 1.1.1 - postcss: 8.4.49 - postcss-import: 15.1.0(postcss@8.4.49) - postcss-js: 4.0.1(postcss@8.4.49) - postcss-load-config: 4.0.2(postcss@8.4.49) - postcss-nested: 6.0.1(postcss@8.4.49) - postcss-selector-parser: 6.0.15 - resolve: 1.22.8 - sucrase: 3.35.0 - transitivePeerDependencies: - - ts-node - - /tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} - engines: {node: '>=6'} - dev: false - - /tar-fs@2.1.1: - resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.0 - tar-stream: 2.2.0 - dev: false - - /tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.4 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - dev: false - - /tar@6.2.0: - resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} - engines: {node: '>=10'} - dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 5.0.0 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 - dev: false - - /term-size@2.2.1: - resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} - engines: {node: '>=8'} - dev: false - - /terminal-paginator@2.0.2: - resolution: {integrity: sha512-IZMT5ECF9p4s+sNCV8uvZSW9E1+9zy9Ji9xz2oee8Jfo7hUFpauyjxkhfRcIH6Lu3Wdepv5D1kVRc8Hx74/LfQ==} - engines: {node: '>=0.10.0'} - dependencies: - debug: 2.6.9 - extend-shallow: 2.0.1 - log-utils: 0.2.1 - transitivePeerDependencies: - - supports-color - dev: false - - /test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} - dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 7.2.0 - minimatch: 3.1.2 - - /text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - - /thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - dependencies: - thenify: 3.3.1 - - /thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - dependencies: - any-promise: 1.3.0 - - /throttleit@1.0.0: - resolution: {integrity: sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==} - dev: false - - /through2@2.0.5: - resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} - dependencies: - readable-stream: 2.3.8 - xtend: 4.0.2 - dev: false - - /through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - - /time-stamp@1.1.0: - resolution: {integrity: sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==} - engines: {node: '>=0.10.0'} - dev: false - - /tiny-invariant@1.3.1: - resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} - dev: true - - /tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - dependencies: - os-tmpdir: 1.0.2 - - /tmp@0.2.1: - resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} - engines: {node: '>=8.17.0'} - dependencies: - rimraf: 3.0.2 - dev: false - - /tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - - /to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - - /to-object-path@0.3.0: - resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: false - - /to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - dependencies: - is-number: 7.0.0 - - /to-vfile@7.2.3: - resolution: {integrity: sha512-QO0A9aE6Z/YkmQadJ0syxpmNXtcQiu0qAtCKYKD5cS3EfgfFTAXfgLX6AOaBrSfWSek5nfsMf3gBZ9KGVFcLuw==} - dependencies: - is-buffer: 2.0.5 - vfile: 5.3.2 - dev: false - - /toggle-array@1.0.1: - resolution: {integrity: sha512-TZXgboKpD5Iu0Goi8hRXuJpE06Pbo+bies4I4jnTBhlRRgyen9c37nMylnquK/ZPKXXOeh1mJ14p9QdKp+9v7A==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: false - - /toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - /toml@3.0.0: - resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} - dev: false - - /tough-cookie@2.5.0: - resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} - engines: {node: '>=0.8'} - dependencies: - psl: 1.8.0 - punycode: 2.3.1 - dev: false - - /tough-cookie@4.1.3: - resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} - engines: {node: '>=6'} - dependencies: - psl: 1.8.0 - punycode: 2.3.1 - universalify: 0.2.0 - url-parse: 1.5.10 - dev: true - - /tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - - /tr46@4.1.1: - resolution: {integrity: sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==} - engines: {node: '>=14'} - dependencies: - punycode: 2.3.1 - dev: true - - /tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - dev: false - - /trim-lines@3.0.1: - resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} - dev: false - - /trim-newlines@3.0.1: - resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} - engines: {node: '>=8'} - dev: false - - /trough@2.0.2: - resolution: {integrity: sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==} - dev: false - - /ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - - /tsconfck@3.0.2(typescript@5.1.6): - resolution: {integrity: sha512-6lWtFjwuhS3XI4HsX4Zg0izOI3FU/AI9EGVlPEUMDIhvLPMD4wkiof0WCoDgW7qY+Dy198g4d9miAqUHWHFH6Q==} - engines: {node: ^18 || >=20} - hasBin: true - peerDependencies: - typescript: ^5.0.0 - peerDependenciesMeta: - typescript: - optional: true - dependencies: - typescript: 5.1.6 - - /tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.2 - minimist: 1.2.8 - strip-bom: 3.0.0 - dev: false - - /tsconfig-paths@4.2.0: - resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} - engines: {node: '>=6'} - dependencies: - json5: 2.2.3 - minimist: 1.2.8 - strip-bom: 3.0.0 - dev: false - - /tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: false - - /tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - - /tsscmp@1.0.6: - resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} - engines: {node: '>=0.6.x'} - dev: false - - /tsutils@3.21.0(typescript@5.1.6): - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 5.1.6 - dev: false - - /tty-table@4.1.6: - resolution: {integrity: sha512-kRj5CBzOrakV4VRRY5kUWbNYvo/FpOsz65DzI5op9P+cHov3+IqPbo1JE1ZnQGkHdZgNFDsrEjrfqqy/Ply9fw==} - engines: {node: '>=8.0.0'} - hasBin: true - dependencies: - chalk: 4.1.2 - csv: 5.5.3 - kleur: 4.1.4 - smartwrap: 2.0.2 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - yargs: 17.5.1 - dev: false - - /tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - dependencies: - safe-buffer: 5.2.1 - dev: false - - /turbo-stream@2.4.1: - resolution: {integrity: sha512-v8kOJXpG3WoTN/+at8vK7erSzo6nW6CIaeOvNOkHQVDajfz1ZVeSxCbc6tOH4hrGZW7VUCV0TOXd8CPzYnYkrw==} - dev: false - - /tweetnacl@0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} - dev: false - - /type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.2.1 - - /type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - - /type-fest@0.13.1: - resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} - engines: {node: '>=10'} - dev: false - - /type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - - /type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - - /type-fest@0.6.0: - resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} - engines: {node: '>=8'} - dev: false - - /type-fest@0.8.1: - resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} - engines: {node: '>=8'} - dev: false - - /type-fest@1.4.0: - resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} - engines: {node: '>=10'} - dev: false - - /type-fest@2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} - dev: true - - /type-fest@3.13.1: - resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} - engines: {node: '>=14.16'} - dev: false - - /type-fest@4.10.2: - resolution: {integrity: sha512-anpAG63wSpdEbLwOqH8L84urkL6PiVIov3EMmgIhhThevh9aiMQov+6Btx0wldNcvm4wV+e2/Rt1QdDwKHFbHw==} - engines: {node: '>=16'} - dev: false - - /type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - - /typed-array-buffer@1.0.1: - resolution: {integrity: sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-typed-array: 1.1.13 - dev: false - - /typed-array-byte-length@1.0.0: - resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - for-each: 0.3.3 - has-proto: 1.0.1 - is-typed-array: 1.1.13 - dev: false - - /typed-array-byte-offset@1.0.0: - resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} - engines: {node: '>= 0.4'} - dependencies: - available-typed-arrays: 1.0.6 - call-bind: 1.0.7 - for-each: 0.3.3 - has-proto: 1.0.1 - is-typed-array: 1.1.13 - dev: false - - /typed-array-length@1.0.4: - resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} - dependencies: - call-bind: 1.0.7 - for-each: 0.3.3 - is-typed-array: 1.1.13 - dev: false - - /typescript@5.1.6: - resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} - engines: {node: '>=14.17'} - hasBin: true - - /ufo@1.5.4: - resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} - - /uid-safe@2.1.5: - resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==} - engines: {node: '>= 0.8'} - dependencies: - random-bytes: 1.0.0 - dev: false - - /unbox-primitive@1.0.2: - resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} - dependencies: - call-bind: 1.0.7 - has-bigints: 1.0.2 - has-symbols: 1.0.3 - which-boxed-primitive: 1.0.2 - dev: false - - /undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: true - - /undici@5.28.4: - resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} - engines: {node: '>=14.0'} - dependencies: - '@fastify/busboy': 2.1.0 - - /undici@6.21.2: - resolution: {integrity: sha512-uROZWze0R0itiAKVPsYhFov9LxrPMHLMEQFszeI2gCN6bnIIZ8twzBCJcN2LJrBBLfrP0t1FW0g+JmKVl8Vk1g==} - engines: {node: '>=18.17'} - dev: false - - /unenv-nightly@2.0.0-1724863496.70db6f1: - resolution: {integrity: sha512-r+VIl1gnsI4WQxluruSQhy8alpAf1AsLRLm4sEKp3otCyTIVD6I6wHEYzeQnwsyWgaD4+3BD4A/eqrgOpdTzhw==} - dependencies: - defu: 6.1.4 - ohash: 1.1.3 - pathe: 1.1.2 - ufo: 1.5.4 - - /unicode-canonical-property-names-ecmascript@2.0.0: - resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} - engines: {node: '>=4'} - dev: false - - /unicode-match-property-ecmascript@2.0.0: - resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} - engines: {node: '>=4'} - dependencies: - unicode-canonical-property-names-ecmascript: 2.0.0 - unicode-property-aliases-ecmascript: 2.0.0 - dev: false - - /unicode-match-property-value-ecmascript@2.1.0: - resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} - engines: {node: '>=4'} - dev: false - - /unicode-property-aliases-ecmascript@2.0.0: - resolution: {integrity: sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==} - engines: {node: '>=4'} - dev: false - - /unified@10.1.2: - resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} - dependencies: - '@types/unist': 2.0.6 - bail: 2.0.1 - extend: 3.0.2 - is-buffer: 2.0.5 - is-plain-obj: 4.0.0 - trough: 2.0.2 - vfile: 5.3.2 - dev: false - - /unified@11.0.4: - resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==} - dependencies: - '@types/unist': 3.0.2 - bail: 2.0.1 - devlop: 1.1.0 - extend: 3.0.2 - is-plain-obj: 4.0.0 - trough: 2.0.2 - vfile: 6.0.1 - dev: false - - /unique-filename@3.0.0: - resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - unique-slug: 4.0.0 - dev: false - - /unique-slug@4.0.0: - resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - imurmurhash: 0.1.4 - dev: false - - /unist-util-generated@2.0.1: - resolution: {integrity: sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==} - dev: false - - /unist-util-is@5.1.1: - resolution: {integrity: sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==} - dev: false - - /unist-util-is@6.0.0: - resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} - dependencies: - '@types/unist': 3.0.2 - dev: false - - /unist-util-position-from-estree@1.1.2: - resolution: {integrity: sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww==} - dependencies: - '@types/unist': 2.0.6 - dev: false - - /unist-util-position-from-estree@2.0.0: - resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} - dependencies: - '@types/unist': 3.0.2 - dev: false - - /unist-util-position@4.0.4: - resolution: {integrity: sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==} - dependencies: - '@types/unist': 2.0.6 - dev: false - - /unist-util-position@5.0.0: - resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} - dependencies: - '@types/unist': 3.0.2 - dev: false - - /unist-util-remove-position@4.0.2: - resolution: {integrity: sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==} - dependencies: - '@types/unist': 2.0.6 - unist-util-visit: 4.1.1 - dev: false - - /unist-util-remove-position@5.0.0: - resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} - dependencies: - '@types/unist': 3.0.2 - unist-util-visit: 5.0.0 - dev: false - - /unist-util-remove@3.1.0: - resolution: {integrity: sha512-rO/sIghl13eN8irs5OBN2a4RC10MsJdiePCfwrvnzGtgIbHcDXr2REr0qi9F2r/CIb1r9FyyFmcMRIGs+EyUFw==} - dependencies: - '@types/unist': 2.0.6 - unist-util-is: 5.1.1 - unist-util-visit-parents: 5.1.1 - dev: false - - /unist-util-stringify-position@2.0.3: - resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} - dependencies: - '@types/unist': 2.0.6 - dev: false - - /unist-util-stringify-position@3.0.0: - resolution: {integrity: sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==} - dependencies: - '@types/unist': 2.0.6 - dev: false - - /unist-util-stringify-position@4.0.0: - resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} - dependencies: - '@types/unist': 3.0.2 - dev: false - - /unist-util-visit-parents@5.1.1: - resolution: {integrity: sha512-gks4baapT/kNRaWxuGkl5BIhoanZo7sC/cUT/JToSRNL1dYoXRFl75d++NkjYk4TAu2uv2Px+l8guMajogeuiw==} - dependencies: - '@types/unist': 2.0.6 - unist-util-is: 5.1.1 - dev: false - - /unist-util-visit-parents@6.0.1: - resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} - dependencies: - '@types/unist': 3.0.2 - unist-util-is: 6.0.0 - dev: false - - /unist-util-visit@4.1.1: - resolution: {integrity: sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg==} - dependencies: - '@types/unist': 2.0.6 - unist-util-is: 5.1.1 - unist-util-visit-parents: 5.1.1 - dev: false - - /unist-util-visit@5.0.0: - resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} - dependencies: - '@types/unist': 3.0.2 - unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 - dev: false - - /universal-user-agent@6.0.0: - resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==} - dev: false - - /universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} - dev: false - - /universalify@0.2.0: - resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} - engines: {node: '>= 4.0.0'} - dev: true - - /universalify@2.0.0: - resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} - engines: {node: '>= 10.0.0'} - dev: false - - /unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - /untildify@4.0.0: - resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} - engines: {node: '>=8'} - dev: false - - /update-browserslist-db@1.0.13(browserslist@4.22.2): - resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - dependencies: - browserslist: 4.22.2 - escalade: 3.1.1 - picocolors: 1.1.1 - - /uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - dependencies: - punycode: 2.3.1 - - /url-parse@1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - dependencies: - querystringify: 2.2.0 - requires-port: 1.0.0 - dev: true - - /util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - /util@0.12.4: - resolution: {integrity: sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==} - dependencies: - inherits: 2.0.4 - is-arguments: 1.1.1 - is-generator-function: 1.0.10 - is-typed-array: 1.1.13 - safe-buffer: 5.2.1 - which-typed-array: 1.1.14 - - /utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - - /uuid@3.4.0: - resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} - deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. - hasBin: true - dev: true - - /uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - dev: false - - /uvu@0.5.3: - resolution: {integrity: sha512-brFwqA3FXzilmtnIyJ+CxdkInkY/i4ErvP7uV0DnUVxQcQ55reuHphorpF+tZoVHK2MniZ/VJzI7zJQoc9T9Yw==} - engines: {node: '>=8'} - hasBin: true - dependencies: - dequal: 2.0.3 - diff: 5.1.0 - kleur: 4.1.4 - sade: 1.8.1 - dev: false - - /v8-to-istanbul@9.1.0: - resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} - engines: {node: '>=10.12.0'} - dependencies: - '@jridgewell/trace-mapping': 0.3.19 - '@types/istanbul-lib-coverage': 2.0.3 - convert-source-map: 1.8.0 - - /valibot@0.41.0(typescript@5.1.6): - resolution: {integrity: sha512-igDBb8CTYr8YTQlOKgaN9nSS0Be7z+WRuaeYqGf3Cjz3aKmSnqEmYnkfVjzIuumGqfHpa3fLIvMEAfhrpqN8ng==} - peerDependencies: - typescript: '>=5' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - typescript: 5.1.6 - dev: false - - /validate-npm-package-license@3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - dependencies: - spdx-correct: 3.1.1 - spdx-expression-parse: 3.0.1 - dev: false - - /validate-npm-package-name@5.0.0: - resolution: {integrity: sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - builtins: 5.0.1 - dev: false - - /vandium-utils@1.2.0: - resolution: {integrity: sha512-yxYUDZz4BNo0CW/z5w4mvclitt5zolY7zjW97i6tTE+sU63cxYs1A6Bl9+jtIQa3+0hkeqY87k+7ptRvmeHe3g==} - dev: true - - /vandium-utils@2.0.0: - resolution: {integrity: sha512-XWbQ/0H03TpYDXk8sLScBEZpE7TbA0CHDL6/Xjt37IBYKLsHUQuBlL44ttAUs9zoBOLFxsW7HehXcuWCNyqOxQ==} - engines: {node: '>=10.16'} - dev: true - - /vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - - /verror@1.10.0: - resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} - engines: {'0': node >=0.6.0} - dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.3.0 - dev: false - - /vfile-message@3.0.2: - resolution: {integrity: sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww==} - dependencies: - '@types/unist': 2.0.6 - unist-util-stringify-position: 3.0.0 - dev: false - - /vfile-message@4.0.2: - resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} - dependencies: - '@types/unist': 3.0.2 - unist-util-stringify-position: 4.0.0 - dev: false - - /vfile@5.3.2: - resolution: {integrity: sha512-w0PLIugRY3Crkgw89TeMvHCzqCs/zpreR31hl4D92y6SOE07+bfJe+dK5Q2akwS+i/c801kzjoOr9gMcTe6IAA==} - dependencies: - '@types/unist': 2.0.6 - is-buffer: 2.0.5 - unist-util-stringify-position: 3.0.0 - vfile-message: 3.0.2 - dev: false - - /vfile@6.0.1: - resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} - dependencies: - '@types/unist': 3.0.2 - unist-util-stringify-position: 4.0.0 - vfile-message: 4.0.2 - dev: false - - /vite-env-only@2.2.0: - resolution: {integrity: sha512-IgTS9TsA6sjvrS2XuC3mWsWwaRode4fi4bfnNAHdG48IZogPI/tZmNIhOdXZ+YZ+wcp/vDXTLvAjW3y1eXH6yg==} - dependencies: - '@babel/core': 7.23.7 - '@babel/generator': 7.23.6 - '@babel/parser': 7.23.6 - '@babel/traverse': 7.23.7 - '@babel/types': 7.23.6 - transitivePeerDependencies: - - supports-color - dev: true - - /vite-node@1.6.1(@types/node@18.17.1): - resolution: {integrity: sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - dependencies: - cac: 6.7.14 - debug: 4.4.0(supports-color@8.1.1) - pathe: 1.1.2 - picocolors: 1.1.1 - vite: 5.1.8(@types/node@18.17.1) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - - /vite-node@3.1.3(@types/node@18.17.1): - resolution: {integrity: sha512-uHV4plJ2IxCl4u1up1FQRrqclylKAogbtBfOTwcuJ28xFi+89PZ57BRh+naIRvH70HPwxy5QHYzg1OrEaC7AbA==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - dependencies: - cac: 6.7.14 - debug: 4.4.0(supports-color@8.1.1) - es-module-lexer: 1.7.0 - pathe: 2.0.3 - vite: 6.0.6(@types/node@18.17.1) - transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - dev: false - - /vite-tsconfig-paths@4.3.1(typescript@5.1.6)(vite@5.1.8): - resolution: {integrity: sha512-cfgJwcGOsIxXOLU/nELPny2/LUD/lcf1IbfyeKTv2bsupVbTH/xpFtdQlBmIP1GEK2CjjLxYhFfB+QODFAx5aw==} - peerDependencies: - vite: '*' - peerDependenciesMeta: - vite: - optional: true - dependencies: - debug: 4.4.0(supports-color@8.1.1) - globrex: 0.1.2 - tsconfck: 3.0.2(typescript@5.1.6) - vite: 5.1.8(@types/node@18.17.1) - transitivePeerDependencies: - - supports-color - - typescript - - /vite-tsconfig-paths@4.3.1(typescript@5.1.6)(vite@6.0.6): - resolution: {integrity: sha512-cfgJwcGOsIxXOLU/nELPny2/LUD/lcf1IbfyeKTv2bsupVbTH/xpFtdQlBmIP1GEK2CjjLxYhFfB+QODFAx5aw==} - peerDependencies: - vite: '*' - peerDependenciesMeta: - vite: - optional: true - dependencies: - debug: 4.4.0(supports-color@8.1.1) - globrex: 0.1.2 - tsconfck: 3.0.2(typescript@5.1.6) - vite: 6.0.6(@types/node@18.17.1) - transitivePeerDependencies: - - supports-color - - typescript - - /vite@5.1.8(@types/node@18.17.1): - resolution: {integrity: sha512-mB8ToUuSmzODSpENgvpFk2fTiU/YQ1tmcVJJ4WZbq4fPdGJkFNVcmVL5k7iDug6xzWjjuGDKAuSievIsD6H7Xw==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - '@types/node': 18.17.1 - esbuild: 0.19.12 - postcss: 8.4.49 - rollup: 4.29.1 - optionalDependencies: - fsevents: 2.3.3 - - /vite@6.0.6(@types/node@18.17.1): - resolution: {integrity: sha512-NSjmUuckPmDU18bHz7QZ+bTYhRR0iA72cs2QAxCqDpafJ0S6qetco0LB3WW2OxlMHS0JmAv+yZ/R3uPmMyGTjQ==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: '>=1.21.0' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - dependencies: - '@types/node': 18.17.1 - esbuild: 0.24.2 - postcss: 8.4.49 - rollup: 4.29.1 - optionalDependencies: - fsevents: 2.3.3 - - /w3c-xmlserializer@4.0.0: - resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} - engines: {node: '>=14'} - dependencies: - xml-name-validator: 4.0.0 - dev: true - - /wait-on@7.0.1: - resolution: {integrity: sha512-9AnJE9qTjRQOlTZIldAaf/da2eW0eSRSgcqq85mXQja/DW3MriHxkpODDSUEg+Gri/rKEcXUZHe+cevvYItaog==} - engines: {node: '>=12.0.0'} - hasBin: true - dependencies: - axios: 0.27.2 - joi: 17.11.0 - lodash: 4.17.21 - minimist: 1.2.8 - rxjs: 7.8.1 - transitivePeerDependencies: - - debug - dev: false - - /walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - dependencies: - makeerror: 1.0.12 - - /warning-symbol@0.1.0: - resolution: {integrity: sha512-1S0lwbHo3kNUKA4VomBAhqn4DPjQkIKSdbOin5K7EFUQNwyIKx+wZMGXKI53RUjla8V2B8ouQduUlgtx8LoSMw==} - engines: {node: '>=0.10.0'} - dev: false - - /wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - dependencies: - defaults: 1.0.3 - - /web-encoding@1.1.5: - resolution: {integrity: sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==} - dependencies: - util: 0.12.4 - optionalDependencies: - '@zxing/text-encoding': 0.9.0 - - /web-streams-polyfill@3.2.0: - resolution: {integrity: sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==} - engines: {node: '>= 8'} - dev: false - - /webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - - /webidl-conversions@7.0.0: - resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} - engines: {node: '>=12'} - dev: true - - /whatwg-encoding@2.0.0: - resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} - engines: {node: '>=12'} - dependencies: - iconv-lite: 0.6.3 - dev: true - - /whatwg-mimetype@3.0.0: - resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} - engines: {node: '>=12'} - dev: true - - /whatwg-url@12.0.1: - resolution: {integrity: sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==} - engines: {node: '>=14'} - dependencies: - tr46: 4.1.1 - webidl-conversions: 7.0.0 - dev: true - - /whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - - /which-boxed-primitive@1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} - dependencies: - is-bigint: 1.0.4 - is-boolean-object: 1.1.2 - is-number-object: 1.0.6 - is-string: 1.0.7 - is-symbol: 1.0.4 - dev: false - - /which-builtin-type@1.1.3: - resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} - engines: {node: '>= 0.4'} - dependencies: - function.prototype.name: 1.1.6 - has-tostringtag: 1.0.2 - is-async-function: 2.0.0 - is-date-object: 1.0.5 - is-finalizationregistry: 1.0.2 - is-generator-function: 1.0.10 - is-regex: 1.1.4 - is-weakref: 1.0.2 - isarray: 2.0.5 - which-boxed-primitive: 1.0.2 - which-collection: 1.0.1 - which-typed-array: 1.1.14 - dev: false - - /which-collection@1.0.1: - resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} - dependencies: - is-map: 2.0.2 - is-set: 2.0.2 - is-weakmap: 2.0.1 - is-weakset: 2.0.2 - dev: false - - /which-module@2.0.0: - resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} - dev: false - - /which-pm@2.0.0: - resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==} - engines: {node: '>=8.15'} - dependencies: - load-yaml-file: 0.2.0 - path-exists: 4.0.0 - dev: false - - /which-typed-array@1.1.14: - resolution: {integrity: sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==} - engines: {node: '>= 0.4'} - dependencies: - available-typed-arrays: 1.0.6 - call-bind: 1.0.7 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.2 - - /which@1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true - dependencies: - isexe: 2.0.0 - dev: false - - /which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - dependencies: - isexe: 2.0.0 - - /which@3.0.1: - resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true - dependencies: - isexe: 2.0.0 - dev: false - - /window-size@1.1.1: - resolution: {integrity: sha512-5D/9vujkmVQ7pSmc0SCBmHXbkv6eaHwXEx65MywhmUMsI8sGqJ972APq1lotfcwMKPFLuCFfL8xGHLIp7jaBmA==} - engines: {node: '>= 0.10.0'} - hasBin: true - dependencies: - define-property: 1.0.0 - is-number: 3.0.0 - dev: false - - /workerd@1.20240821.1: - resolution: {integrity: sha512-y4phjCnEG96u8ZkgkkHB+gSw0i6uMNo23rBmixylWpjxDklB+LWD8dztasvsu7xGaZbLoTxQESdEw956F7VJDA==} - engines: {node: '>=16'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@cloudflare/workerd-darwin-64': 1.20240821.1 - '@cloudflare/workerd-darwin-arm64': 1.20240821.1 - '@cloudflare/workerd-linux-64': 1.20240821.1 - '@cloudflare/workerd-linux-arm64': 1.20240821.1 - '@cloudflare/workerd-windows-64': 1.20240821.1 - - /wrangler@3.74.0(@cloudflare/workers-types@4.20240208.0): - resolution: {integrity: sha512-wmtb+tQrgb61yN+Wa2JM98G1Gt4tKFRYPw6xwuyzUcA74L+Dum1A13w22/manl9Gq1jA3dPn+7UzT5sYEVHRog==} - engines: {node: '>=16.17.0'} - hasBin: true - peerDependencies: - '@cloudflare/workers-types': ^4.20240821.1 - peerDependenciesMeta: - '@cloudflare/workers-types': - optional: true - dependencies: - '@cloudflare/kv-asset-handler': 0.3.4 - '@cloudflare/workers-shared': 0.4.1 - '@cloudflare/workers-types': 4.20240208.0 - '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) - '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) - blake3-wasm: 2.1.5 - chokidar: 3.6.0 - date-fns: 3.6.0 - esbuild: 0.17.19 - miniflare: 3.20240821.1 - nanoid: 3.3.7 - path-to-regexp: 6.2.1 - resolve: 1.22.8 - resolve.exports: 2.0.2 - selfsigned: 2.4.1 - source-map: 0.6.1 - unenv: /unenv-nightly@2.0.0-1724863496.70db6f1 - workerd: 1.20240821.1 - xxhash-wasm: 1.0.2 - optionalDependencies: - fsevents: 2.3.3 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - /wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - /wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - /wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - /write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - imurmurhash: 0.1.4 - signal-exit: 3.0.7 - - /ws@7.5.10: - resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} - engines: {node: '>=8.3.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: false - - /ws@8.18.0: - resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - /xml-name-validator@4.0.0: - resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} - engines: {node: '>=12'} - dev: true - - /xmlchars@2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - dev: true - - /xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - dev: false - - /xxhash-wasm@1.0.2: - resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} - - /y18n@4.0.3: - resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} - dev: false - - /y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - /yallist@2.1.2: - resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} - dev: false - - /yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - - /yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - - /yaml@2.3.4: - resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} - engines: {node: '>= 14'} - - /yargs-parser@18.1.3: - resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} - engines: {node: '>=6'} - dependencies: - camelcase: 5.3.1 - decamelize: 1.2.0 - dev: false - - /yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - dev: false - - /yargs-parser@21.0.1: - resolution: {integrity: sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==} - engines: {node: '>=12'} - - /yargs@15.4.1: - resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} - engines: {node: '>=8'} - dependencies: - cliui: 6.0.0 - decamelize: 1.2.0 - find-up: 4.1.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - require-main-filename: 2.0.0 - set-blocking: 2.0.0 - string-width: 4.2.3 - which-module: 2.0.0 - y18n: 4.0.3 - yargs-parser: 18.1.3 - dev: false - - /yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - dependencies: - cliui: 7.0.4 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - dev: false - - /yargs@17.5.1: - resolution: {integrity: sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==} - engines: {node: '>=12'} - dependencies: - cliui: 7.0.4 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.0.1 - - /yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - dev: false - - /yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - - /youch@3.3.3: - resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} - dependencies: - cookie: 0.5.0 - mustache: 4.2.0 - stacktracey: 2.1.8 - - /zod@3.22.4: - resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} - - /zwitch@2.0.2: - resolution: {integrity: sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==} - dev: false diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml deleted file mode 100644 index cae0a89b7ea..00000000000 --- a/pnpm-workspace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -packages: - - "integration" - - "integration/helpers/*" - - "packages/*" diff --git a/prettier.config.js b/prettier.config.js deleted file mode 100644 index 27cca4c3daf..00000000000 --- a/prettier.config.js +++ /dev/null @@ -1,2 +0,0 @@ -/** @type {import('prettier').Options} */ -module.exports = {}; diff --git a/rollup.config.js b/rollup.config.js deleted file mode 100644 index b294f70ac01..00000000000 --- a/rollup.config.js +++ /dev/null @@ -1,15 +0,0 @@ -const fs = require("node:fs"); -const path = require("node:path"); - -module.exports = function rollup(options) { - return fs.readdirSync("packages").flatMap((dir) => { - let configPath = path.join("packages", dir, "rollup.config.js"); - try { - fs.readFileSync(configPath); - } catch { - return []; - } - let packageBuild = require(`.${path.sep}${configPath}`); - return packageBuild(options); - }); -}; diff --git a/rollup.utils.js b/rollup.utils.js deleted file mode 100644 index 4d46afe4bde..00000000000 --- a/rollup.utils.js +++ /dev/null @@ -1,239 +0,0 @@ -const babel = require("@rollup/plugin-babel").default; -const copy = require("rollup-plugin-copy"); -const fs = require("node:fs"); -const fse = require("fs-extra"); -const nodeResolve = require("@rollup/plugin-node-resolve").default; -const path = require("node:path"); - -const REPO_ROOT_DIR = __dirname; - -let activeOutputDir = "build"; -if (process.env.LOCAL_BUILD_DIRECTORY) { - let appDir = path.resolve(process.env.LOCAL_BUILD_DIRECTORY); - try { - fse.readdirSync(path.join(appDir, "node_modules")); - } catch { - console.error( - "Oops! You pointed LOCAL_BUILD_DIRECTORY to a directory that " + - "does not have a node_modules/ folder. Please `npm install` in that " + - "directory and try again." - ); - process.exit(1); - } - console.log("Writing rollup output to", appDir); - activeOutputDir = appDir; -} - -/** - * @param {string} packageName - * @param {string} version - * @param {boolean} [executable] - */ -function createBanner(packageName, version, executable = false) { - let banner = `/** - * ${packageName} v${version} - * - * Copyright (c) Remix Software Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE.md file in the root directory of this source tree. - * - * @license MIT - */`; - return executable ? "#!/usr/bin/env node\n" + banner : banner; -} - -/** - * @param {string} packageDir - */ -function getVersion(packageDir) { - return require(`./${packageDir}/package.json`).version; -} - -/** - * @param {string} id - */ -function isBareModuleId(id) { - return !id.startsWith(".") && !path.isAbsolute(id); -} - -/** - * @param {string} appDir - */ -async function triggerLiveReload(appDir) { - // Tickle live reload by touching the server entry - // Consider all of entry.server.{tsx,ts,jsx,js} since React may be used - // via `React.createElement` without the need for JSX. - let serverEntryPaths = [ - "entry.server.ts", - "entry.server.tsx", - "entry.server.js", - "entry.server.jsx", - ]; - let serverEntryPath = serverEntryPaths - .map((entryFile) => path.join(appDir, "app", entryFile)) - .find((entryPath) => fse.existsSync(entryPath)); - if (serverEntryPath) { - let date = new Date(); - await fs.promises.utimes(serverEntryPath, date, date); - } -} - -/** - * @param {string} packageName - * @returns {import("rollup").Plugin} - */ -function copyPublishFiles(packageName) { - let sourceDir = `packages/${getPackageDirname(packageName)}`; - let outputDir = getOutputDir(packageName); - return copy({ - targets: [ - { src: "LICENSE.md", dest: [outputDir, sourceDir] }, - { src: `${sourceDir}/package.json`, dest: outputDir }, - { src: `${sourceDir}/README.md`, dest: outputDir }, - { src: `${sourceDir}/CHANGELOG.md`, dest: outputDir }, - ], - }); -} - -/** - * @returns {import("rollup").Plugin} - */ -function copyToPlaygrounds() { - return { - name: "copy-to-remix-playground", - async writeBundle(options, bundle) { - if (activeOutputDir === "build") { - let playgroundsDir = path.join(REPO_ROOT_DIR, "playground"); - let playgrounds = await fs.promises.readdir(playgroundsDir); - let writtenDir = path.join(REPO_ROOT_DIR, options.dir); - for (let playground of playgrounds) { - let playgroundDir = path.join(playgroundsDir, playground); - if (!fse.statSync(playgroundDir).isDirectory()) { - continue; - } - let destDir = writtenDir.replace( - path.join(REPO_ROOT_DIR, "build"), - playgroundDir - ); - fse.copySync(writtenDir, destDir); - await triggerLiveReload(playgroundDir); - } - } else { - // Otherwise, trigger live reload on our LOCAL_BUILD_DIRECTORY folder - await triggerLiveReload(activeOutputDir); - } - }, - }; -} - -/** - * @param {RemixAdapter} adapterName - * @returns {import("rollup").RollupOptions} - */ -function getAdapterConfig(adapterName) { - /** @type {`@remix-run/${RemixAdapter}`} */ - let packageName = `@remix-run/${adapterName}`; - let sourceDir = `packages/remix-${adapterName}`; - let outputDir = getOutputDir(packageName); - let outputDist = path.join(outputDir, "dist"); - let version = getVersion(sourceDir); - - return { - external(id) { - return isBareModuleId(id); - }, - input: `${sourceDir}/index.ts`, - output: { - banner: createBanner(packageName, version), - dir: outputDist, - format: "cjs", - preserveModules: true, - exports: "auto", - }, - plugins: [ - babel({ - babelHelpers: "bundled", - exclude: /node_modules/, - extensions: [".ts", ".tsx"], - }), - nodeResolve({ extensions: [".ts", ".tsx"] }), - copyPublishFiles(packageName), - copyToPlaygrounds(), - ], - }; -} - -/** - * @param {{ packageName: string; version: string }} args - * @returns {import("rollup").RollupOptions} - */ -function getCliConfig({ packageName, version }) { - let sourceDir = `packages/${getPackageDirname(packageName)}`; - let outputDir = getOutputDir(packageName); - let outputDist = path.join(outputDir, "dist"); - return { - external() { - return true; - }, - input: `${sourceDir}/cli.ts`, - output: { - banner: createBanner(packageName, version, true), - dir: outputDist, - format: "cjs", - }, - plugins: [ - babel({ - babelHelpers: "bundled", - exclude: /node_modules/, - extensions: [".ts"], - }), - nodeResolve({ extensions: [".ts"] }), - { - name: "dynamic-import-polyfill", - renderDynamicImport() { - return { - left: "import(", - right: ")", - }; - }, - }, - copyPublishFiles(packageName), - copyToPlaygrounds(), - ], - }; -} - -/** - * @param {string} packageName - */ -function getOutputDir(packageName) { - return path.join(activeOutputDir, "node_modules", packageName); -} - -/** - * @param {string} packageName - */ -function getPackageDirname(packageName) { - let scope = "@remix-run/"; - return packageName.startsWith(scope) - ? `remix-${packageName.slice(scope.length)}` - : packageName; -} - -module.exports = { - copyPublishFiles, - copyToPlaygrounds, - createBanner, - getAdapterConfig, - getCliConfig, - getOutputDir, - isBareModuleId, -}; - -/** - * @typedef {"architect" | "cloudflare-pages" | "cloudflare-workers" | "express"} RemixAdapter - * @typedef {"cloudflare" | "node" | "deno"} RemixRuntime - * @typedef {`@remix-run/${RemixAdapter | RemixRuntime | "dev" | "eslint-config" | "react" | "serve" | "server-runtime"}`} ScopedRemixPackage - * @typedef {"create-remix" | "remix" | ScopedRemixPackage} RemixPackage - */ diff --git a/scripts/build.mjs b/scripts/build.mjs deleted file mode 100644 index dfeed704350..00000000000 --- a/scripts/build.mjs +++ /dev/null @@ -1,41 +0,0 @@ -import { spawn } from "cross-spawn"; - -const args = process.argv.slice(2); -const tsc = process.env.CI || args.includes("--tsc"); - -exec("pnpm", ["rollup", "-c"]) - .then(() => tsc && exec("pnpm", ["--recursive", "tsc", "-b"])) - .then(() => - exec("node", ["scripts/copy-build-to-dist.mjs", ...(tsc ? ["--tsc"] : [])]) - ) - .then(() => process.exit(0)) - .catch((err) => { - console.error(err); - process.exit(1); - }); - -/** - * @param {string} command - * @param {string[]} [args] - */ -function exec(command, args) { - /** @type {(data: any) => any} */ - let handleData = (data) => console.log(data.toString().trim()); - - /** @type {(data: Error) => any} */ - let handleError = (data) => console.error(data.toString().trim()); - - return new Promise((resolve, reject) => { - let ls = spawn(command, args, { cwd: process.cwd() }); - ls.stdout.on("data", handleData); - ls.stderr.on("data", handleData); - ls.on("error", handleError); - ls.on("close", (code) => { - if (code === 0) { - resolve(void 0); - } else { - reject(new Error(`${command} exited with code ${code}`)); - } - }); - }); -} diff --git a/scripts/bump-fetch-versions.sh b/scripts/bump-fetch-versions.sh deleted file mode 100755 index 8813e78fc2e..00000000000 --- a/scripts/bump-fetch-versions.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -VERSION="${1}" - -if [ "${VERSION}" == "" ]; then - VERSION="latest" -fi - - -echo "Updating the undici dependencies to version '${VERSION}'" -echo "" - -if [ ! -d "packages/remix-node" ]; then - echo "Must be run from the remix repository" - exit 1 -fi - -set -x - -cd packages/remix-node -pnpm add undici@${VERSION} -cd ../.. - -set +x \ No newline at end of file diff --git a/scripts/bump-router-versions.sh b/scripts/bump-router-versions.sh deleted file mode 100755 index 6c492db67c9..00000000000 --- a/scripts/bump-router-versions.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -ROUTER_VERSION="${1}" -RR_VERSION="${2}" - -if [ "${ROUTER_VERSION}" == "" ]; then - ROUTER_VERSION="latest" - RR_VERSION="latest" -elif [ "${RR_VERSION}" == "" ]; then - RR_VERSION="${ROUTER_VERSION}" -fi - - -echo "Updating the React Router dependencies to the following versions:" -echo " @remix-run/router -> ${ROUTER_VERSION}" -echo " react-router-dom -> ${RR_VERSION}" -echo "" - -if [ ! -d "packages/remix-server-runtime" ]; then - echo "Must be run from the remix repository" - exit 1 -fi - -set -x - -cd packages/remix-dev -npx pnpm@8 add -E @remix-run/router@${ROUTER_VERSION} -cd ../.. - -cd packages/remix-server-runtime -npx pnpm@8 add -E @remix-run/router@${ROUTER_VERSION} -cd ../.. - -cd packages/remix-react -npx pnpm@8 add -E @remix-run/router@${ROUTER_VERSION} react-router@${RR_VERSION} react-router-dom@${RR_VERSION} -cd ../.. - -cd packages/remix-testing -npx pnpm@8 add -E @remix-run/router@${ROUTER_VERSION} react-router-dom@${RR_VERSION} -cd ../.. - -cd integration -npx pnpm@8 add -E @remix-run/router@${ROUTER_VERSION} -cd .. - -# Because deplicates... -npx pnpm@8 dedupe && rm -rf ./node_modules && npx pnpm@8 install - -set +x \ No newline at end of file diff --git a/scripts/clean-build.mjs b/scripts/clean-build.mjs deleted file mode 100644 index 78e31b173d9..00000000000 --- a/scripts/clean-build.mjs +++ /dev/null @@ -1,35 +0,0 @@ -import path from "node:path"; -import fse from "fs-extra"; -import chalk from "chalk"; - -const ROOT_DIR = process.cwd(); -const BUILD_PATH = path.join(ROOT_DIR, "build"); -const PACKAGES_PATH = path.join(ROOT_DIR, "packages"); - -cleanBuild(); - -async function cleanBuild() { - /** @type {Promise[]} */ - let deleteQueue = [removeDir(BUILD_PATH)]; - for (let fileName of await fse.readdir(PACKAGES_PATH)) { - let buildPath = path.join(PACKAGES_PATH, fileName, "dist"); - deleteQueue.push(removeDir(buildPath)); - } - await Promise.all(deleteQueue); - console.log(chalk.green(" ✅ Successfully deleted build files!")); -} - -/** - * @param {string} dir - */ -async function removeDir(dir) { - try { - if (!(await fse.stat(dir)).isDirectory()) { - return; - } - } catch (_) { - return; - } - console.log(chalk.yellow(` 🛠 Deleting ${path.relative(ROOT_DIR, dir)}`)); - await fse.remove(dir); -} diff --git a/scripts/close-v2-issues-comment.md b/scripts/close-v2-issues-comment.md deleted file mode 100644 index 32ac730da95..00000000000 --- a/scripts/close-v2-issues-comment.md +++ /dev/null @@ -1,17 +0,0 @@ -Thank you for opening this issue, and our apologies we haven't gotten around to it yet! - -With the release of [React Router v7](https://remix.run/blog/react-router-v7) we are sun-setting continued development/maintenance on Remix v2. If you have not already [upgraded to React Router v7](https://reactrouter.com/upgrading/remix), we recommend you do so. We've tried to make the upgrade process as smooth as possible with our [Future Flags](https://remix.run/docs/en/main/start/future-flags). We are now in the process of cleaning up outdated issues and pull requests to improve the overall hygiene of our repositories. - -We plan to continue to address 2 types of issues in Remix v2: - -- Bugs that pose security concerns -- Bugs that prevent upgrading to React Router v7 - -If you believe this issue meets one of those criteria, please respond or [create a new issue](https://github.com/remix-run/remix/issues/new?template=bug_report.yml). - -For all other issues, ongoing maintenance will be happening in React Router v7, so: - -- If this is a bug, please reopen this issue [in that repo](https://github.com/remix-run/react-router/issues/new?template=bug_report.yml) with a new [minimal reproduction](https://reactrouter.com/new) against v7 -- If this is a feature request, please open a new [Proposal Discussion](https://github.com/remix-run/react-router/discussions/new?category=proposals) in React Router, and if it gets enough community support it can be considered for implementation - -If you have any questions you can always reach out on [Discord](https://rmx.as/discord). Thanks again for providing feedback and helping us make our framework even better! diff --git a/scripts/close-v2-issues.mjs b/scripts/close-v2-issues.mjs deleted file mode 100644 index 651c16af575..00000000000 --- a/scripts/close-v2-issues.mjs +++ /dev/null @@ -1,107 +0,0 @@ -import { execSync } from "node:child_process"; -import { parseArgs } from "node:util"; - -const CI = process.env.CI === "true"; - -let oneYearAgo = new Date(Date.now() - 365 * 24 * 60 * 60 * 1000); - -const { values: args } = parseArgs({ - options: { - date: { - type: "string", - short: "d", - default: new Date(oneYearAgo).toISOString().substring(0, 10), - }, - type: { - type: "string", - short: "t", - default: "issues", // issues | prs - }, - }, - strict: true, -}); - -console.log(args); - -if (!args.type || !["issues", "prs"].includes(args.type)) { - console.error("Missing or invalid date - expected YYYY-MM-DD."); - process.exit(1); -} else if (!args.date || !/^\d{4}-\d{2}-\d{2}$/.test(args.date)) { - console.error("Missing or invalid date - expected YYYY-MM-DD."); - process.exit(1); -} else { - run(); -} - -async function run() { - /** @type {(ms: number) => Promise} */ - let sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); - - let isPullRequests = args.type === "prs"; - - /** @type {(q: string) => string} */ - let getQueryCmd = (q) => - isPullRequests - ? `gh pr list --search "${q}" --json number` - : `gh issue list --search "${q}" --json number`; - - /** @type {(n: number) => string} */ - let getCommentCmd = (n) => - isPullRequests - ? `gh pr comment ${n} -F ./scripts/close-v2-prs-comment.md` - : `gh issue comment ${n} -F ./scripts/close-v2-issues-comment.md`; - - /** @type {(n: number) => string} */ - let getCloseCmd = (n) => - isPullRequests - ? `gh pr close ${n}` - : `gh issue close ${n} -r "not planned"`; - - let query = isPullRequests - ? `is:pr is:open updated:<${args.date}` - : `is:issue state:open updated:<${args.date}`; - let issueCmd = getQueryCmd(query); - console.log(`Executing command: ${issueCmd}`); - - let result = execSync(issueCmd).toString(); - console.log(`Result: ${result}`); - - let issues = JSON.parse(result).map((i) => i.number); - if (issues.length > 50) { - console.log( - "❌ Refusing to close more than 50 issues/PRs at once, exiting." - ); - process.exit(1); - } - - let label = isPullRequests ? "PR" : "issue"; - - console.log(`Parsed ${issues.length} ${label}s`); - - for (let issue of issues) { - console.log(`--- Processing ${label} #${issue} ---`); - let commentResult = runCmdIfTokenExists(getCommentCmd(issue)); - console.log(`Commented on ${label} #${issue}: ${commentResult}`); - await sleep(250); - - runCmdIfTokenExists(getCloseCmd(issue)); - // No log here since the GH CLI already logs for issue close - await sleep(250); - } - - console.log("Done!"); -} - -/** - * @param {string} cmd - * @return {string} - */ -function runCmdIfTokenExists(cmd) { - if (CI) { - console.log(); - return execSync(cmd).toString(); - } else { - console.log(`⚠️ Local run, skipping command: ${cmd}`); - return ""; - } -} diff --git a/scripts/close-v2-prs-comment.md b/scripts/close-v2-prs-comment.md deleted file mode 100644 index 6d2c4458996..00000000000 --- a/scripts/close-v2-prs-comment.md +++ /dev/null @@ -1,17 +0,0 @@ -Thank you for opening this pull request, and our apologies we haven't gotten around to it yet! - -With the release of [React Router v7](https://remix.run/blog/react-router-v7) we are sun-setting continued development/maintenance on Remix v2. If you have not already [upgraded to React Router v7](https://reactrouter.com/upgrading/remix), we recommend you do so. We've tried to make the upgrade process as smooth as possible with our [Future Flags](https://remix.run/docs/en/main/start/future-flags). We are now in the process of cleaning up outdated issues and pull requests to improve the overall hygiene of our repositories. - -We plan to continue to address 2 types of issues in Remix v2: - -- Bugs that pose security concerns -- Bugs that prevent upgrading to React Router v7 - -If you believe this pull request meets one of those criteria, please respond or create a new pull request so it pops up on our radar (since github notifications may get lost in the noise 😕). - -For all other issues/changes, ongoing maintenance will be happening in React Router v7, so: - -- If this is a bug fix, please reopen against [React Router v7](https://github.com/remix-run/react-router) -- If this is a new feature, please open a new [Proposal Discussion](https://github.com/remix-run/react-router/discussions/new?category=proposals) in React Router, and if it gets enough community support it can be considered for implementation - -If you have any questions you can always reach out on [Discord](https://rmx.as/discord). Thanks again for providing feedback and helping us make our framework even better! diff --git a/scripts/compile-release-notes.mjs b/scripts/compile-release-notes.mjs deleted file mode 100644 index 31606feea30..00000000000 --- a/scripts/compile-release-notes.mjs +++ /dev/null @@ -1,167 +0,0 @@ -import * as fs from "node:fs"; -import path from "node:path"; -import * as url from "node:url"; -import remarkParse from "remark-parse"; -import remarkGfm from "remark-gfm"; -import rehypeStringify from "remark-stringify"; -import remarkFrontmatter from "remark-frontmatter"; -import { unified } from "unified"; -import parseFrontMatter from "front-matter"; - -// Wrote this quick and dirty, gets the job done, plz don't judge me. The idea -// is not to auto-generate release notes but to quickly compile all changesets -// into a single document from which we can easily reference changes to write -// the release notes. Much faster than going back and forth between files! The -// generated markdown file should be in .gitignore, as it's only there as a -// reference. - -const __dirname = url.fileURLToPath(new URL(".", import.meta.url)); -const rootDir = path.join(__dirname, ".."); -const changesetsDir = path.join(rootDir, ".changeset"); -const releaseNotesPath = path.join(rootDir, "RELEASENOTES.md"); - -main(); - -async function main() { - let changesets = getChangesetPaths(); - /** @type {ReleaseNotes[]} */ - let majorReleaseNotes = []; - /** @type {ReleaseNotes[]} */ - let minorReleaseNotes = []; - /** @type {ReleaseNotes[]} */ - let patchReleaseNotes = []; - - /** @type {import('unified').Processor} */ - let markdownProcessor = await unified() - .use({ - settings: { - fences: true, - listItemIndent: "one", - tightDefinitions: true, - }, - }) - // We have multiple versions of remark-parse, TS resolves the wrong one - // @ts-expect-error - .use(remarkParse) - .use(remarkGfm) - .use(remarkFrontmatter, ["yaml", "toml"]) - // same problem - // @ts-expect-error - .use(rehypeStringify, { - bullet: "-", - emphasis: "_", - listItemIndent: "one", - }); - - for (let changeset of changesets) { - let fileContents = fs.readFileSync(changeset, "utf-8"); - let markdown = await markdownProcessor.process(fileContents); - - /** @type {{attributes: unknown; body: string}} */ - let { attributes, body } = parseFrontMatter(markdown.toString()); - if (!isPlainObject(attributes)) { - // 🤷‍♀️ - continue; - } - - let affectedPackages = Object.keys(attributes); - let releaseTypes = Object.values(attributes); - if (releaseTypes.includes("major")) { - majorReleaseNotes.push({ affectedPackages, body }); - } else if (releaseTypes.includes("minor")) { - minorReleaseNotes.push({ affectedPackages, body }); - } else { - patchReleaseNotes.push({ affectedPackages, body }); - } - } - - let i = 0; - let fileContents = ""; - for (let releaseNotes of [ - majorReleaseNotes, - minorReleaseNotes, - patchReleaseNotes, - ]) { - if (releaseNotes.length === 0) { - i++; - continue; - } - - let heading = - "## " + - (i === 0 - ? "Major Changes" - : i === 1 - ? "Minor Changes" - : "Patch Changes") + - "\n"; - let body = ""; - /** @type {string[]} */ - let affectedPackages = []; - for (let note of releaseNotes) { - affectedPackages = uniq(affectedPackages, note.affectedPackages); - body += `${note.body - .split("\n") - .filter(Boolean) - .map(bulletize) - .join("\n")}\n`; - } - body = `- Affected packages: \n - ${affectedPackages - .map((p) => "`" + p + "`") - .join("\n - ")}\n${body}`; - fileContents += heading + "\n" + body + "\n"; - i++; - } - - await fs.promises.writeFile(releaseNotesPath, fileContents.trim(), "utf-8"); - - console.log("✅ Donezo"); -} - -/** - * @param {string} fileName - * @returns - */ -function isChangeset(fileName) { - return fileName.endsWith(".md") && path.basename(fileName) !== "README.md"; -} - -function getChangesetPaths() { - return fs - .readdirSync(changesetsDir) - .filter((fileName) => isChangeset(fileName)) - .map((fileName) => path.join(changesetsDir, fileName)); -} - -/** - * - * @param {unknown} obj - * @returns {obj is Record} - */ -function isPlainObject(obj) { - return !!obj && Object.prototype.toString.call(obj) === "[object Object]"; -} - -/** @typedef {{ affectedPackages: string[]; body: string }} ReleaseNotes */ - -/** - * @param {...any} arrays - * @returns - */ -function uniq(...arrays) { - return [...new Set(arrays.flat())]; -} - -/** - * @param {string} str - * @param {number} i - */ -function bulletize(str, i) { - if (i === 0) { - return "- " + str.trim().replace(/^- /, ""); - } - if (str.startsWith("- ")) { - return " " + str.trim(); - } - return " - " + str.trim(); -} diff --git a/scripts/copy-build-to-dist.mjs b/scripts/copy-build-to-dist.mjs deleted file mode 100644 index 1ad3808f83a..00000000000 --- a/scripts/copy-build-to-dist.mjs +++ /dev/null @@ -1,169 +0,0 @@ -import path from "node:path"; -import fse from "fs-extra"; -import chalk from "chalk"; - -const args = process.argv.slice(2); -const tsc = process.env.CI || args.includes("--tsc"); - -const ROOT_DIR = process.cwd(); -const PACKAGES_PATH = path.join(ROOT_DIR, "packages"); -const DEFAULT_BUILD_PATH = path.join(ROOT_DIR, "build"); - -let activeOutputDir = DEFAULT_BUILD_PATH; -if (process.env.LOCAL_BUILD_DIRECTORY) { - let appDir = path.resolve(process.env.LOCAL_BUILD_DIRECTORY); - try { - fse.readdirSync(path.join(appDir, "node_modules")); - } catch { - console.error( - "Oops! You pointed `LOCAL_BUILD_DIRECTORY` to a directory that " + - "does not have a `node_modules` folder. Please `npm install` in that " + - "directory and try again." - ); - process.exit(1); - } - activeOutputDir = appDir; -} - -copyBuildToDist(); - -async function copyBuildToDist() { - let buildPath = getBuildPath(); - let packages = (await getPackageBuildPaths(buildPath)).map((buildDir) => { - let parentDir = path.basename(path.dirname(buildDir)); - let dirName = path.basename(buildDir); - return { - build: buildDir, - src: path.join( - PACKAGES_PATH, - parentDir === "@remix-run" ? `remix-${dirName}` : dirName - ), - }; - }); - - // Write an export shim for @remix-run/node/globals types - let dest = path.join( - ".", - "build", - "node_modules", - "@remix-run", - "node", - "globals.d.ts" - ); - console.log(chalk.yellow(` 🛠 Writing globals.d.ts shim to ${dest}`)); - await fse.writeFile(dest, "export * from './dist/globals';"); - - /** @type {Promise[]} */ - let copyQueue = []; - for (let pkg of packages) { - try { - let srcPath = path.join(pkg.build, "dist"); - let destPath = path.join(pkg.src, "dist"); - if (!(await fse.stat(srcPath)).isDirectory()) { - continue; - } - copyQueue.push( - (async () => { - console.log( - chalk.yellow( - ` 🛠 Copying ${path.relative( - ROOT_DIR, - srcPath - )} to ${path.relative(ROOT_DIR, destPath)}` - ) - ); - fse.copy(srcPath, destPath, { - recursive: true, - }); - })() - ); - } catch {} - } - - // One-off deep import copies so folks don't need to import from inside of - // dist/. TODO: Remove in a future major release and either get rid of the - // deep import or manage with the package.json "exports" field - let oneOffCopies = [ - // server-build.js built by rollup outside of dist/, need to copy to - // packages/ dir outside of dist/ - [ - "build/node_modules/@remix-run/dev/server-build.js", - "packages/remix-dev/server-build.js", - ], - // server-build.d.ts only built by tsc to dist/. Copy outside of dist/ - // both in build/ and packages/ dir - ...(tsc - ? [ - [ - "build/node_modules/@remix-run/dev/dist/server-build.d.ts", - "build/node_modules/@remix-run/dev/server-build.d.ts", - ], - [ - "build/node_modules/@remix-run/dev/dist/server-build.d.ts", - "packages/remix-dev/server-build.d.ts", - ], - // globals.d.ts shim written outside of dist/ in above, copy to packages/ - // dir outside of dist/ - [ - "build/node_modules/@remix-run/node/globals.d.ts", - "packages/remix-node/globals.d.ts", - ], - ] - : []), - ]; - - oneOffCopies.forEach(([srcFile, destFile]) => - copyQueue.push( - (async () => { - let src = path.relative(ROOT_DIR, path.join(...srcFile.split("/"))); - let dest = path.relative(ROOT_DIR, path.join(...destFile.split("/"))); - console.log(chalk.yellow(` 🛠 Copying ${src} to ${dest}`)); - await fse.copy(src, dest); - })() - ) - ); - - await Promise.all(copyQueue); - console.log( - chalk.green( - " ✅ Successfully copied build files to package dist directories!" - ) - ); -} - -/** - * @param {string} moduleRootDir - * @returns {Promise} - */ -async function getPackageBuildPaths(moduleRootDir) { - /** @type {string[]} */ - let packageBuilds = []; - - try { - for (let fileName of await fse.readdir(moduleRootDir)) { - let moduleDir = path.join(moduleRootDir, fileName); - if (!(await fse.stat(moduleDir)).isDirectory()) { - continue; - } - if (path.basename(moduleDir) === "@remix-run") { - packageBuilds.push(...(await getPackageBuildPaths(moduleDir))); - } else if ( - /node_modules[/\\]@remix-run[/\\]/.test(moduleDir) || - /node_modules[/\\]create-remix/.test(moduleDir) || - /node_modules[/\\]remix/.test(moduleDir) - ) { - packageBuilds.push(moduleDir); - } - } - return packageBuilds; - } catch (_) { - console.error( - "No build files found. Run `pnpm build` before running this script." - ); - process.exit(1); - } -} - -function getBuildPath() { - return path.join(activeOutputDir, "node_modules"); -} diff --git a/scripts/copy-templates-to-fixtures.sh b/scripts/copy-templates-to-fixtures.sh deleted file mode 100644 index 3b46687aa69..00000000000 --- a/scripts/copy-templates-to-fixtures.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -set -x - -cp -r templates/cloudflare-pages/* packages/remix-dev/__tests__/fixtures/cloudflare/ -rm -f packages/remix-dev/__tests__/fixtures/cloudflare/app/entry.client.tsx -rm -f packages/remix-dev/__tests__/fixtures/cloudflare/app/entry.server.tsx - -cp -r templates/deno/* packages/remix-dev/__tests__/fixtures/deno/ -rm -f packages/remix-dev/__tests__/fixtures/deno/app/entry.client.tsx -rm -f packages/remix-dev/__tests__/fixtures/deno/app/entry.server.tsx - -cp -r templates/remix/* packages/remix-dev/__tests__/fixtures/node/ -rm -f packages/remix-dev/__tests__/fixtures/node/app/entry.client.tsx -rm -f packages/remix-dev/__tests__/fixtures/node/app/entry.server.tsx - -set +x diff --git a/scripts/deployment-test/_shared.mjs b/scripts/deployment-test/_shared.mjs deleted file mode 100644 index 467b4d3bbcb..00000000000 --- a/scripts/deployment-test/_shared.mjs +++ /dev/null @@ -1,148 +0,0 @@ -import path from "node:path"; -import { fileURLToPath } from "node:url"; -import { execSync } from "node:child_process"; -import crypto from "node:crypto"; -import { sync as spawnSync } from "cross-spawn"; -import PackageJson from "@npmcli/package-json"; -import jsonfile from "jsonfile"; -import retry from "fetch-retry"; -import { fetch } from "undici"; - -let fetchRetry = retry(fetch); - -let __dirname = path.dirname(fileURLToPath(import.meta.url)); - -export function getAppDirectory(name) { - return path.join(__dirname, "apps", name); -} - -export let CYPRESS_SOURCE_DIR = path.join(__dirname, "cypress"); -export let CYPRESS_CONFIG = path.join(__dirname, "cypress.json"); - -export function getAppName(target) { - let sha = execSync("git rev-parse HEAD").toString().trim().slice(0, 7); - let suffix = crypto.randomBytes(4).toString("hex"); - return `remix-deployment-test-${target}-${sha}-${suffix}`; -} - -export async function addCypress(directory, url) { - let shared = await jsonfile.readFile(path.join(__dirname, "package.json")); - let pkgJson = await PackageJson.load(directory); - - pkgJson.update({ - devDependencies: { - ...pkgJson.content.devDependencies, - "start-server-and-test": shared.dependencies["start-server-and-test"], - cypress: shared.dependencies["cypress"], - "@testing-library/cypress": - shared.dependencies["@testing-library/cypress"], - }, - scripts: { - ...pkgJson.content.scripts, - "cy:run": "cypress run", - "cy:open": "cypress open", - "test:e2e:dev": `start-server-and-test dev ${url} cy:open`, - "test:e2e:run": `start-server-and-test dev ${url} cy:run`, - }, - }); - - await pkgJson.save(); -} - -export function getSpawnOpts(dir = __dirname, env = {}) { - return { - cwd: dir, - stdio: "inherit", - env: { - PATH: process.env.PATH, - HOME: process.env.HOME, - NODE_ENV: "development", - ...env, - }, - }; -} - -export function runCypress(dir, dev, url) { - let spawnOpts = getSpawnOpts(dir, { CYPRESS_BASE_URL: url }); - - if (dev) { - let cypressDevCommand = spawnSync( - "npm", - ["run", "test:e2e:run"], - spawnOpts - ); - if (cypressDevCommand.status !== 0) { - throw new Error("Cypress tests failed in development"); - } - } else { - let cypressProdCommand = spawnSync("npm", ["run", "cy:run"], spawnOpts); - if (cypressProdCommand.status !== 0) { - throw new Error("Cypress tests failed in production"); - } - } -} - -export function checkUrl(url) { - let retries = 10; - - // exponential backoff for retries, maxes out at 10 seconds - function wait(attempt) { - return Math.min(Math.pow(2, attempt) * 250, 10_000); // 250, 500, 1000, 2000, 4000, 8000, 10000 - } - - return fetchRetry(url, { - retryDelay: function (attempt, error, response) { - return wait(attempt); - }, - retryOn: (attempt, error, response) => { - let currentAttempt = attempt + 1; // `attempt` is 0 based - if (currentAttempt > retries) { - console.log(`out of retries for ${url}`); - return false; - } - - if (error !== null || !response.ok) { - console.log( - `[${currentAttempt}/${retries}] - ${url} - waiting ${wait(attempt)}ms` - ); - return true; - } - }, - }); -} - -export async function validatePackageVersions(directory) { - let packageJson = jsonfile.readFileSync(path.join(directory, "package.json")); - let devDependencies = packageJson.devDependencies || {}; - let dependencies = packageJson.dependencies || {}; - let allDeps = { ...devDependencies, ...dependencies }; - let remixDeps = Object.keys(allDeps).filter((key) => - key.startsWith("@remix-run") - ); - - let settled = await Promise.all( - remixDeps.map(async (key) => { - let version = allDeps[key]; - let pinnedVersion = version.replace(/^\^/, ""); - let url = `https://registry.npmjs.org/${key}/${pinnedVersion}`; - let result = await checkUrl(url); - return { ok: result.ok, url, status: result.status }; - }) - ); - - let failed = settled.filter((result) => result.ok === false); - - if (failed.length > 0) { - return [ - false, - failed - .map( - (result) => - `${result.url} returned a ${result.status} HTTP status code` - ) - .join("\n"), - ]; - } - - return [true, null]; -} diff --git a/scripts/deployment-test/arc.mjs b/scripts/deployment-test/arc.mjs deleted file mode 100644 index b619fe1bd13..00000000000 --- a/scripts/deployment-test/arc.mjs +++ /dev/null @@ -1,148 +0,0 @@ -import path from "node:path"; -import { sync as spawnSync } from "cross-spawn"; -import { ApiGatewayV2Client } from "@aws-sdk/client-apigatewayv2"; -import fse from "fs-extra"; -import arcParser from "@architect/parser"; -import { toLogicalID } from "@architect/utils"; -import destroy from "@architect/destroy"; -import PackageJson from "@npmcli/package-json"; - -import { - addCypress, - CYPRESS_CONFIG, - CYPRESS_SOURCE_DIR, - getAppDirectory, - getAppName, - getSpawnOpts, - runCypress, - validatePackageVersions, -} from "./_shared.mjs"; - -let APP_NAME = getAppName("arc"); -let AWS_STACK_NAME = toLogicalID(APP_NAME) + "Staging"; -let PROJECT_DIR = getAppDirectory(APP_NAME); -let ARC_CONFIG_PATH = path.join(PROJECT_DIR, "app.arc"); -let CYPRESS_DEV_URL = "http://localhost:3333"; - -/** @type {import('@aws-sdk/client-apigatewayv2').ApiGatewayV2ClientConfig} */ -let options = { - region: "us-west-2", - apiVersion: "latest", - credentials: { - accessKeyId: process.env.AWS_ACCESS_KEY_ID, - secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, - }, -}; - -let apiGateway = new ApiGatewayV2Client(options); - -async function getArcDeployment() { - let deployments = await apiGateway.getApis().promise(); - return deployments.Items.find((item) => item.Name === AWS_STACK_NAME); -} - -async function createAndDeployApp() { - // create a new remix app - spawnSync( - "npx", - [ - "--yes", - "create-remix@latest", - PROJECT_DIR, - "--template", - "arc", - "--no-install", - "--typescript", - ], - getSpawnOpts() - ); - - // validate dependencies are available - let [valid, errors] = await validatePackageVersions(PROJECT_DIR); - - if (!valid) { - console.error(errors); - process.exit(1); - } - - let pkgJson = await PackageJson.load(PROJECT_DIR); - pkgJson.update({ - devDependencies: { - ...pkgJson.content.devDependencies, - "@architect/architect": "latest", - }, - }); - - await Promise.all([ - fse.copy(CYPRESS_SOURCE_DIR, path.join(PROJECT_DIR, "cypress")), - fse.copy(CYPRESS_CONFIG, path.join(PROJECT_DIR, "cypress.json")), - addCypress(PROJECT_DIR, CYPRESS_DEV_URL), - pkgJson.save(), - ]); - - let spawnOpts = getSpawnOpts(PROJECT_DIR, { - // these would usually be here by default, but I'd rather be explicit, so there is no spreading internally - AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID, - AWS_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY, - }); - - // install deps - spawnSync("npm", ["install"], spawnOpts); - spawnSync("npm", ["run", "build"], spawnOpts); - - // run cypress against the dev server - runCypress(PROJECT_DIR, true, CYPRESS_DEV_URL); - - // update our app.arc deployment name - let fileContents = await fse.readFile(ARC_CONFIG_PATH); - let parsed = arcParser(fileContents); - parsed.app = [APP_NAME]; - await fse.writeFile(ARC_CONFIG_PATH, arcParser.stringify(parsed)); - - // deploy to the staging environment - let deployCommand = spawnSync("npx", ["arc", "deploy", "--prune"], spawnOpts); - if (deployCommand.status !== 0) { - console.error(deployCommand.error); - throw new Error("Architect deploy failed"); - } - - let deployment = await getArcDeployment(); - if (!deployment) { - throw new Error("Deployment not found"); - } - - // run cypress against the deployed app - runCypress(PROJECT_DIR, false, deployment.ApiEndpoint); -} - -async function destroyApp() { - console.log(`Destroying app ${APP_NAME}`); - - try { - process.env.AWS_REGION = options.region; - await destroy({ - appname: APP_NAME, - env: "staging", - force: true, - }); - console.log(`Destroyed app ${APP_NAME}`); - } catch (error) { - console.error(`Failed to destroy app ${APP_NAME}`); - } -} - -async function main() { - let exitCode; - try { - await createAndDeployApp(); - exitCode = 0; - } catch (error) { - console.error(error); - exitCode = 1; - } finally { - await destroyApp(); - process.exit(exitCode); - } -} - -main(); diff --git a/scripts/deployment-test/cf-pages.mjs b/scripts/deployment-test/cf-pages.mjs deleted file mode 100644 index ebd500be436..00000000000 --- a/scripts/deployment-test/cf-pages.mjs +++ /dev/null @@ -1,155 +0,0 @@ -import path from "node:path"; -import { sync as spawnSync } from "cross-spawn"; -import fse from "fs-extra"; -import PackageJson from "@npmcli/package-json"; -import { fetch } from "undici"; - -import { - addCypress, - checkUrl, - CYPRESS_CONFIG, - CYPRESS_SOURCE_DIR, - getAppDirectory, - getAppName, - getSpawnOpts, - runCypress, - validatePackageVersions, -} from "./_shared.mjs"; - -let APP_NAME = getAppName("cf-pages"); -let PROJECT_DIR = getAppDirectory(APP_NAME); -let CYPRESS_DEV_URL = "http://localhost:8788"; - -async function createAndDeployApp() { - // create a new remix app - spawnSync( - "npx", - [ - "--yes", - "create-remix@latest", - PROJECT_DIR, - "--template", - "cloudflare-pages", - "--no-install", - "--typescript", - ], - getSpawnOpts() - ); - - // validate dependencies are available - let [valid, errors] = await validatePackageVersions(PROJECT_DIR); - - if (!valid) { - console.error(errors); - process.exit(1); - } - - let pkgJson = await PackageJson.load(PROJECT_DIR); - pkgJson.update({ - devDependencies: { - ...pkgJson.content.devDependencies, - wrangler: "latest", - }, - }); - - // add cypress to the project - await Promise.all([ - fse.copy(CYPRESS_SOURCE_DIR, path.join(PROJECT_DIR, "cypress")), - fse.copy(CYPRESS_CONFIG, path.join(PROJECT_DIR, "cypress.json")), - addCypress(PROJECT_DIR, CYPRESS_DEV_URL), - pkgJson.save(), - ]); - - let spawnOpts = getSpawnOpts(PROJECT_DIR, { - // these would usually be here by default, but I'd rather be explicit, so there is no spreading internally - CLOUDFLARE_API_TOKEN: process.env.CLOUDFLARE_API_TOKEN, - CLOUDFLARE_ACCOUNT_ID: process.env.CLOUDFLARE_ACCOUNT_ID, - CLOUDFLARE_GLOBAL_API_KEY: process.env.CLOUDFLARE_GLOBAL_API_KEY, - CLOUDFLARE_EMAIL: process.env.CLOUDFLARE_EMAIL, - }); - - // install deps - spawnSync("npm", ["install"], spawnOpts); - spawnSync("npm", ["run", "build"], spawnOpts); - - // run cypress against the dev server - runCypress(PROJECT_DIR, true, CYPRESS_DEV_URL); - - let createCommand = spawnSync( - `npx`, - [ - "wrangler", - "pages", - "project", - "create", - APP_NAME, - "--production-branch", - "main", - ], - spawnOpts - ); - - if (createCommand.status !== 0) { - console.error(createCommand.error); - throw new Error("Cloudflare Pages project creation failed"); - } - - let deployCommand = spawnSync( - "npx", - [ - "wrangler", - "pages", - "publish", - "./public", - "--project-name", - APP_NAME, - "--branch", - "main", - ], - spawnOpts - ); - if (deployCommand.status !== 0) { - console.error(deployCommand.error); - throw new Error("Cloudflare Pages deploy failed"); - } - - console.log("Successfully created Cloudflare Pages project"); - - let appUrl = `https://${APP_NAME}.pages.dev`; - - await checkUrl(appUrl); - - // run cypress against the deployed app - runCypress(PROJECT_DIR, false, appUrl); -} - -async function destroyApp() { - let result = await fetch( - `https://api.cloudflare.com/client/v4/accounts/${process.env.CLOUDFLARE_ACCOUNT_ID}/pages/projects/${APP_NAME}`, - { - method: "DELETE", - headers: { - "X-Auth-Email": process.env.CLOUDFLARE_EMAIL, - "X-Auth-Key": process.env.CLOUDFLARE_GLOBAL_API_KEY, - }, - } - ); - let json = await result.json(); - console.log(`[DESTROY_APP]`, json); -} - -async function main() { - let exitCode; - try { - await createAndDeployApp(); - exitCode = 0; - } catch (error) { - console.error(error); - exitCode = 1; - } finally { - await destroyApp(); - process.exit(exitCode); - } -} - -main(); diff --git a/scripts/deployment-test/cf-workers.mjs b/scripts/deployment-test/cf-workers.mjs deleted file mode 100644 index 5c69a9e21f6..00000000000 --- a/scripts/deployment-test/cf-workers.mjs +++ /dev/null @@ -1,130 +0,0 @@ -import path from "node:path"; -import { sync as spawnSync } from "cross-spawn"; -import fse from "fs-extra"; -import toml from "@iarna/toml"; -import PackageJson from "@npmcli/package-json"; -import { fetch } from "undici"; - -import { - addCypress, - CYPRESS_CONFIG, - CYPRESS_SOURCE_DIR, - getAppDirectory, - getAppName, - getSpawnOpts, - runCypress, - validatePackageVersions, -} from "./_shared.mjs"; - -let APP_NAME = getAppName("cf-workers"); -let PROJECT_DIR = getAppDirectory(APP_NAME); -let CYPRESS_DEV_URL = "http://localhost:8787"; - -async function createAndDeployApp() { - // create a new remix app - spawnSync( - "npx", - [ - "--yes", - "create-remix@latest", - PROJECT_DIR, - "--template", - "cloudflare-workers", - "--no-install", - "--typescript", - ], - getSpawnOpts() - ); - - // validate dependencies are available - let [valid, errors] = await validatePackageVersions(PROJECT_DIR); - - if (!valid) { - console.error(errors); - process.exit(1); - } - - let pkgJson = await PackageJson.load(PROJECT_DIR); - pkgJson.update({ - devDependencies: { - ...pkgJson.content.devDependencies, - wrangler: "latest", - }, - }); - - // add cypress to the project - await Promise.all([ - fse.copy(CYPRESS_SOURCE_DIR, path.join(PROJECT_DIR, "cypress")), - fse.copy(CYPRESS_CONFIG, path.join(PROJECT_DIR, "cypress.json")), - addCypress(PROJECT_DIR, CYPRESS_DEV_URL), - pkgJson.save(), - ]); - - let spawnOpts = getSpawnOpts(PROJECT_DIR, { - // these would usually be here by default, but I'd rather be explicit, so there is no spreading internally - CLOUDFLARE_API_TOKEN: process.env.CLOUDFLARE_API_TOKEN, - CLOUDFLARE_ACCOUNT_ID: process.env.CLOUDFLARE_ACCOUNT_ID, - CLOUDFLARE_GLOBAL_API_KEY: process.env.CLOUDFLARE_GLOBAL_API_KEY, - CLOUDFLARE_EMAIL: process.env.CLOUDFLARE_EMAIL, - }); - - // install deps - spawnSync("npm", ["install"], spawnOpts); - spawnSync("npm", ["run", "build"], spawnOpts); - - // run cypress against the dev server - runCypress(PROJECT_DIR, true, CYPRESS_DEV_URL); - - // we need to update the workers name - let wranglerTomlPath = path.join(PROJECT_DIR, "wrangler.toml"); - let wranglerTomlContent = await fse.readFile(wranglerTomlPath); - let wranglerToml = toml.parse(wranglerTomlContent); - wranglerToml.name = APP_NAME; - await fse.writeFile(wranglerTomlPath, toml.stringify(wranglerToml)); - let url = `https://${APP_NAME}.remixrun.workers.dev`; - console.log(`worker url: ${url}`); - - spawnSync("npx", ["wrangler", "--version"], spawnOpts); - - // deploy the app - let deployCommand = spawnSync("npx", ["wrangler", "publish"], spawnOpts); - if (deployCommand.status !== 0) { - console.error(deployCommand.error); - throw new Error("Cloudflare Workers deploy failed"); - } - - // run cypress against the deployed app - runCypress(PROJECT_DIR, false, url); -} - -async function destroyApp() { - let result = await fetch( - // using force will also delete bindings/durable objects - `https://api.cloudflare.com/client/v4/accounts/${process.env.CLOUDFLARE_ACCOUNT_ID}/workers/scripts/${APP_NAME}?force=true`, - { - method: "DELETE", - headers: { - "X-Auth-Email": process.env.CLOUDFLARE_EMAIL, - "X-Auth-Key": process.env.CLOUDFLARE_GLOBAL_API_KEY, - }, - } - ); - let json = await result.json(); - console.log(`[DESTROY_APP]`, json); -} - -async function main() { - let exitCode; - try { - await createAndDeployApp(); - exitCode = 0; - } catch (error) { - console.error(error); - exitCode = 1; - } finally { - await destroyApp(); - process.exit(exitCode); - } -} - -main(); diff --git a/scripts/deployment-test/cypress.json b/scripts/deployment-test/cypress.json deleted file mode 100644 index 0967ef424bc..00000000000 --- a/scripts/deployment-test/cypress.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/scripts/deployment-test/cypress/.eslintrc.js b/scripts/deployment-test/cypress/.eslintrc.js deleted file mode 100644 index 37c79ff0667..00000000000 --- a/scripts/deployment-test/cypress/.eslintrc.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - parserOptions: { - tsconfigRootDir: __dirname, - project: "./tsconfig.json", - }, -}; diff --git a/scripts/deployment-test/cypress/e2e/smoke.ts b/scripts/deployment-test/cypress/e2e/smoke.ts deleted file mode 100644 index 06f01059eba..00000000000 --- a/scripts/deployment-test/cypress/e2e/smoke.ts +++ /dev/null @@ -1,6 +0,0 @@ -describe("smoke", () => { - it("should work", () => { - cy.visit("/"); - cy.contains("a", "15m Quickstart Blog Tutorial"); - }); -}); diff --git a/scripts/deployment-test/cypress/fixtures/example.json b/scripts/deployment-test/cypress/fixtures/example.json deleted file mode 100644 index 0967ef424bc..00000000000 --- a/scripts/deployment-test/cypress/fixtures/example.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/scripts/deployment-test/cypress/plugins/index.ts b/scripts/deployment-test/cypress/plugins/index.ts deleted file mode 100644 index e29b9e3bbef..00000000000 --- a/scripts/deployment-test/cypress/plugins/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -module.exports = ( - on: Cypress.PluginEvents, - config: Cypress.PluginConfigOptions -) => { - let configOverrides: Partial = { - viewportWidth: 1030, - viewportHeight: 800, - integrationFolder: "cypress/e2e", - video: !process.env.CI, - screenshotOnRunFailure: !process.env.CI, - }; - Object.assign(config, configOverrides); - - on("task", { - log(message) { - console.log(message); - return null; - }, - }); - - return config; -}; diff --git a/scripts/deployment-test/cypress/support/index.js b/scripts/deployment-test/cypress/support/index.js deleted file mode 100644 index 44cbd485bc2..00000000000 --- a/scripts/deployment-test/cypress/support/index.js +++ /dev/null @@ -1 +0,0 @@ -import "@testing-library/cypress/add-commands"; diff --git a/scripts/deployment-test/cypress/tsconfig.json b/scripts/deployment-test/cypress/tsconfig.json deleted file mode 100644 index 72b0805a1b6..00000000000 --- a/scripts/deployment-test/cypress/tsconfig.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "exclude": [ - "../node_modules/@types/jest", - "../node_modules/@testing-library/jest-dom" - ], - "include": [ - "./index.ts", - "e2e/**/*", - "plugins/**/*", - "support/**/*", - "../node_modules/cypress", - "../node_modules/@testing-library/cypress" - ], - "compilerOptions": { - "baseUrl": ".", - "noEmit": true, - "types": ["node", "cypress", "@testing-library/cypress"], - "esModuleInterop": true, - "jsx": "react", - "moduleResolution": "Bundler", - "target": "ES2022", - "strict": true, - "skipLibCheck": true, - "resolveJsonModule": true, - "typeRoots": ["../types", "../node_modules/@types"] - } -} diff --git a/scripts/deployment-test/deno-deploy.mjs b/scripts/deployment-test/deno-deploy.mjs deleted file mode 100644 index d9ac9d97993..00000000000 --- a/scripts/deployment-test/deno-deploy.mjs +++ /dev/null @@ -1,70 +0,0 @@ -import { sync as spawnSync } from "cross-spawn"; - -import { - getAppDirectory, - getAppName, - getSpawnOpts, - validatePackageVersions, -} from "./_shared.mjs"; - -let DENO_DEPLOY_PROJECT_NAME = "remix-deno-deploy-test"; -let APP_NAME = getAppName(DENO_DEPLOY_PROJECT_NAME); -let PROJECT_DIR = getAppDirectory(APP_NAME); - -try { - // create a new remix app - spawnSync( - "npx", - [ - "--yes", - "create-remix@latest", - PROJECT_DIR, - "--template", - "deno", - "--no-install", - "--typescript", - ], - getSpawnOpts() - ); - - // validate dependencies are available - let [valid, errors] = await validatePackageVersions(PROJECT_DIR); - - if (!valid) { - console.error(errors); - process.exit(1); - } - - let spawnOpts = getSpawnOpts(PROJECT_DIR, { - // these would usually be here by default, but I'd rather be explicit, so there is no spreading internally - DENO_DEPLOY_TOKEN: process.env.DENO_DEPLOY_TOKEN, - }); - - // install deps - spawnSync("npm", ["install"], spawnOpts); - spawnSync("npm", ["run", "build"], spawnOpts); - - // deploy to deno deploy - // note we dont have to install deployctl here as we do it ahead of time in the deployments workflow - let deployCommand = spawnSync( - "deployctl", - [ - "deploy", - "--project", - DENO_DEPLOY_PROJECT_NAME, - "./build/index.js", - "--prod", - "--include=build,public", - ], - spawnOpts - ); - if (deployCommand.status !== 0) { - console.error(deployCommand.error); - throw new Error("Deno Deploy deploy failed"); - } - - console.log(`Deployed to ${DENO_DEPLOY_PROJECT_NAME}.deno.dev`); -} catch (error) { - console.error(error); - process.exit(1); -} diff --git a/scripts/deployment-test/fly.mjs b/scripts/deployment-test/fly.mjs deleted file mode 100644 index 3dbd7d9c638..00000000000 --- a/scripts/deployment-test/fly.mjs +++ /dev/null @@ -1,131 +0,0 @@ -import path from "node:path"; -import { sync as spawnSync } from "cross-spawn"; -import fse from "fs-extra"; -import toml from "@iarna/toml"; - -import { - addCypress, - checkUrl, - CYPRESS_CONFIG, - CYPRESS_SOURCE_DIR, - getAppDirectory, - getAppName, - getSpawnOpts, - runCypress, - validatePackageVersions, -} from "./_shared.mjs"; - -let APP_NAME = getAppName("fly"); -let PROJECT_DIR = getAppDirectory(APP_NAME); -let CYPRESS_DEV_URL = "http://localhost:3000"; - -let spawnOpts = getSpawnOpts(PROJECT_DIR, { - // these would usually be here by default, but I'd rather be explicit, so there is no spreading internally - FLY_API_TOKEN: process.env.FLY_API_TOKEN, -}); - -async function createAndDeployApp() { - // create a new remix app - spawnSync( - "npx", - [ - "--yes", - "create-remix@latest", - PROJECT_DIR, - "--template", - "fly", - "--no-install", - "--typescript", - ], - getSpawnOpts() - ); - - // validate dependencies are available - let [valid, errors] = await validatePackageVersions(PROJECT_DIR); - - if (!valid) { - console.error(errors); - process.exit(1); - } - - // add cypress to the project - await Promise.all([ - fse.copy(CYPRESS_SOURCE_DIR, path.join(PROJECT_DIR, "cypress")), - fse.copy(CYPRESS_CONFIG, path.join(PROJECT_DIR, "cypress.json")), - addCypress(PROJECT_DIR, CYPRESS_DEV_URL), - ]); - - // create a new app on fly - // note we dont have to install fly here as we do it ahead of time in the deployments workflow - let flyLaunchCommand = spawnSync( - "flyctl", - [ - "launch", - "--name", - APP_NAME, - "--no-deploy", - "--org", - "personal", - "--region", - "ord", - ], - spawnOpts - ); - if (flyLaunchCommand.status !== 0) { - console.error(flyLaunchCommand.error); - throw new Error("Failed to launch fly app"); - } - - // we need to add a PORT env variable to our fly.toml - let flyTomlPath = path.join(PROJECT_DIR, "fly.toml"); - let flyTomlContent = await fse.readFile(flyTomlPath); - let flyToml = toml.parse(flyTomlContent); - flyToml.env = flyToml.env || {}; - flyToml.env.PORT = "8080"; - flyToml.services = flyToml.services || []; - flyToml.services[0].internal_port = "8080"; - - await fse.writeFile(flyTomlPath, toml.stringify(flyToml)); - let flyUrl = `https://${flyToml.app}.fly.dev`; - console.log(`Fly app url: ${flyUrl}`); - - // install deps - spawnSync("npm", ["install"], spawnOpts); - - // run cypress against the dev server - runCypress(PROJECT_DIR, true, CYPRESS_DEV_URL); - - // deploy to fly - let deployCommand = spawnSync("fly", ["deploy", "--remote-only"], spawnOpts); - if (deployCommand.status !== 0) { - console.error(deployCommand.error); - throw new Error("Fly deploy failed"); - } - - // fly deployments can take a little bit to start receiving traffic - console.log(`Fly app deployed, waiting for dns...`); - await checkUrl(flyUrl); - - // run cypress against the deployed app - runCypress(PROJECT_DIR, false, flyUrl); -} - -function destroyApp() { - spawnSync("fly", ["apps", "destroy", APP_NAME, "--yes"], spawnOpts); -} - -async function main() { - let exitCode; - try { - await createAndDeployApp(); - exitCode = 0; - } catch (error) { - console.error(error); - exitCode = 1; - } finally { - await destroyApp(); - process.exit(exitCode); - } -} - -main(); diff --git a/scripts/deployment-test/package.json b/scripts/deployment-test/package.json deleted file mode 100644 index c70441c218e..00000000000 --- a/scripts/deployment-test/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "deployment-test", - "description": "deps needed for testing remix deployments", - "private": true, - "scripts": {}, - "dependencies": { - "@architect/destroy": "^3.0.3", - "@architect/parser": "^5.0.2", - "@architect/utils": "^3.0.4", - "@aws-sdk/client-apigatewayv2": "^3.310.0", - "@iarna/toml": "^2.2.5", - "@npmcli/package-json": "^4.0.1", - "@testing-library/cypress": "^8.0.2", - "cypress": "^9.2.0", - "fetch-retry": "^5.0.2", - "fs-extra": "^10.0.0", - "semver": "^7.3.7", - "start-server-and-test": "^1.14.0" - } -} diff --git a/scripts/find-release-from-changeset.js b/scripts/find-release-from-changeset.js deleted file mode 100644 index a499ec59e24..00000000000 --- a/scripts/find-release-from-changeset.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * - * @param {string | undefined} publishedPackages - * @param {string | undefined} packageVersionToFollow - * @returns {string | undefined} - */ -function findReleaseFromChangeset(publishedPackages, packageVersionToFollow) { - if (!publishedPackages) { - throw new Error("No published packages found"); - } - - let packages = JSON.parse(publishedPackages); - - if (!Array.isArray(packages)) { - throw new Error("Published packages is not an array"); - } - - /** @see https://github.com/changesets/action#outputs */ - /** @type { { name: string; version: string }[] } */ - let typed = packages.filter((pkg) => "name" in pkg && "version" in pkg); - - let found = typed.find((pkg) => pkg.name === packageVersionToFollow); - - if (!found) { - throw new Error( - `${packageVersionToFollow} was not found in the published packages` - ); - } - - console.log(found.version); - return found.version; -} - -findReleaseFromChangeset( - process.env.PUBLISHED_PACKAGES, - process.env.PACKAGE_VERSION_TO_FOLLOW -); diff --git a/scripts/lint-templates.sh b/scripts/lint-templates.sh deleted file mode 100755 index 3417c7e994f..00000000000 --- a/scripts/lint-templates.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -# Helper script for us to use to validate template lint setups outside of the -# monorepo. This script will, for each template in your local Remix repo clone: -# -# * Install an app via create-remix for the template (into a temp/ directory) -# * Install deps -# * npm run lint -# -# Usage: -# lint-templates.sh [path-to-remix-repo] -# -# So from a sibling folder to the remix repo: -# ../remix/scripts/lint-templates.sh ../remix - -REPO_DIR="${1}" - -if [ "${REPO_DIR}" == "" ]; then - REPO_DIR="../remix" -fi - -if [ ! -e "${REPO_DIR}" ]; then - echo "Invalid repo directory: ${REPO_DIR}"; - exit 1; -fi - -TEMPLATES=$(find ${REPO_DIR}/templates -type d -mindepth 1 -maxdepth 1 | grep -v deno | grep -v tutorial | sort) - -for D in ${TEMPLATES}; do - echo "Linting template: ${D}"; - echo "-------------------------------------------------------"; - rm -rf temp; - npx create-remix@latest --template "${D}" temp -y; - cd temp; - npm run lint; - echo ""; - echo ""; - cd ..; -done diff --git a/scripts/markdown-references.mjs b/scripts/markdown-references.mjs deleted file mode 100644 index 4398c082694..00000000000 --- a/scripts/markdown-references.mjs +++ /dev/null @@ -1,34 +0,0 @@ -import path from "node:path"; -import fsp from "node:fs/promises"; -import { read } from "to-vfile"; -import { remark } from "remark"; -import { remarkDefinitionLinks } from "@mcansh/remark-definition-links"; -import remarkFrontmatter from "remark-frontmatter"; -import remarkGfm from "remark-gfm"; -import glob from "glob"; - -main(); - -async function main() { - let files = glob.sync("**/*.md", { - absolute: true, - cwd: path.join(process.cwd(), "./docs"), - }); - - for (let file of files) { - let result = await remark() - .use({ - settings: { - fences: true, - listItemIndent: "one", - tightDefinitions: true, - }, - }) - .use(remarkDefinitionLinks) - .use(remarkGfm) - .use(remarkFrontmatter, ["yaml", "toml"]) - .process(await read(file)); - - await fsp.writeFile(file, result.toString()); - } -} diff --git a/scripts/patchup-version.mjs b/scripts/patchup-version.mjs deleted file mode 100644 index 2bb9b91eecc..00000000000 --- a/scripts/patchup-version.mjs +++ /dev/null @@ -1,126 +0,0 @@ -import { execSync, spawnSync } from "node:child_process"; -import * as fs from "node:fs"; -import path from "node:path"; -import * as url from "node:url"; -import { getPackagesSync } from "@manypkg/get-packages"; - -const __dirname = url.fileURLToPath(new URL(".", import.meta.url)); -const rootDir = path.join(__dirname, ".."); - -Promise.all([writeRemixChangelog(), bumpPeerDepRanges()]).then(() => - console.log("---\n🎉 Done!") -); - -/** - * Consider this scenario: - * 1. Run `pnpm changeset:version` to bump versions - * 2. Changesets sees that a package has a minor change - * 3. Because we release packages in lockstep, all packages get a minor update - * 4. `@remix-run/dev` has "peerDependencies": { "@remix-run/serve": "1.8.0" } - * 5. This dependency will now be out of range after the update - * 6. Changesets makes the safe bet and updates `@remix-run/dev` to 2.0.0 - * because it can't be sure this doesn't result in a breaking change - * 7. Because we release packages in lockstep, all packages get a major update - * - * In practice, this means any `minor` changeset will result in a major bump, - * which definitely isn't what we want. - * - * Instead, we relaxe the peer dependency range for internal packages. That way - * the update doesn't result in an out-of-range peer dependency, and all - * packages are bumped to the next minor release instead. - * - * Because changesets doesn't automatically bump peer dependencies with the - * relaxed range (which makes sense in some cases), this script does that for - * us. This makes the change safer because updating the leading dependency will - * result in a peer dependency warning if the user doesn't bump the peer - * dependency for some reason. - * - * Thanks to Mateusz Burzyński for the original script - * Copyright (c) 2015 David Khourshid, MIT License - * @see https://github.com/statelyai/xstate/blob/fb4786b80786d8ff3d44dfa818097b219dab623c/scripts/bump-peer-dep-ranges.js - */ -async function bumpPeerDepRanges() { - let gitStatusResult = spawnSync("git", ["status", "--porcelain"]); - if (gitStatusResult.status !== 0) { - process.exit(gitStatusResult.status || undefined); - } - - let allPackages = getPackagesSync(rootDir).packages; - // let pkgChanges = new Map( - // gitStatusResult.stdout - // .toString() - // .trim() - // .split("\n") - // .filter((line) => /^\s*M\s+.*\/package.json/.test(line)) - // .map((line) => { - // /** - // * @type {string} - // * This will always be defined but TS doesn't know that - // * @ts-expect-error */ - // let gitPath = line.match(/[^\s]+package.json/)[0]; - // let fsPath = path.join(rootDir, gitPath); - // let packageJson = JSON.parse(fs.readFileSync(fsPath, "utf-8")); - // let previousPackageJsonResult = spawnSync("git", [ - // "show", - // `HEAD:${gitPath}`, - // ]); - - // if (previousPackageJsonResult.status !== 0) { - // process.exit(gitStatusResult.status || undefined); - // } - - // return [ - // packageJson.name, - // { - // path: fsPath, - // packageJson: packageJson, - // versionChanged: - // packageJson.version !== - // JSON.parse(previousPackageJsonResult.stdout.toString().trim()) - // .version, - // }, - // ]; - // }) - // ); - - for (let pkg of allPackages) { - let peerPkg = pkg.packageJson.name; - let peerPkgVersion = pkg.packageJson.version; - // let peerPkgChange = pkgChanges.get(peerPkg); - // if (!peerPkgChange || !peerPkgChange.versionChanged) { - // continue; - // } - - for (let dependentPkg of allPackages) { - let peerDeps = dependentPkg.packageJson.peerDependencies; - if (!peerDeps || !peerDeps[peerPkg]) { - continue; - } - let pkgJsonCopy = { ...dependentPkg.packageJson }; - // TS not smart enough to realize we checked this before copying the object - // @ts-expect-error - pkgJsonCopy.peerDependencies[peerPkg] = `^${peerPkgVersion}`; - - await fs.promises.writeFile( - path.join(dependentPkg.dir, "package.json"), - JSON.stringify(pkgJsonCopy, null, 2) + "\n", - "utf-8" - ); - } - } - - console.log("✅ Bumped peer dependency ranges"); - - execSync("pnpm install --no-frozen-lockfile"); - console.log( - "✅ Synced up `pnpm-lock.yaml` via `pnpm install --no-frozen-lockfile`" - ); -} - -async function writeRemixChangelog() { - let contents = - "# `remix`\n\nSee the `CHANGELOG.md` in individual Remix packages for all changes.\n"; - let filePath = path.join(rootDir, "packages", "remix", "CHANGELOG.md"); - await fs.promises.writeFile(filePath, contents, "utf-8"); - console.log("✅ Wrote `remix` changelog"); -} diff --git a/scripts/playground/new.js b/scripts/playground/new.js deleted file mode 100644 index 9cb64774743..00000000000 --- a/scripts/playground/new.js +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env node - -// this generates a new playground project in the .gitignored playground directory -// pnpm playground:new - -let path = require("node:path"); -let { execSync } = require("node:child_process"); -let fse = require("fs-extra"); - -createNewProject(process.argv[2]); - -async function createNewProject(name = `playground-${Date.now()}`) { - let projectDir = path.join(__dirname, "../../playground", name); - let localTemplate = path.join(__dirname, "template.local"); - let hasLocalTemplate = fse.existsSync(localTemplate); - if (hasLocalTemplate) { - console.log(`ℹ️ Using local template: ${localTemplate}`); - } else { - console.log( - `ℹ️ Using default template. If you want to customize it, make a project in ${localTemplate.replace( - process.cwd(), - "." - )} and we'll use that one instead.` - ); - } - let templateDir = hasLocalTemplate - ? localTemplate - : path.join(__dirname, "template"); - if (await fse.pathExists(projectDir)) { - throw new Error( - `🚨 A playground with the name ${name} already exists. Delete it first or use a different name.` - ); - } - await fse.copy(templateDir, projectDir, { - filter(src, dest) { - return !src.includes("node_modules"); - }, - }); - - console.log("📥 Installing deps..."); - execSync(`npm install`, { stdio: "inherit", cwd: projectDir }); - - let remixDeps = path.join(__dirname, "../../build/node_modules"); - - console.log("🏗 Building remix..."); - execSync(`pnpm rollup -c`, { stdio: "inherit" }); - - console.log("🚚 Copying remix deps..."); - await fse.copy(remixDeps, path.join(projectDir, "node_modules"), { - overwrite: true, - }); - - let relativeProjectDir = projectDir.replace(process.cwd(), "."); - let hasInit = fse.existsSync(path.join(projectDir, "remix.init")); - if (hasInit) { - console.log("🎬 Running Remix Init..."); - execSync(`node ./node_modules/@remix-run/dev/dist/cli init`, { - stdio: "inherit", - cwd: projectDir, - }); - } else { - console.log( - `ℹ️ No remix.init directory found in ${relativeProjectDir}. Skipping init.` - ); - } - console.log( - `✅ Done! Now in one terminal run \`pnpm watch\` in the root of the remix repo and in another cd into ${relativeProjectDir} and run \`npm run dev\` and you should be set.` - ); -} diff --git a/scripts/playground/template/.env b/scripts/playground/template/.env deleted file mode 100644 index 0d0e0d65e4b..00000000000 --- a/scripts/playground/template/.env +++ /dev/null @@ -1,2 +0,0 @@ -DATABASE_URL="file:./data.db?connection_limit=1" -SESSION_SECRET="super-duper-s3cret" diff --git a/scripts/playground/template/.gitignore b/scripts/playground/template/.gitignore deleted file mode 100644 index 8e3c3201b44..00000000000 --- a/scripts/playground/template/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -**/public/build - -**/prisma/data.db -**/prisma/data.db-journal diff --git a/scripts/playground/template/.prettierignore b/scripts/playground/template/.prettierignore deleted file mode 100644 index 8cb6bcbdbb0..00000000000 --- a/scripts/playground/template/.prettierignore +++ /dev/null @@ -1,7 +0,0 @@ -node_modules - -/build -/public/build -.env - -/app/styles/tailwind.css diff --git a/scripts/playground/template/README.md b/scripts/playground/template/README.md deleted file mode 100644 index 555e31149f7..00000000000 --- a/scripts/playground/template/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Remix Playground - -This project has everything set up for you to play around with the local Remix packages in a real app environment. - -To create a new project within the `playground` directory (which is ignored by `.gitignore`), execute the command `pnpm playground:new `. For more details, please refer to [the contributing guidelines](https://remix.run/pages/contributing). diff --git a/scripts/playground/template/app/db.server.ts b/scripts/playground/template/app/db.server.ts deleted file mode 100644 index 50676831102..00000000000 --- a/scripts/playground/template/app/db.server.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { PrismaClient } from "@prisma/client"; - -let prisma: PrismaClient; - -declare global { - // eslint-disable-next-line prefer-let/prefer-let - var __db__: PrismaClient; -} - -// this is needed because in development we don't want to restart -// the server with every change, but we want to make sure we don't -// create a new connection to the DB with every change either. -// in production we'll have a single connection to the DB. -if (process.env.NODE_ENV === "production") { - prisma = new PrismaClient(); -} else { - if (!global.__db__) { - global.__db__ = new PrismaClient(); - } - prisma = global.__db__; - prisma.$connect(); -} - -export { prisma }; diff --git a/scripts/playground/template/app/entry.client.tsx b/scripts/playground/template/app/entry.client.tsx deleted file mode 100644 index 93347c1e9e7..00000000000 --- a/scripts/playground/template/app/entry.client.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { RemixBrowser } from "@remix-run/react"; -import { startTransition, StrictMode } from "react"; -import { hydrateRoot } from "react-dom/client"; - -const hydrate = () => { - startTransition(() => { - hydrateRoot( - document, - - - - ); - }); -}; - -if (typeof requestIdleCallback === "function") { - requestIdleCallback(hydrate); -} else { - // Safari doesn't support requestIdleCallback - // https://caniuse.com/requestidlecallback - setTimeout(hydrate, 1); -} diff --git a/scripts/playground/template/app/entry.server.tsx b/scripts/playground/template/app/entry.server.tsx deleted file mode 100644 index 9e8354f7991..00000000000 --- a/scripts/playground/template/app/entry.server.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { PassThrough } from "node:stream"; -import type { AppLoadContext, EntryContext } from "@remix-run/node"; -import { createReadableStreamFromReadable } from "@remix-run/node"; -import { RemixServer } from "@remix-run/react"; -import { isbot } from "isbot"; -import { renderToPipeableStream } from "react-dom/server"; - -const ABORT_DELAY = 5000; - -export default function handleRequest( - request: Request, - responseStatusCode: number, - responseHeaders: Headers, - remixContext: EntryContext, - loadContext: AppLoadContext -) { - let callbackName = isbot(request.headers.get("user-agent") || "") - ? "onAllReady" - : "onShellReady"; - - return new Promise((resolve, reject) => { - let didError = false; - - let { pipe, abort } = renderToPipeableStream( - , - { - [callbackName]: () => { - let body = new PassThrough(); - let stream = createReadableStreamFromReadable(body); - - responseHeaders.set("Content-Type", "text/html"); - - resolve( - new Response(stream, { - headers: responseHeaders, - status: didError ? 500 : responseStatusCode, - }) - ); - - pipe(body); - }, - onShellError: (err: unknown) => { - reject(err); - }, - onError: (error: unknown) => { - didError = true; - - console.error(error); - }, - } - ); - - setTimeout(abort, ABORT_DELAY); - }); -} diff --git a/scripts/playground/template/app/models/note.server.ts b/scripts/playground/template/app/models/note.server.ts deleted file mode 100644 index c266dfc0756..00000000000 --- a/scripts/playground/template/app/models/note.server.ts +++ /dev/null @@ -1,54 +0,0 @@ -import type { User, Note } from "@prisma/client"; - -import { prisma } from "~/db.server"; - -export type { Note } from "@prisma/client"; - -export function getNote({ - id, - userId, -}: Pick & { - userId: User["id"]; -}) { - return prisma.note.findFirst({ - select: { id: true, body: true, title: true }, - where: { id, userId }, - }); -} - -export function getNoteListItems({ userId }: { userId: User["id"] }) { - return prisma.note.findMany({ - where: { userId }, - select: { id: true, title: true }, - orderBy: { updatedAt: "desc" }, - }); -} - -export function createNote({ - body, - title, - userId, -}: Pick & { - userId: User["id"]; -}) { - return prisma.note.create({ - data: { - title, - body, - user: { - connect: { - id: userId, - }, - }, - }, - }); -} - -export function deleteNote({ - id, - userId, -}: Pick & { userId: User["id"] }) { - return prisma.note.deleteMany({ - where: { id, userId }, - }); -} diff --git a/scripts/playground/template/app/models/user.server.ts b/scripts/playground/template/app/models/user.server.ts deleted file mode 100644 index 32e030b4be5..00000000000 --- a/scripts/playground/template/app/models/user.server.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { Password, User } from "@prisma/client"; -import bcrypt from "bcryptjs"; - -import { prisma } from "~/db.server"; - -export type { User } from "@prisma/client"; - -export async function getUserById(id: User["id"]) { - return prisma.user.findUnique({ where: { id } }); -} - -export async function getUserByEmail(email: User["email"]) { - return prisma.user.findUnique({ where: { email } }); -} - -export async function createUser(email: User["email"], password: string) { - let hashedPassword = await bcrypt.hash(password, 10); - - return prisma.user.create({ - data: { - email, - password: { - create: { - hash: hashedPassword, - }, - }, - }, - }); -} - -export async function deleteUserByEmail(email: User["email"]) { - return prisma.user.delete({ where: { email } }); -} - -export async function verifyLogin( - email: User["email"], - password: Password["hash"] -) { - let userWithPassword = await prisma.user.findUnique({ - where: { email }, - include: { - password: true, - }, - }); - - if (!userWithPassword || !userWithPassword.password) { - return null; - } - - let isValid = await bcrypt.compare(password, userWithPassword.password.hash); - - if (!isValid) { - return null; - } - - let { password: _password, ...userWithoutPassword } = userWithPassword; - - return userWithoutPassword; -} diff --git a/scripts/playground/template/app/root.tsx b/scripts/playground/template/app/root.tsx deleted file mode 100644 index 8c522fd5931..00000000000 --- a/scripts/playground/template/app/root.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import type { LinksFunction, LoaderFunctionArgs } from "@remix-run/node"; -import { json } from "@remix-run/node"; -import { - Links, - LiveReload, - Meta, - Outlet, - Scripts, - ScrollRestoration, -} from "@remix-run/react"; -import { cssBundleHref } from "@remix-run/css-bundle"; - -import tailwindStylesheetUrl from "./styles/tailwind.css"; -import { getUser } from "./session.server"; - -export const links: LinksFunction = () => { - return [ - { rel: "stylesheet", href: tailwindStylesheetUrl }, - ...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []), - ]; -}; - -export async function loader({ request }: LoaderFunctionArgs) { - return json({ - user: await getUser(request), - }); -} - -export default function App() { - return ( - - - - - - - - - - - - - - - ); -} diff --git a/scripts/playground/template/app/routes/index.tsx b/scripts/playground/template/app/routes/index.tsx deleted file mode 100644 index 3f0f81745da..00000000000 --- a/scripts/playground/template/app/routes/index.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import type { MetaFunction } from "@remix-run/node"; -import { Link } from "@remix-run/react"; - -import { useOptionalUser } from "~/utils"; - -export const meta: MetaFunction = () => { - return [{ title: "Remix Notes" }]; -}; - -export default function Index() { - let user = useOptionalUser(); - return ( -
-
-

Remix Playground

-
- {user ? ( - - View Notes for {user.email} - - ) : ( -
- - Sign up - - - Log In - -
- )} -
-
-
- ); -} diff --git a/scripts/playground/template/app/routes/join.tsx b/scripts/playground/template/app/routes/join.tsx deleted file mode 100644 index 82cd14fd880..00000000000 --- a/scripts/playground/template/app/routes/join.tsx +++ /dev/null @@ -1,172 +0,0 @@ -import type { - ActionFunctionArgs, - LoaderFunctionArgs, - MetaFunction, -} from "@remix-run/node"; -import { json, redirect } from "@remix-run/node"; -import { Form, Link, useActionData, useSearchParams } from "@remix-run/react"; -import * as React from "react"; - -import { createUser, getUserByEmail } from "~/models/user.server"; -import { getUserId, createUserSession } from "~/session.server"; -import { safeRedirect, validateEmail } from "~/utils"; - -export async function loader({ request }: LoaderFunctionArgs) { - let userId = await getUserId(request); - if (userId) return redirect("/"); - return json({}); -} - -export async function action({ request }: ActionFunctionArgs) { - let formData = await request.formData(); - let email = formData.get("email"); - let password = formData.get("password"); - let redirectTo = safeRedirect(formData.get("redirectTo"), "/"); - - if (!validateEmail(email)) { - return json( - { errors: { email: "Email is invalid", password: null } }, - { status: 400 } - ); - } - - if (typeof password !== "string" || password.length === 0) { - return json( - { errors: { email: null, password: "Password is required" } }, - { status: 400 } - ); - } - - if (password.length < 8) { - return json( - { errors: { email: null, password: "Password is too short" } }, - { status: 400 } - ); - } - - let existingUser = await getUserByEmail(email); - if (existingUser) { - return json( - { - errors: { - email: "A user already exists with this email", - password: null, - }, - }, - { status: 400 } - ); - } - - let user = await createUser(email, password); - - return createUserSession({ - request, - userId: user.id, - remember: false, - redirectTo, - }); -} - -export const meta: MetaFunction = () => { - return [{ title: "Sign Up" }]; -}; - -export default function Join() { - let [searchParams] = useSearchParams(); - let redirectTo = searchParams.get("redirectTo") ?? undefined; - let actionData = useActionData(); - let emailRef = React.useRef(null); - let passwordRef = React.useRef(null); - - React.useEffect(() => { - if (actionData?.errors?.email) { - emailRef.current?.focus(); - } else if (actionData?.errors?.password) { - passwordRef.current?.focus(); - } - }, [actionData]); - - return ( -
-
-
-
- -
- - {actionData?.errors?.email && ( -
- {actionData.errors.email} -
- )} -
-
- -
- -
- - {actionData?.errors?.password && ( -
- {actionData.errors.password} -
- )} -
-
- - - -
-
- Already have an account?{" "} - - Log in - -
-
-
-
-
- ); -} diff --git a/scripts/playground/template/app/routes/login.tsx b/scripts/playground/template/app/routes/login.tsx deleted file mode 100644 index ec59e0378fa..00000000000 --- a/scripts/playground/template/app/routes/login.tsx +++ /dev/null @@ -1,181 +0,0 @@ -import type { - ActionFunctionArgs, - LoaderFunctionArgs, - MetaFunction, -} from "@remix-run/node"; -import { json, redirect } from "@remix-run/node"; -import { Form, Link, useActionData, useSearchParams } from "@remix-run/react"; -import * as React from "react"; - -import { verifyLogin } from "~/models/user.server"; -import { createUserSession, getUserId } from "~/session.server"; -import { safeRedirect, validateEmail } from "~/utils"; - -export async function loader({ request }: LoaderFunctionArgs) { - let userId = await getUserId(request); - if (userId) return redirect("/"); - return json({}); -} - -export async function action({ request }: ActionFunctionArgs) { - let formData = await request.formData(); - let email = formData.get("email"); - let password = formData.get("password"); - let redirectTo = safeRedirect(formData.get("redirectTo"), "/notes"); - let remember = formData.get("remember"); - - if (!validateEmail(email)) { - return json( - { errors: { email: "Email is invalid", password: null } }, - { status: 400 } - ); - } - - if (typeof password !== "string" || password.length === 0) { - return json( - { errors: { email: null, password: "Password is required" } }, - { status: 400 } - ); - } - - if (password.length < 8) { - return json( - { errors: { email: null, password: "Password is too short" } }, - { status: 400 } - ); - } - - let user = await verifyLogin(email, password); - - if (!user) { - return json( - { errors: { email: "Invalid email or password", password: null } }, - { status: 400 } - ); - } - - return createUserSession({ - request, - userId: user.id, - remember: remember === "on" ? true : false, - redirectTo, - }); -} - -export const meta: MetaFunction = () => { - return [{ title: "Login" }]; -}; - -export default function LoginPage() { - let [searchParams] = useSearchParams(); - let redirectTo = searchParams.get("redirectTo") || "/notes"; - let actionData = useActionData(); - let emailRef = React.useRef(null); - let passwordRef = React.useRef(null); - - React.useEffect(() => { - if (actionData?.errors?.email) { - emailRef.current?.focus(); - } else if (actionData?.errors?.password) { - passwordRef.current?.focus(); - } - }, [actionData]); - - return ( -
-
-
-
- -
- - {actionData?.errors?.email && ( -
- {actionData.errors.email} -
- )} -
-
- -
- -
- - {actionData?.errors?.password && ( -
- {actionData.errors.password} -
- )} -
-
- - - -
-
- - -
-
- Don't have an account?{" "} - - Sign up - -
-
-
-
-
- ); -} diff --git a/scripts/playground/template/app/routes/logout.tsx b/scripts/playground/template/app/routes/logout.tsx deleted file mode 100644 index 749332539fe..00000000000 --- a/scripts/playground/template/app/routes/logout.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import type { ActionFunctionArgs } from "@remix-run/node"; -import { redirect } from "@remix-run/node"; - -import { logout } from "~/session.server"; - -export async function action({ request }: ActionFunctionArgs) { - return logout(request); -} - -export async function loader() { - return redirect("/"); -} diff --git a/scripts/playground/template/app/routes/notes.tsx b/scripts/playground/template/app/routes/notes.tsx deleted file mode 100644 index 78521b36743..00000000000 --- a/scripts/playground/template/app/routes/notes.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import type { LoaderFunctionArgs, MetaFunction } from "@remix-run/node"; -import { json } from "@remix-run/node"; -import { Form, Link, NavLink, Outlet, useLoaderData } from "@remix-run/react"; - -import { requireUserId } from "~/session.server"; -import { useUser } from "~/utils"; -import { getNoteListItems } from "~/models/note.server"; - -export async function loader({ request }: LoaderFunctionArgs) { - let userId = await requireUserId(request); - let noteListItems = await getNoteListItems({ userId }); - return json({ noteListItems }); -} - -export const meta: MetaFunction = () => { - return [{ title: "Remix Notes" }]; -}; - -export default function NotesPage() { - let data = useLoaderData(); - let user = useUser(); - - return ( -
-
-

- Notes -

-

{user.email}

-
- -
-
- -
-
- - + New Note - - -
- - {data.noteListItems.length === 0 ? ( -

No notes yet

- ) : ( -
    - {data.noteListItems.map((note) => ( -
  1. - - `block border-b p-4 text-xl ${isActive ? "bg-white" : ""}` - } - to={note.id} - > - 📝 {note.title} - -
  2. - ))} -
- )} -
- -
- -
-
-
- ); -} diff --git a/scripts/playground/template/app/routes/notes/$noteId.tsx b/scripts/playground/template/app/routes/notes/$noteId.tsx deleted file mode 100644 index 953cc9ffcf6..00000000000 --- a/scripts/playground/template/app/routes/notes/$noteId.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import type { - MetaFunction, - ActionFunctionArgs, - LoaderFunctionArgs, -} from "@remix-run/node"; -import { json, redirect } from "@remix-run/node"; -import { Form, useCatch, useLoaderData } from "@remix-run/react"; -import invariant from "tiny-invariant"; - -import { deleteNote, getNote } from "~/models/note.server"; -import { requireUserId } from "~/session.server"; - -export async function loader({ request, params }: LoaderFunctionArgs) { - let userId = await requireUserId(request); - invariant(params.noteId, "noteId not found"); - let note = await getNote({ userId, id: params.noteId }); - if (!note) { - throw new Response("Not Found", { status: 404 }); - } - return json({ note }); -} - -export const meta: MetaFunction = ({ data }) => { - return [{ title: "Note: " + data.note.title }]; -}; - -export async function action({ request, params }: ActionFunctionArgs) { - let userId = await requireUserId(request); - invariant(params.noteId, "noteId not found"); - - await deleteNote({ userId, id: params.noteId }); - - return redirect("/notes"); -} - -export default function NoteDetailsPage() { - let data = useLoaderData(); - - return ( -
-

{data.note.title}

-

{data.note.body}

-
-
- -
-
- ); -} - -export function ErrorBoundary({ error }: { error: Error }) { - console.error(error); - - return
An unexpected error occurred: {error.message}
; -} - -export function CatchBoundary() { - let caught = useCatch(); - - if (caught.status === 404) { - return
Note not found
; - } - - throw new Error(`Unexpected caught response with status: ${caught.status}`); -} diff --git a/scripts/playground/template/app/routes/notes/index.tsx b/scripts/playground/template/app/routes/notes/index.tsx deleted file mode 100644 index 033d247eafa..00000000000 --- a/scripts/playground/template/app/routes/notes/index.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import type { MetaFunction } from "@remix-run/node"; -import { Link } from "@remix-run/react"; - -export const meta: MetaFunction = () => { - return [{ title: "Remix Notes" }]; -}; - -export default function NoteIndexPage() { - return ( -

- No note selected. Select a note on the left, or{" "} - - create a new note. - -

- ); -} diff --git a/scripts/playground/template/app/routes/notes/new.tsx b/scripts/playground/template/app/routes/notes/new.tsx deleted file mode 100644 index 0a5dc8f3c50..00000000000 --- a/scripts/playground/template/app/routes/notes/new.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import type { ActionFunctionArgs, MetaFunction } from "@remix-run/node"; -import { json, redirect } from "@remix-run/node"; -import { Form, useActionData } from "@remix-run/react"; -import * as React from "react"; - -import { createNote } from "~/models/note.server"; -import { requireUserId } from "~/session.server"; - -export async function action({ request }: ActionFunctionArgs) { - let userId = await requireUserId(request); - - let formData = await request.formData(); - let title = formData.get("title"); - let body = formData.get("body"); - - if (typeof title !== "string" || title.length === 0) { - return json( - { errors: { title: "Title is required", body: null } }, - { status: 400 } - ); - } - - if (typeof body !== "string" || body.length === 0) { - return json( - { errors: { title: null, body: "Body is required" } }, - { status: 400 } - ); - } - - let note = await createNote({ title, body, userId }); - - return redirect(`/notes/${note.id}`); -} - -export const meta: MetaFunction = () => { - return [{ title: "Create a Note" }]; -}; - -export default function NewNotePage() { - let actionData = useActionData(); - let titleRef = React.useRef(null); - let bodyRef = React.useRef(null); - - React.useEffect(() => { - if (actionData?.errors?.title) { - titleRef.current?.focus(); - } else if (actionData?.errors?.body) { - bodyRef.current?.focus(); - } - }, [actionData]); - - return ( -
-
- - {actionData?.errors?.title && ( -
- {actionData.errors.title} -
- )} -
- -
-

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 diff --git a/src/test/utils.ts b/src/test/utils.ts index b8bb081e507..ffcfd39ad89 100644 --- a/src/test/utils.ts +++ b/src/test/utils.ts @@ -1,6 +1,33 @@ import Headers from '@mjackson/headers'; -import { concat } from '../lib/buffer-utils.js'; +export function concat(chunks: Uint8Array[]): Uint8Array { + if (chunks.length === 1) return chunks[0]; + + let length = 0; + for (let chunk of chunks) { + length += chunk.length; + } + + let result = new Uint8Array(length); + let offset = 0; + + for (let chunk of chunks) { + result.set(chunk, offset); + offset += chunk.length; + } + + return result; +} + +export function getRandomBytes(size: number): Uint8Array { + let chunks: Uint8Array[] = []; + + for (let i = 0; i < size; i += 65536) { + chunks.push(crypto.getRandomValues(new Uint8Array(Math.min(size - i, 65536)))); + } + + return concat(chunks); +} export function createReadableStream( content: string | Uint8Array, From 24862f79839bccdf54078485831daa6b44975feb Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 14 Aug 2024 14:20:40 -0700 Subject: [PATCH 243/730] Simplify internal buffer handling --- src/lib/buffer-search.spec.ts | 32 ++++++ src/lib/buffer-search.ts | 60 +++++++++++ src/lib/buffer-utils.spec.ts | 102 ------------------- src/lib/buffer-utils.ts | 94 ------------------ src/lib/multipart.ts | 181 ++++++++++++++-------------------- 5 files changed, 168 insertions(+), 301 deletions(-) create mode 100644 src/lib/buffer-search.spec.ts create mode 100644 src/lib/buffer-search.ts delete mode 100644 src/lib/buffer-utils.spec.ts delete mode 100644 src/lib/buffer-utils.ts diff --git a/src/lib/buffer-search.spec.ts b/src/lib/buffer-search.spec.ts new file mode 100644 index 00000000000..9224f7d2087 --- /dev/null +++ b/src/lib/buffer-search.spec.ts @@ -0,0 +1,32 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { createSearch } from './buffer-search.js'; + +function encode(string: string): Uint8Array { + return new TextEncoder().encode(string); +} + +describe('createSearch.indexIn', () => { + it('finds the first occurrence of a pattern in a buffer', () => { + let search = createSearch('world'); + assert.equal(search.indexIn(encode('hello world')), 6); + }); + + it('returns -1 if the pattern is not found', () => { + let search = createSearch('world'); + assert.equal(search.indexIn(encode('hello worl')), -1); + }); +}); + +describe('createSearch.endPartialIndexIn', () => { + it('finds the last partial occurrence of a pattern in a buffer', () => { + let search = createSearch('world'); + assert.equal(search.endPartialIndexIn(encode('hello worl')), 6); + }); + + it('returns -1 if the pattern is not found at the end', () => { + let search = createSearch('world'); + assert.equal(search.endPartialIndexIn(encode('hello worlds')), -1); + }); +}); diff --git a/src/lib/buffer-search.ts b/src/lib/buffer-search.ts new file mode 100644 index 00000000000..7a4cae32fb2 --- /dev/null +++ b/src/lib/buffer-search.ts @@ -0,0 +1,60 @@ +export interface BufferSearch { + indexIn(haystack: Uint8Array): number; + endPartialIndexIn(haystack: Uint8Array): number; +} + +export function createSearch(pattern: string): BufferSearch { + let needle = new TextEncoder().encode(pattern); + let needleLength = needle.length; + + let indexIn: (haystack: Uint8Array) => number; + if ('Buffer' in globalThis && !('Bun' in globalThis || 'Deno' in globalThis)) { + // Use the built-in Buffer.indexOf method on Node.js for better perf. + indexIn = (haystack) => Buffer.prototype.indexOf.call(haystack, needle); + } else { + let skipTable = new Uint8Array(256).fill(needleLength); + for (let i = 0, end = needleLength - 1; i < end; ++i) { + skipTable[needle[i]] = end - i; + } + + indexIn = (haystack) => { + let haystackLength = haystack.length; + let i = needleLength - 1; + + while (i < haystackLength) { + for (let j = needleLength - 1, k = i; j >= 0 && haystack[k] === needle[j]; --j, --k) { + if (j === 0) return k; + } + + i += skipTable[haystack[i]]; + } + + return -1; + }; + } + + let byteIndexes: Record = {}; + for (let i = 0; i < needleLength; ++i) { + let byte = needle[i]; + if (byteIndexes[byte] === undefined) byteIndexes[byte] = []; + byteIndexes[byte].push(i); + } + + function endPartialIndexIn(haystack: Uint8Array): number { + let end = haystack.length - 1; + + if (haystack[end] in byteIndexes) { + let indexes = byteIndexes[haystack[end]]; + + for (let i = indexes.length - 1; i >= 0; --i) { + for (let j = indexes[i], k = end; j >= 0 && haystack[k] === needle[j]; --j, --k) { + if (j === 0) return k; + } + } + } + + return -1; + } + + return { indexIn, endPartialIndexIn } as const; +} diff --git a/src/lib/buffer-utils.spec.ts b/src/lib/buffer-utils.spec.ts deleted file mode 100644 index 32b1734bab9..00000000000 --- a/src/lib/buffer-utils.spec.ts +++ /dev/null @@ -1,102 +0,0 @@ -import * as assert from 'node:assert/strict'; -import { describe, it } from 'node:test'; - -import { indexOf, combinedIndexOf } from './buffer-utils.js'; - -describe('indexOf', () => { - it('finds the needle at the beginning', () => { - let haystack = new Uint8Array([1, 2, 3, 4, 5]); - let needle = new Uint8Array([1, 2]); - assert.equal(indexOf(haystack, needle), 0); - }); - - it('finds the needle at the end', () => { - let haystack = new Uint8Array([1, 2, 3, 4, 5]); - let needle = new Uint8Array([4, 5]); - assert.equal(indexOf(haystack, needle), 3); - }); - - it('finds the needle in the middle', () => { - let haystack = new Uint8Array([1, 2, 3, 4, 5]); - let needle = new Uint8Array([2, 3]); - assert.equal(indexOf(haystack, needle), 1); - }); - - it('returns -1 when the needle is not found', () => { - let haystack = new Uint8Array([1, 2, 3, 4, 5]); - let needle = new Uint8Array([2, 4]); - assert.equal(indexOf(haystack, needle), -1); - }); -}); - -describe('combinedIndexOf', () => { - it('finds the needle at the beginning of the head', () => { - let head = new Uint8Array([1, 2, 3]); - let tail = new Uint8Array([4, 5, 6]); - let needle = new Uint8Array([1, 2]); - assert.equal(combinedIndexOf(head, tail, needle), 0); - }); - - it('finds the needle at the end of the head', () => { - let head = new Uint8Array([1, 2, 3]); - let tail = new Uint8Array([4, 5, 6]); - let needle = new Uint8Array([2, 3]); - assert.equal(combinedIndexOf(head, tail, needle), 1); - }); - - it('finds the needle split between head and tail', () => { - let head = new Uint8Array([1, 2, 3]); - let tail = new Uint8Array([4, 5, 6]); - assert.equal(combinedIndexOf(head, tail, new Uint8Array([2, 3, 4])), 1); - assert.equal(combinedIndexOf(head, tail, new Uint8Array([3, 4, 5])), 2); - }); - - it('finds the needle at the beginning of the tail', () => { - let head = new Uint8Array([1, 2, 3]); - let tail = new Uint8Array([4, 5, 6]); - let needle = new Uint8Array([4, 5]); - assert.equal(combinedIndexOf(head, tail, needle), 3); - }); - - it('finds the needle at the end of the tail', () => { - let head = new Uint8Array([1, 2, 3]); - let tail = new Uint8Array([4, 5, 6]); - let needle = new Uint8Array([5, 6]); - assert.equal(combinedIndexOf(head, tail, needle), 4); - }); - - it('returns -1 when the needle is not found', () => { - let head = new Uint8Array([1, 2, 3]); - let tail = new Uint8Array([4, 5, 6]); - let needle = new Uint8Array([2, 4]); - assert.equal(combinedIndexOf(head, tail, needle), -1); - }); - - it('handles empty head correctly', () => { - let head = new Uint8Array([]); - let tail = new Uint8Array([1, 2, 3]); - let needle = new Uint8Array([1, 2]); - assert.equal(combinedIndexOf(head, tail, needle), 0); - }); - - it('handles needle equal to the total length', () => { - let head = new Uint8Array([1, 2, 3]); - let tail = new Uint8Array([4, 5, 6]); - let needle = new Uint8Array([1, 2, 3, 4, 5, 6]); - assert.equal(combinedIndexOf(head, tail, needle), 0); - }); - - it('handles needle longer than the total length', () => { - let head = new Uint8Array([1, 2, 3]); - let tail = new Uint8Array([4, 5, 6]); - let needle = new Uint8Array([1, 2, 3, 4, 5, 6, 7]); - assert.equal(combinedIndexOf(head, tail, needle), -1); - }); - - it('handles repeated patterns correctly', () => { - let head = new Uint8Array([1, 2, 1, 2]); - let tail = new Uint8Array([1, 2, 1, 2]); - let needle = new Uint8Array([2, 1, 2, 1]); - assert.equal(combinedIndexOf(head, tail, needle), 1); - }); -}); diff --git a/src/lib/buffer-utils.ts b/src/lib/buffer-utils.ts deleted file mode 100644 index ffd27b9a525..00000000000 --- a/src/lib/buffer-utils.ts +++ /dev/null @@ -1,94 +0,0 @@ -export function concat(chunks: Uint8Array[]): Uint8Array { - if (chunks.length === 1) return chunks[0]; - - let length = 0; - for (let chunk of chunks) { - length += chunk.length; - } - - let result = new Uint8Array(length); - let offset = 0; - - for (let chunk of chunks) { - result.set(chunk, offset); - offset += chunk.length; - } - - return result; -} - -export function computeSkipTable(needle: Uint8Array): Uint8Array { - let table = new Uint8Array(256).fill(needle.length); - - let lastIndex = needle.length - 1; - for (let i = 0; i < lastIndex; ++i) { - table[needle[i]] = lastIndex - i; - } - - return table; -} - -export function indexOf( - haystack: Uint8Array, - needle: Uint8Array, - offset = 0, - skipTable = computeSkipTable(needle), -): number { - let i = Math.max(needle.length - 1, offset); - - while (i < haystack.length) { - let j = needle.length - 1; - let k = i; - - while (j >= 0 && haystack[k] === needle[j]) { - j--; - k--; - } - - if (j === -1) { - return k + 1; - } - - i += skipTable[haystack[i]]; - } - - return -1; // Not found -} - -export function combinedIndexOf( - head: Uint8Array, - tail: Uint8Array, - needle: Uint8Array, - skipTable = computeSkipTable(needle), -): number { - let headLength = head.length; - let totalLength = headLength + tail.length; - let i = needle.length - 1; - - while (i < totalLength) { - let j = needle.length - 1; - let k = i; - - while (j >= 0 && (k < headLength ? head[k] : tail[k - headLength]) === needle[j]) { - j--; - k--; - } - - if (j === -1) { - return k + 1; - } - - i += skipTable[i < headLength ? head[i] : tail[i - headLength]]; - - // This optimization is worthwhile when streaming large files because the head is - // typically very small compared to the tail, so we can switch to a simpler implementation - // once we are sure the boundary is not contained in the head (the parser's buffer) + - // the beginning of the tail (the new chunk) - if (i >= headLength + needle.length) { - let index = indexOf(tail, needle, i - headLength, skipTable); - return index === -1 ? -1 : index + headLength; - } - } - - return -1; // Not found -} diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 2b2a6f4be4f..b0a2d955a2d 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -1,6 +1,6 @@ import Headers from '@mjackson/headers'; -import { concat, computeSkipTable, combinedIndexOf } from './buffer-utils.js'; +import { BufferSearch, createSearch } from './buffer-search.js'; /** * Extracts the boundary string from a `multipart/*` content type. @@ -92,10 +92,8 @@ export async function* parseMultipart( } } -const HYPHEN = 45; const EMPTY_BUFFER = new Uint8Array(0); -const DOUBLE_NEWLINE = new Uint8Array([13, 10, 13, 10]); -const DOUBLE_NEWLINE_SKIP_TABLE = computeSkipTable(DOUBLE_NEWLINE); +const doubleNewlineSearch = createSearch('\r\n\r\n'); export class MultipartParseError extends Error { constructor(message: string) { @@ -123,16 +121,14 @@ const enum MultipartParserState { export class MultipartParser { boundary: string; - #boundaryArray: Uint8Array; + #boundarySearch: BufferSearch; #boundaryLength: number; - #boundarySkipTable: Uint8Array; #maxHeaderSize: number; #maxFileSize: number; #state = MultipartParserState.Start; #buffer: Uint8Array = EMPTY_BUFFER; - #chunk: Uint8Array = EMPTY_BUFFER; - #length = 0; + #bufferLength = 0; #bodyController: ReadableStreamDefaultController | null = null; #bodyLength = 0; @@ -145,9 +141,8 @@ export class MultipartParser { }: MultipartParserOptions = {}, ) { this.boundary = boundary; - this.#boundaryArray = new TextEncoder().encode(`--${boundary}`); - this.#boundaryLength = this.#boundaryArray.length; - this.#boundarySkipTable = computeSkipTable(this.#boundaryArray); + this.#boundarySearch = createSearch(`--${boundary}`); + this.#boundaryLength = 2 + boundary.length; // +2 for leading "--" this.#maxHeaderSize = maxHeaderSize; this.#maxFileSize = maxFileSize; } @@ -210,26 +205,28 @@ export class MultipartParser { throw new MultipartParseError('Cannot push, parser is done'); } - this.#chunk = chunk; - this.#length = this.#buffer.length + this.#chunk.length; + if (this.#bufferLength > 0) { + let newBuffer = new Uint8Array(this.#bufferLength + chunk.length); + newBuffer.set(this.#buffer, 0); + newBuffer.set(chunk, this.#bufferLength); + this.#buffer = newBuffer; + this.#bufferLength += chunk.length; + } else { + this.#buffer = chunk; + this.#bufferLength = chunk.length; + } if (this.#state === MultipartParserState.Start) { - if (this.#length < this.#boundaryLength) { - this.#save(); + if (this.#bufferLength < this.#boundaryLength) { return []; } - let boundaryIndex = combinedIndexOf( - this.#buffer, - this.#chunk, - this.#boundaryArray, - this.#boundarySkipTable, - ); + let boundaryIndex = this.#boundarySearch.indexIn(this.#buffer); if (boundaryIndex !== 0) { throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); } - this.#skip(this.#boundaryLength); + this.#skip(this.#boundaryLength); // Skip initial boundary this.#state = MultipartParserState.AfterBoundary; } @@ -238,22 +235,15 @@ export class MultipartParser { while (true) { if (this.#state === MultipartParserState.AfterBoundary) { - if (this.#length < 2) { - this.#save(); + if (this.#bufferLength < 2) { break; } // If the next two bytes are "--" then we're done; this is the closing boundary. Otherwise // they're the \r\n after a boundary in the middle of the message and we can ignore them. - let twoBytes = this.#read(2); - if ( - (twoBytes.length === 1 && twoBytes[0][0] === HYPHEN && twoBytes[0][1] === HYPHEN) || - (twoBytes[0][0] === HYPHEN && twoBytes[1][0] === HYPHEN) - ) { - // Discard any remaining data in the current buffer/chunk so we don't leak memory. - this.#buffer = EMPTY_BUFFER; - this.#chunk = EMPTY_BUFFER; - + let nextTwoBytes = this.#read(2); + if (nextTwoBytes[0] === 45 && nextTwoBytes[1] === 45) { + this.#buffer = EMPTY_BUFFER; // Don't leak memory this.#state = MultipartParserState.Done; break; } @@ -262,25 +252,22 @@ export class MultipartParser { } if (this.#state === MultipartParserState.Header) { - if (this.#length < 4) { - this.#save(); + if (this.#bufferLength < 4) { break; } - let headerEndIndex = combinedIndexOf( - this.#buffer, - this.#chunk, - DOUBLE_NEWLINE, - DOUBLE_NEWLINE_SKIP_TABLE, - ); - if (headerEndIndex === -1) break; + let headerEndIndex = doubleNewlineSearch.indexIn(this.#buffer); + if (headerEndIndex === -1) { + break; // No \r\n\r\n found + } + if (headerEndIndex > this.#maxHeaderSize) { throw new MultipartParseError( `Header size exceeds maximum allowed size of ${this.#maxHeaderSize} bytes`, ); } - let header = concat(this.#read(headerEndIndex)); + let header = this.#read(headerEndIndex); this.#skip(4); // Skip \r\n\r\n let body = new ReadableStream({ @@ -295,28 +282,33 @@ export class MultipartParser { } if (this.#state === MultipartParserState.Body) { - if (this.#length < this.#boundaryLength) { - this.#save(); + if (this.#bufferLength < this.#boundaryLength) { break; } - let boundaryIndex = combinedIndexOf( - this.#buffer, - this.#chunk, - this.#boundaryArray, - this.#boundarySkipTable, - ); + let boundaryIndex = this.#boundarySearch.indexIn(this.#buffer); if (boundaryIndex === -1) { - // Write as much of the buffer as we can to the current body stream while still - // keeping enough to check if the last few bytes are part of the boundary. - this.#writeBody(this.#read(this.#length - this.#boundaryLength + 1)); - this.#save(); + // No boundary found, but we might have a partial match at the end of the buffer. + let endPartialIndex = this.#boundarySearch.endPartialIndexIn(this.#buffer); + + if (endPartialIndex === -1) { + this.#writeBody(this.#buffer); + this.#buffer = EMPTY_BUFFER; + this.#bufferLength = 0; + } else { + let chunkSize = endPartialIndex - 2; // -2 to avoid \r\n before boundary + if (chunkSize > 0) { + this.#writeBody(this.#read(chunkSize)); + } + } + break; } - if (boundaryIndex > 2) { - this.#writeBody(this.#read(boundaryIndex - 2)); // -2 to avoid \r\n before boundary + let chunkSize = boundaryIndex - 2; // -2 to avoid \r\n before boundary + if (chunkSize > 0) { + this.#writeBody(this.#read(chunkSize)); } this.#closeBody(); @@ -335,65 +327,35 @@ export class MultipartParser { reset(): void { this.#state = MultipartParserState.Start; this.#buffer = EMPTY_BUFFER; - this.#chunk = EMPTY_BUFFER; - this.#length = 0; + this.#bufferLength = 0; this.#bodyController = null; this.#bodyLength = 0; } - #read(size: number): Uint8Array[] { - this.#length -= size; - - if (size > this.#buffer.length) { - if (this.#buffer.length > 0) { - let head = this.#buffer; - this.#buffer = EMPTY_BUFFER; - let tail = this.#chunk.subarray(0, size - head.length); - this.#chunk = this.#chunk.subarray(size - head.length); - return [head, tail]; - } - - let view = this.#chunk.subarray(0, size); - this.#chunk = this.#chunk.subarray(size); - return [view]; - } - - let view = this.#buffer.subarray(0, size); - this.#buffer = this.#buffer.subarray(size); - return [view]; + #read(size: number): Uint8Array { + let chunk = this.#buffer.subarray(0, size); + this.#skip(size); + return chunk; } #skip(size: number): void { - this.#length -= size; - - if (size > this.#buffer.length) { - this.#chunk = this.#chunk.subarray(size - this.#buffer.length); - this.#buffer = EMPTY_BUFFER; - } else { - this.#buffer = this.#buffer.subarray(size); - } - } - - #save(): void { - if (this.#chunk.length === 0) return; - this.#buffer = this.#buffer.length > 0 ? concat([this.#buffer, this.#chunk]) : this.#chunk; + this.#buffer = this.#buffer.subarray(size); + this.#bufferLength -= size; } - #writeBody(chunks: Uint8Array[]): void { - for (let chunk of chunks) { - if (this.#bodyLength + chunk.length > this.#maxFileSize) { - let error = new MultipartParseError( - `File size exceeds maximum allowed size of ${this.#maxFileSize} bytes`, - ); - - this.#bodyController!.error(error); + #writeBody(chunk: Uint8Array): void { + if (this.#bodyLength + chunk.length > this.#maxFileSize) { + let error = new MultipartParseError( + `File size exceeds maximum allowed size of ${this.#maxFileSize} bytes`, + ); - throw error; - } + this.#bodyController!.error(error); - this.#bodyController!.enqueue(chunk); - this.#bodyLength += chunk.length; + throw error; } + + this.#bodyController!.enqueue(chunk); + this.#bodyLength += chunk.length; } #closeBody(): void { @@ -460,11 +422,20 @@ export class MultipartPart { this.#bodyUsed = true; let chunks: Uint8Array[] = []; + let totalLength = 0; for await (let chunk of this.#body) { chunks.push(chunk); + totalLength += chunk.length; + } + + let result = new Uint8Array(totalLength); + let offset = 0; + for (let chunk of chunks) { + result.set(chunk, offset); + offset += chunk.length; } - return concat(chunks); + return result; } /** From d741248fdcbf00419a51d9f84d98ea1aeb67e4bf Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 15 Aug 2024 15:10:06 -0700 Subject: [PATCH 244/730] Change default maxFileSize to Infinity --- CHANGELOG.md | 5 +++++ src/lib/multipart.ts | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b779ac75927..9d5c8fba2fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # `multipart-parser` CHANGELOG +## HEAD + +- Change default `maxFileSize` from 10 MB to `Infinity` +- Simplify internal buffer management and search, which leads to more consistent chunk flow when handling large file uploads + ## v0.4.2 (Aug 13, 2024) - Fix bug where max file size exceeded error would crash Node.js servers (https://github.com/mjackson/multipart-parser/issues/8) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index b0a2d955a2d..4ecdcda46b0 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -137,7 +137,7 @@ export class MultipartParser { boundary: string, { maxHeaderSize = 8 * 1024, // 8 KB - maxFileSize = 10 * 1024 * 1024, // 10 MB + maxFileSize = Infinity, }: MultipartParserOptions = {}, ) { this.boundary = boundary; @@ -216,9 +216,11 @@ export class MultipartParser { this.#bufferLength = chunk.length; } + let parts: MultipartPart[] = []; + if (this.#state === MultipartParserState.Start) { if (this.#bufferLength < this.#boundaryLength) { - return []; + return parts; } let boundaryIndex = this.#boundarySearch.indexIn(this.#buffer); @@ -231,8 +233,6 @@ export class MultipartParser { this.#state = MultipartParserState.AfterBoundary; } - let parts: MultipartPart[] = []; - while (true) { if (this.#state === MultipartParserState.AfterBoundary) { if (this.#bufferLength < 2) { From 956596bb56c628c833f9ca13426a1314ff3a36ce Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 15 Aug 2024 15:11:34 -0700 Subject: [PATCH 245/730] Use for await...of in benchmark --- bench/global.d.ts | 8 ++++++++ bench/globals.d.ts | 5 ----- bench/parsers/multipart-parser.ts | 6 +++--- 3 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 bench/global.d.ts delete mode 100644 bench/globals.d.ts diff --git a/bench/global.d.ts b/bench/global.d.ts new file mode 100644 index 00000000000..dbb97336eb9 --- /dev/null +++ b/bench/global.d.ts @@ -0,0 +1,8 @@ +declare var Deno: { version: { deno: string } } | undefined; + +// See https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62651 + +interface ReadableStream { + values(options?: { preventCancel?: boolean }): AsyncIterableIterator; + [Symbol.asyncIterator](): AsyncIterableIterator; +} diff --git a/bench/globals.d.ts b/bench/globals.d.ts deleted file mode 100644 index 4c75c2fd6ef..00000000000 --- a/bench/globals.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare global { - var Deno: { version: { deno: string } } | undefined; -} - -export {}; diff --git a/bench/parsers/multipart-parser.ts b/bench/parsers/multipart-parser.ts index 850e91f270c..2575f969cfb 100644 --- a/bench/parsers/multipart-parser.ts +++ b/bench/parsers/multipart-parser.ts @@ -1,4 +1,4 @@ -import { MultipartParser } from '@mjackson/multipart-parser'; +import { parseMultipart } from '@mjackson/multipart-parser'; import { MultipartMessage } from '../messages.js'; @@ -14,9 +14,9 @@ export async function parse(message: MultipartMessage): Promise { let start = performance.now(); - await new MultipartParser(message.boundary, { maxFileSize: Infinity }).parse(stream, (_) => { + for await (let _ of parseMultipart(stream, message.boundary)) { // Do nothing - }); + } return performance.now() - start; } From 1e8d14a473464f18701e0d76a3e86ff20eb05d33 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 15 Aug 2024 15:19:53 -0700 Subject: [PATCH 246/730] Version 0.5.0 --- CHANGELOG.md | 2 +- jsr.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d5c8fba2fb..395c9925444 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # `multipart-parser` CHANGELOG -## HEAD +## v0.5.0 (Aug 15, 2024) - Change default `maxFileSize` from 10 MB to `Infinity` - Simplify internal buffer management and search, which leads to more consistent chunk flow when handling large file uploads diff --git a/jsr.json b/jsr.json index fd637ad381c..3fe528c72c2 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.4.2", + "version": "0.5.0", "exports": "./src/multipart-parser.ts", "publish": { "include": [ diff --git a/package.json b/package.json index 6fd3413c2b9..5d5bef0bc40 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.4.2", + "version": "0.5.0", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "repository": { From fde5d176bf3ace2e14ee2662cef725516dc772c5 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 15 Aug 2024 18:06:29 -0700 Subject: [PATCH 247/730] Remove some lower-level duplicate API --- CHANGELOG.md | 4 +++ README.md | 10 +++--- src/lib/multipart.ts | 73 +++++++++++++++++++------------------------- 3 files changed, 41 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 395c9925444..1c5dbf4b420 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # `multipart-parser` CHANGELOG +## HEAD + +- Removed some low-level API (`parser.push` and `parser.reset`) that was duplicating higher-level API. Use `parser.parse` instead. + ## v0.5.0 (Aug 15, 2024) - Change default `maxFileSize` from 10 MB to `Infinity` diff --git a/README.md b/README.md index 394b041abd7..edd6c0efb35 100644 --- a/README.md +++ b/README.md @@ -98,14 +98,14 @@ If you're working directly with multipart boundaries and buffers/streams of mult import { parseMultipart } from '@mjackson/multipart-parser'; // Get the data from some API, filesystem, etc. -let multipartData = new Uint8Array(); +let multipartMessage = new Uint8Array(); // can also be a stream or any Iterable/AsyncIterable // let multipartData = new ReadableStream(...); // let multipartData = [new Uint8Array(...), new Uint8Array(...)]; let boundary = '----WebKitFormBoundary56eac3x'; -for await (let part of parseMultipart(multipartData, boundary)) { +for await (let part of parseMultipart(multipartMessage, boundary)) { // Do whatever you want with the part... } ``` @@ -115,13 +115,13 @@ If you'd prefer a callback-based API, instantiate your own `MultipartParser` and ```typescript import { MultipartParser } from '@mjackson/multipart-parser'; -let multipartData = new Uint8Array(); // or ReadableStream +let multipartMessage = new Uint8Array(); // or ReadableStream let boundary = '...'; let parser = new MultipartParser(boundary); -// parse() will resolve once all your callbacks are done -await parser.parse(multipartData, async (part) => { +// parser.parse() will resolve once all your callbacks are done +await parser.parse(multipartMessage, async (part) => { // Do whatever you need... }); ``` diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 4ecdcda46b0..138b061f17f 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -15,7 +15,7 @@ export function getMultipartBoundary(contentType: string): string | null { */ export function isMultipartRequest(request: Request): boolean { let contentType = request.headers.get('Content-Type'); - return contentType != null && /^multipart\//i.test(contentType); + return contentType != null && contentType.startsWith('multipart/'); } /** @@ -48,7 +48,11 @@ export async function* parseMultipartRequest( * building a web server, consider using `parseMultipartRequest(request)` instead. */ export async function* parseMultipart( - data: ReadableStream | Uint8Array | Iterable | AsyncIterable, + message: + | ReadableStream + | Uint8Array + | Iterable + | AsyncIterable, boundary: string, options?: MultipartParserOptions, ): AsyncGenerator { @@ -60,8 +64,9 @@ export async function* parseMultipart( let done = false; parser - .parse(data, (part) => { + .parse(message, (part) => { parts.push(part); + if (resolveNext) { resolveNext(); resolveNext = null; @@ -129,7 +134,6 @@ export class MultipartParser { #state = MultipartParserState.Start; #buffer: Uint8Array = EMPTY_BUFFER; #bufferLength = 0; - #bodyController: ReadableStreamDefaultController | null = null; #bodyLength = 0; @@ -148,61 +152,59 @@ export class MultipartParser { } /** - * True if the parser has finished parsing the stream and found the closing multipart boundary. - */ - get done(): boolean { - return this.#state === MultipartParserState.Done; - } - - /** - * Parse a buffer or stream of multipart data and call the given handler for each part it contains. + * Parse a stream/buffer multipart message and call the given handler for each part it contains. * Resolves when the parse is done and all handlers are finished. */ async parse( - data: + message: | ReadableStream | Uint8Array | Iterable | AsyncIterable, handler: (part: MultipartPart) => void, ): Promise { - this.reset(); + this.#reset(); let results = []; - if (data instanceof ReadableStream || isAsyncIterable(data)) { - for await (let chunk of data) { - for (let part of this.push(chunk)) { + if (message instanceof ReadableStream || isAsyncIterable(message)) { + for await (let chunk of message) { + for (let part of this.#write(chunk)) { results.push(handler(part)); } } - } else if (data instanceof Uint8Array) { - for (let part of this.push(data)) { + } else if (message instanceof Uint8Array) { + for (let part of this.#write(message)) { results.push(handler(part)); } - } else if (isIterable(data)) { - for (let chunk of data) { - for (let part of this.push(chunk)) { + } else if (isIterable(message)) { + for (let chunk of message) { + for (let part of this.#write(chunk)) { results.push(handler(part)); } } } else { - throw new TypeError('Cannot parse data: expected a stream or buffer'); + throw new TypeError('Cannot parse multipart message; expected a stream or buffer'); } - if (!this.done) { + if (this.#state !== MultipartParserState.Done) { throw new MultipartParseError('Unexpected end of stream'); } await Promise.all(results); } - /** - * Push a new chunk of data into the parser and return any parts it contains. - */ - push(chunk: Uint8Array): MultipartPart[] { - if (this.done) { - throw new MultipartParseError('Cannot push, parser is done'); + #reset(): void { + this.#state = MultipartParserState.Start; + this.#buffer = EMPTY_BUFFER; + this.#bufferLength = 0; + this.#bodyController = null; + this.#bodyLength = 0; + } + + #write(chunk: Uint8Array): MultipartPart[] { + if (this.#state === MultipartParserState.Done) { + throw new MultipartParseError('Unexpected data after end of stream'); } if (this.#bufferLength > 0) { @@ -321,17 +323,6 @@ export class MultipartParser { return parts; } - /** - * Reset the internal state of the parser. - */ - reset(): void { - this.#state = MultipartParserState.Start; - this.#buffer = EMPTY_BUFFER; - this.#bufferLength = 0; - this.#bodyController = null; - this.#bodyLength = 0; - } - #read(size: number): Uint8Array { let chunk = this.#buffer.subarray(0, size); this.#skip(size); From 6eefb900bae2f786dab3a150e8a3f1ab5b3385f0 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 15 Aug 2024 18:07:32 -0700 Subject: [PATCH 248/730] Use high-level API in benchmark --- bench/parsers/multipart-parser.ts | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/bench/parsers/multipart-parser.ts b/bench/parsers/multipart-parser.ts index 2575f969cfb..60685982676 100644 --- a/bench/parsers/multipart-parser.ts +++ b/bench/parsers/multipart-parser.ts @@ -1,20 +1,25 @@ -import { parseMultipart } from '@mjackson/multipart-parser'; +import { parseMultipartRequest } from '@mjackson/multipart-parser'; import { MultipartMessage } from '../messages.js'; export async function parse(message: MultipartMessage): Promise { - let stream = new ReadableStream({ - start(controller) { - for (let chunk of message.generateChunks()) { - controller.enqueue(chunk); - } - controller.close(); - }, - }); + let request = { + headers: new Headers({ + 'Content-Type': `multipart/form-data; boundary=${message.boundary}`, + }), + body: new ReadableStream({ + start(controller) { + for (let chunk of message.generateChunks()) { + controller.enqueue(chunk); + } + controller.close(); + }, + }), + } as unknown as Request; let start = performance.now(); - for await (let _ of parseMultipart(stream, message.boundary)) { + for await (let _ of parseMultipartRequest(request)) { // Do nothing } From baf151273a2c78cb35af3651683e2771242b9613 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Fri, 16 Aug 2024 13:15:51 -0700 Subject: [PATCH 249/730] Make options public properties of the parser --- src/lib/multipart.ts | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 138b061f17f..59f498fa045 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -97,8 +97,8 @@ export async function* parseMultipart( } } -const EMPTY_BUFFER = new Uint8Array(0); -const doubleNewlineSearch = createSearch('\r\n\r\n'); +const EmptyBuffer = new Uint8Array(0); +const DoubleNewlineSearch = createSearch('\r\n\r\n'); export class MultipartParseError extends Error { constructor(message: string) { @@ -125,14 +125,14 @@ const enum MultipartParserState { */ export class MultipartParser { boundary: string; + maxHeaderSize: number; + maxFileSize: number; #boundarySearch: BufferSearch; #boundaryLength: number; - #maxHeaderSize: number; - #maxFileSize: number; #state = MultipartParserState.Start; - #buffer: Uint8Array = EMPTY_BUFFER; + #buffer: Uint8Array = EmptyBuffer; #bufferLength = 0; #bodyController: ReadableStreamDefaultController | null = null; #bodyLength = 0; @@ -145,10 +145,10 @@ export class MultipartParser { }: MultipartParserOptions = {}, ) { this.boundary = boundary; + this.maxHeaderSize = maxHeaderSize; + this.maxFileSize = maxFileSize; this.#boundarySearch = createSearch(`--${boundary}`); this.#boundaryLength = 2 + boundary.length; // +2 for leading "--" - this.#maxHeaderSize = maxHeaderSize; - this.#maxFileSize = maxFileSize; } /** @@ -196,7 +196,7 @@ export class MultipartParser { #reset(): void { this.#state = MultipartParserState.Start; - this.#buffer = EMPTY_BUFFER; + this.#buffer = EmptyBuffer; this.#bufferLength = 0; this.#bodyController = null; this.#bodyLength = 0; @@ -245,7 +245,7 @@ export class MultipartParser { // they're the \r\n after a boundary in the middle of the message and we can ignore them. let nextTwoBytes = this.#read(2); if (nextTwoBytes[0] === 45 && nextTwoBytes[1] === 45) { - this.#buffer = EMPTY_BUFFER; // Don't leak memory + this.#buffer = EmptyBuffer; // Don't leak memory this.#state = MultipartParserState.Done; break; } @@ -258,19 +258,19 @@ export class MultipartParser { break; } - let headerEndIndex = doubleNewlineSearch.indexIn(this.#buffer); + let headerEndIndex = DoubleNewlineSearch.indexIn(this.#buffer); if (headerEndIndex === -1) { break; // No \r\n\r\n found } - if (headerEndIndex > this.#maxHeaderSize) { + if (headerEndIndex > this.maxHeaderSize) { throw new MultipartParseError( - `Header size exceeds maximum allowed size of ${this.#maxHeaderSize} bytes`, + `Header size exceeds maximum allowed size of ${this.maxHeaderSize} bytes`, ); } let header = this.#read(headerEndIndex); - this.#skip(4); // Skip \r\n\r\n + this.#skip(4); // Skip \r\n\r\n after header let body = new ReadableStream({ start: (controller) => { @@ -296,7 +296,7 @@ export class MultipartParser { if (endPartialIndex === -1) { this.#writeBody(this.#buffer); - this.#buffer = EMPTY_BUFFER; + this.#buffer = EmptyBuffer; this.#bufferLength = 0; } else { let chunkSize = endPartialIndex - 2; // -2 to avoid \r\n before boundary @@ -335,9 +335,9 @@ export class MultipartParser { } #writeBody(chunk: Uint8Array): void { - if (this.#bodyLength + chunk.length > this.#maxFileSize) { + if (this.#bodyLength + chunk.length > this.maxFileSize) { let error = new MultipartParseError( - `File size exceeds maximum allowed size of ${this.#maxFileSize} bytes`, + `File size exceeds maximum allowed size of ${this.maxFileSize} bytes`, ); this.#bodyController!.error(error); From 76787d4de1e502cac4fd16ea9b71538c972cd542 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 17 Aug 2024 00:27:11 -0700 Subject: [PATCH 250/730] Small perf improvements --- README.md | 28 ++++-- src/lib/buffer-search.spec.ts | 32 ------- src/lib/buffer-search.ts | 60 ------------ src/lib/multipart.ts | 175 +++++++++++++++++----------------- src/lib/search.spec.ts | 32 +++++++ src/lib/search.ts | 67 +++++++++++++ 6 files changed, 206 insertions(+), 188 deletions(-) delete mode 100644 src/lib/buffer-search.spec.ts delete mode 100644 src/lib/buffer-search.ts create mode 100644 src/lib/search.spec.ts create mode 100644 src/lib/search.ts diff --git a/README.md b/README.md index edd6c0efb35..7e7252e728e 100644 --- a/README.md +++ b/README.md @@ -92,16 +92,16 @@ server.listen(8080); ## Low-level API -If you're working directly with multipart boundaries and buffers/streams of multipart data that are not necessarily part of a request, `multipart-parser` provides a few lower-level APIs that you can use directly: +If you're working directly with multipart boundaries and buffers/streams of multipart data that are not necessarily part of a request, `multipart-parser` provides a lower-level API that you can use directly: ```typescript import { parseMultipart } from '@mjackson/multipart-parser'; -// Get the data from some API, filesystem, etc. +// Get the multipart data from some API, filesystem, etc. let multipartMessage = new Uint8Array(); // can also be a stream or any Iterable/AsyncIterable -// let multipartData = new ReadableStream(...); -// let multipartData = [new Uint8Array(...), new Uint8Array(...)]; +// let multipartMessage = new ReadableStream(...); +// let multipartMessage = [new Uint8Array(...), new Uint8Array(...)]; let boundary = '----WebKitFormBoundary56eac3x'; @@ -113,17 +113,25 @@ for await (let part of parseMultipart(multipartMessage, boundary)) { If you'd prefer a callback-based API, instantiate your own `MultipartParser` and go for it: ```typescript -import { MultipartParser } from '@mjackson/multipart-parser'; +import { MultipartParseError, MultipartParser } from '@mjackson/multipart-parser'; -let multipartMessage = new Uint8Array(); // or ReadableStream +let multipartMessage = new Uint8Array(); // or ReadableStream, etc. let boundary = '...'; let parser = new MultipartParser(boundary); -// parser.parse() will resolve once all your callbacks are done -await parser.parse(multipartMessage, async (part) => { - // Do whatever you need... -}); +try { + // parse() resolves once the parse is finished and all your callbacks are done + await parser.parse(multipartMessage, async (part) => { + // Do whatever you need... + }); +} catch (error) { + if (error instanceof MultipartParseError) { + // The parse failed + } else { + // One of your handlers failed + } +} ``` ## Examples diff --git a/src/lib/buffer-search.spec.ts b/src/lib/buffer-search.spec.ts deleted file mode 100644 index 9224f7d2087..00000000000 --- a/src/lib/buffer-search.spec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import * as assert from 'node:assert/strict'; -import { describe, it } from 'node:test'; - -import { createSearch } from './buffer-search.js'; - -function encode(string: string): Uint8Array { - return new TextEncoder().encode(string); -} - -describe('createSearch.indexIn', () => { - it('finds the first occurrence of a pattern in a buffer', () => { - let search = createSearch('world'); - assert.equal(search.indexIn(encode('hello world')), 6); - }); - - it('returns -1 if the pattern is not found', () => { - let search = createSearch('world'); - assert.equal(search.indexIn(encode('hello worl')), -1); - }); -}); - -describe('createSearch.endPartialIndexIn', () => { - it('finds the last partial occurrence of a pattern in a buffer', () => { - let search = createSearch('world'); - assert.equal(search.endPartialIndexIn(encode('hello worl')), 6); - }); - - it('returns -1 if the pattern is not found at the end', () => { - let search = createSearch('world'); - assert.equal(search.endPartialIndexIn(encode('hello worlds')), -1); - }); -}); diff --git a/src/lib/buffer-search.ts b/src/lib/buffer-search.ts deleted file mode 100644 index 7a4cae32fb2..00000000000 --- a/src/lib/buffer-search.ts +++ /dev/null @@ -1,60 +0,0 @@ -export interface BufferSearch { - indexIn(haystack: Uint8Array): number; - endPartialIndexIn(haystack: Uint8Array): number; -} - -export function createSearch(pattern: string): BufferSearch { - let needle = new TextEncoder().encode(pattern); - let needleLength = needle.length; - - let indexIn: (haystack: Uint8Array) => number; - if ('Buffer' in globalThis && !('Bun' in globalThis || 'Deno' in globalThis)) { - // Use the built-in Buffer.indexOf method on Node.js for better perf. - indexIn = (haystack) => Buffer.prototype.indexOf.call(haystack, needle); - } else { - let skipTable = new Uint8Array(256).fill(needleLength); - for (let i = 0, end = needleLength - 1; i < end; ++i) { - skipTable[needle[i]] = end - i; - } - - indexIn = (haystack) => { - let haystackLength = haystack.length; - let i = needleLength - 1; - - while (i < haystackLength) { - for (let j = needleLength - 1, k = i; j >= 0 && haystack[k] === needle[j]; --j, --k) { - if (j === 0) return k; - } - - i += skipTable[haystack[i]]; - } - - return -1; - }; - } - - let byteIndexes: Record = {}; - for (let i = 0; i < needleLength; ++i) { - let byte = needle[i]; - if (byteIndexes[byte] === undefined) byteIndexes[byte] = []; - byteIndexes[byte].push(i); - } - - function endPartialIndexIn(haystack: Uint8Array): number { - let end = haystack.length - 1; - - if (haystack[end] in byteIndexes) { - let indexes = byteIndexes[haystack[end]]; - - for (let i = indexes.length - 1; i >= 0; --i) { - for (let j = indexes[i], k = end; j >= 0 && haystack[k] === needle[j]; --j, --k) { - if (j === 0) return k; - } - } - } - - return -1; - } - - return { indexIn, endPartialIndexIn } as const; -} diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 59f498fa045..9bc65b87f0f 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -1,6 +1,11 @@ import Headers from '@mjackson/headers'; -import { BufferSearch, createSearch } from './buffer-search.js'; +import { + SearchFunction, + createSearch, + PartialTailSearchFunction, + createPartialTailSearch, +} from './search.js'; /** * Extracts the boundary string from a `multipart/*` content type. @@ -97,8 +102,7 @@ export async function* parseMultipart( } } -const EmptyBuffer = new Uint8Array(0); -const DoubleNewlineSearch = createSearch('\r\n\r\n'); +const findDoubleNewline = createSearch('\r\n\r\n'); export class MultipartParseError extends Error { constructor(message: string) { @@ -128,12 +132,15 @@ export class MultipartParser { maxHeaderSize: number; maxFileSize: number; - #boundarySearch: BufferSearch; + #findOpeningBoundary: SearchFunction; + #openingBoundaryLength: number; + + #findBoundary: SearchFunction; + #findPartialTailBoundary: PartialTailSearchFunction; #boundaryLength: number; #state = MultipartParserState.Start; - #buffer: Uint8Array = EmptyBuffer; - #bufferLength = 0; + #buffer: Uint8Array | null = null; #bodyController: ReadableStreamDefaultController | null = null; #bodyLength = 0; @@ -147,13 +154,18 @@ export class MultipartParser { this.boundary = boundary; this.maxHeaderSize = maxHeaderSize; this.maxFileSize = maxFileSize; - this.#boundarySearch = createSearch(`--${boundary}`); - this.#boundaryLength = 2 + boundary.length; // +2 for leading "--" + + this.#findOpeningBoundary = createSearch(`--${boundary}`); + this.#openingBoundaryLength = 2 + boundary.length; // length of '--' + boundary + + this.#findBoundary = createSearch(`\r\n--${boundary}`); + this.#findPartialTailBoundary = createPartialTailSearch(`\r\n--${boundary}`); + this.#boundaryLength = 4 + boundary.length; // length of '\r\n--' + boundary } /** * Parse a stream/buffer multipart message and call the given handler for each part it contains. - * Resolves when the parse is done and all handlers are finished. + * Resolves when the parse is finished and all handlers resolve. */ async parse( message: @@ -163,25 +175,25 @@ export class MultipartParser { | AsyncIterable, handler: (part: MultipartPart) => void, ): Promise { - this.#reset(); + if (this.#state !== MultipartParserState.Start) { + this.#reset(); + } + + let results: unknown[] = []; - let results = []; + function handlePart(part: MultipartPart): void { + results.push(handler(part)); + } if (message instanceof ReadableStream || isAsyncIterable(message)) { for await (let chunk of message) { - for (let part of this.#write(chunk)) { - results.push(handler(part)); - } + this.#write(chunk, handlePart); } } else if (message instanceof Uint8Array) { - for (let part of this.#write(message)) { - results.push(handler(part)); - } + this.#write(message, handlePart); } else if (isIterable(message)) { for (let chunk of message) { - for (let part of this.#write(chunk)) { - results.push(handler(part)); - } + this.#write(chunk, handlePart); } } else { throw new TypeError('Cannot parse multipart message; expected a stream or buffer'); @@ -196,142 +208,133 @@ export class MultipartParser { #reset(): void { this.#state = MultipartParserState.Start; - this.#buffer = EmptyBuffer; - this.#bufferLength = 0; + this.#buffer = null; this.#bodyController = null; this.#bodyLength = 0; } - #write(chunk: Uint8Array): MultipartPart[] { + #write(chunk: Uint8Array, handler: (part: MultipartPart) => void): void { if (this.#state === MultipartParserState.Done) { throw new MultipartParseError('Unexpected data after end of stream'); } - if (this.#bufferLength > 0) { - let newBuffer = new Uint8Array(this.#bufferLength + chunk.length); - newBuffer.set(this.#buffer, 0); - newBuffer.set(chunk, this.#bufferLength); - this.#buffer = newBuffer; - this.#bufferLength += chunk.length; - } else { - this.#buffer = chunk; - this.#bufferLength = chunk.length; - } + let index = 0; + let length = chunk.length; - let parts: MultipartPart[] = []; + if (this.#buffer !== null) { + let newChunk = new Uint8Array(this.#buffer.length + length); + newChunk.set(this.#buffer, 0); + newChunk.set(chunk, this.#buffer.length); + chunk = newChunk; + length = chunk.length; + this.#buffer = null; + } if (this.#state === MultipartParserState.Start) { - if (this.#bufferLength < this.#boundaryLength) { - return parts; + if (length < this.#openingBoundaryLength) { + this.#buffer = chunk; + return; } - let boundaryIndex = this.#boundarySearch.indexIn(this.#buffer); + let boundaryIndex = this.#findOpeningBoundary(chunk); if (boundaryIndex !== 0) { throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); } - this.#skip(this.#boundaryLength); // Skip initial boundary + index += this.#openingBoundaryLength; this.#state = MultipartParserState.AfterBoundary; } while (true) { if (this.#state === MultipartParserState.AfterBoundary) { - if (this.#bufferLength < 2) { + if (length - index < 2) { + this.#buffer = chunk.subarray(index); break; } - // If the next two bytes are "--" then we're done; this is the closing boundary. Otherwise - // they're the \r\n after a boundary in the middle of the message and we can ignore them. - let nextTwoBytes = this.#read(2); - if (nextTwoBytes[0] === 45 && nextTwoBytes[1] === 45) { - this.#buffer = EmptyBuffer; // Don't leak memory + if (chunk[index] === 45 && chunk[index + 1] === 45) { this.#state = MultipartParserState.Done; break; } + index += 2; // Skip \r\n after boundary + this.#state = MultipartParserState.Header; } if (this.#state === MultipartParserState.Header) { - if (this.#bufferLength < 4) { + if (length - index < 4) { + this.#buffer = chunk.subarray(index); break; } - let headerEndIndex = DoubleNewlineSearch.indexIn(this.#buffer); + let headerEndIndex = findDoubleNewline(chunk, index); + if (headerEndIndex === -1) { - break; // No \r\n\r\n found + if (length - index > this.maxHeaderSize) { + throw new MultipartParseError( + `Header size exceeds maximum allowed size of ${this.maxHeaderSize} bytes`, + ); + } + + this.#buffer = chunk.subarray(index); + break; } - if (headerEndIndex > this.maxHeaderSize) { + if (headerEndIndex - index > this.maxHeaderSize) { throw new MultipartParseError( `Header size exceeds maximum allowed size of ${this.maxHeaderSize} bytes`, ); } - let header = this.#read(headerEndIndex); - this.#skip(4); // Skip \r\n\r\n after header + let header = chunk.subarray(index, headerEndIndex); + index = headerEndIndex + 4; // Skip header + \r\n\r\n - let body = new ReadableStream({ - start: (controller) => { - this.#bodyController = controller; - }, - }); + let part = new MultipartPart( + header, + new ReadableStream({ + start: (controller) => { + this.#bodyController = controller; + }, + }), + ); - parts.push(new MultipartPart(header, body)); + handler(part); this.#state = MultipartParserState.Body; } if (this.#state === MultipartParserState.Body) { - if (this.#bufferLength < this.#boundaryLength) { + if (length - index < this.#boundaryLength) { + this.#buffer = chunk.subarray(index); break; } - let boundaryIndex = this.#boundarySearch.indexIn(this.#buffer); + let boundaryIndex = this.#findBoundary(chunk, index); if (boundaryIndex === -1) { - // No boundary found, but we might have a partial match at the end of the buffer. - let endPartialIndex = this.#boundarySearch.endPartialIndexIn(this.#buffer); + // No boundary found, but there may be a partial match at the end of the chunk. + let partialTailIndex = this.#findPartialTailBoundary(chunk); - if (endPartialIndex === -1) { - this.#writeBody(this.#buffer); - this.#buffer = EmptyBuffer; - this.#bufferLength = 0; + if (partialTailIndex === -1) { + this.#writeBody(chunk.subarray(index)); } else { - let chunkSize = endPartialIndex - 2; // -2 to avoid \r\n before boundary - if (chunkSize > 0) { - this.#writeBody(this.#read(chunkSize)); - } + this.#writeBody(chunk.subarray(index, partialTailIndex)); + this.#buffer = chunk.subarray(partialTailIndex); } break; } - let chunkSize = boundaryIndex - 2; // -2 to avoid \r\n before boundary - if (chunkSize > 0) { - this.#writeBody(this.#read(chunkSize)); - } + this.#writeBody(chunk.subarray(index, boundaryIndex)); this.#closeBody(); - this.#skip(2 + this.#boundaryLength); // Skip \r\n + boundary + index = boundaryIndex + this.#boundaryLength; this.#state = MultipartParserState.AfterBoundary; } } - - return parts; - } - - #read(size: number): Uint8Array { - let chunk = this.#buffer.subarray(0, size); - this.#skip(size); - return chunk; - } - - #skip(size: number): void { - this.#buffer = this.#buffer.subarray(size); - this.#bufferLength -= size; } #writeBody(chunk: Uint8Array): void { diff --git a/src/lib/search.spec.ts b/src/lib/search.spec.ts new file mode 100644 index 00000000000..f8ead797f9f --- /dev/null +++ b/src/lib/search.spec.ts @@ -0,0 +1,32 @@ +import * as assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { createSearch, createPartialTailSearch } from './search.js'; + +function buf(string: string): Uint8Array { + return new TextEncoder().encode(string); +} + +describe('createSearch', () => { + it('finds the first occurrence of a pattern in a buffer', () => { + let search = createSearch('world'); + assert.equal(search(buf('hello world')), 6); + }); + + it('returns -1 if the pattern is not found', () => { + let search = createSearch('world'); + assert.equal(search(buf('hello worl')), -1); + }); +}); + +describe('createPartialTailSearch', () => { + it('finds the last partial occurrence of a pattern in a buffer', () => { + let search = createPartialTailSearch('world'); + assert.equal(search(buf('hello worl')), 6); + }); + + it('returns -1 if the pattern is not found at the end', () => { + let search = createPartialTailSearch('world'); + assert.equal(search(buf('hello worlds')), -1); + }); +}); diff --git a/src/lib/search.ts b/src/lib/search.ts new file mode 100644 index 00000000000..041702acc2a --- /dev/null +++ b/src/lib/search.ts @@ -0,0 +1,67 @@ +export interface SearchFunction { + (haystack: Uint8Array, start?: number): number; +} + +export function createSearch(pattern: string): SearchFunction { + let needle = new TextEncoder().encode(pattern); + + let search: SearchFunction; + if ('Buffer' in globalThis && !('Bun' in globalThis || 'Deno' in globalThis)) { + // Use the built-in Buffer.indexOf method on Node.js for better perf. + search = (haystack, start = 0) => Buffer.prototype.indexOf.call(haystack, needle, start); + } else { + let needleEnd = needle.length - 1; + let skipTable = new Uint8Array(256).fill(needle.length); + for (let i = 0; i < needleEnd; ++i) { + skipTable[needle[i]] = needleEnd - i; + } + + search = (haystack, start = 0) => { + let haystackLength = haystack.length; + let i = start + needleEnd; + + while (i < haystackLength) { + for (let j = needleEnd, k = i; j >= 0 && haystack[k] === needle[j]; --j, --k) { + if (j === 0) return k; + } + + i += skipTable[haystack[i]]; + } + + return -1; + }; + } + + return search; +} + +export interface PartialTailSearchFunction { + (haystack: Uint8Array): number; +} + +export function createPartialTailSearch(pattern: string): PartialTailSearchFunction { + let needle = new TextEncoder().encode(pattern); + + let byteIndexes: Record = {}; + for (let i = 0; i < needle.length; ++i) { + let byte = needle[i]; + if (byteIndexes[byte] === undefined) byteIndexes[byte] = []; + byteIndexes[byte].push(i); + } + + return function (haystack: Uint8Array): number { + let haystackEnd = haystack.length - 1; + + if (haystack[haystackEnd] in byteIndexes) { + let indexes = byteIndexes[haystack[haystackEnd]]; + + for (let i = indexes.length - 1; i >= 0; --i) { + for (let j = indexes[i], k = haystackEnd; j >= 0 && haystack[k] === needle[j]; --j, --k) { + if (j === 0) return k; + } + } + } + + return -1; + }; +} From 3c5bc5c4c53e07bcce59939d733d9d6377417223 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 17 Aug 2024 00:31:45 -0700 Subject: [PATCH 251/730] Use low-level API in benchmark --- bench/parsers/multipart-parser.ts | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/bench/parsers/multipart-parser.ts b/bench/parsers/multipart-parser.ts index 60685982676..b3c7216ff7b 100644 --- a/bench/parsers/multipart-parser.ts +++ b/bench/parsers/multipart-parser.ts @@ -1,27 +1,13 @@ -import { parseMultipartRequest } from '@mjackson/multipart-parser'; +import { MultipartParser } from '@mjackson/multipart-parser'; import { MultipartMessage } from '../messages.js'; export async function parse(message: MultipartMessage): Promise { - let request = { - headers: new Headers({ - 'Content-Type': `multipart/form-data; boundary=${message.boundary}`, - }), - body: new ReadableStream({ - start(controller) { - for (let chunk of message.generateChunks()) { - controller.enqueue(chunk); - } - controller.close(); - }, - }), - } as unknown as Request; - let start = performance.now(); - for await (let _ of parseMultipartRequest(request)) { + await new MultipartParser(message.boundary).parse(message.generateChunks(), (_part) => { // Do nothing - } + }); return performance.now() - start; } From 75383d663f781911e24162b87f5b0384be23e1b5 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 17 Aug 2024 10:42:26 -0700 Subject: [PATCH 252/730] Update CHANGELOG --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c5dbf4b420..732640c88dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,9 @@ ## HEAD -- Removed some low-level API (`parser.push` and `parser.reset`) that was duplicating higher-level API. Use `parser.parse` instead. +- BREAKING: Removed some low-level API (`parser.push()` and `parser.reset()`) that was duplicating higher-level API. Use `parser.parse()` instead. +- Added `parser.maxHeaderSize` and `parser.maxFileSize` properties +- Small performance improvements when parsing large files ## v0.5.0 (Aug 15, 2024) From a58383ba7ab2dfb3db134c35498bb194db33871c Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 17 Aug 2024 10:59:18 -0700 Subject: [PATCH 253/730] Version 0.6.0 --- CHANGELOG.md | 2 +- jsr.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 732640c88dd..e8718ac5c57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # `multipart-parser` CHANGELOG -## HEAD +## v0.6.0 (Aug 17, 2024) - BREAKING: Removed some low-level API (`parser.push()` and `parser.reset()`) that was duplicating higher-level API. Use `parser.parse()` instead. - Added `parser.maxHeaderSize` and `parser.maxFileSize` properties diff --git a/jsr.json b/jsr.json index 3fe528c72c2..45ae7dc749a 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.5.0", + "version": "0.6.0", "exports": "./src/multipart-parser.ts", "publish": { "include": [ diff --git a/package.json b/package.json index 5d5bef0bc40..22a3dfdfcaa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.5.0", + "version": "0.6.0", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "repository": { From fbffb237bfe3cde8ec93377f9c2bf2e7e81fd7f1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 17 Aug 2024 11:07:53 -0700 Subject: [PATCH 254/730] Update benchmarks for v0.6 --- README.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 7e7252e728e..40efc21f438 100644 --- a/README.md +++ b/README.md @@ -145,56 +145,56 @@ The [`examples` directory](https://github.com/mjackson/multipart-parser/tree/mai ## Benchmark -`multipart-parser` is designed to be as efficient as possible, only operating on streams of data and never buffering in common usage. This design yields exceptional performance when handling multipart payloads of any size. In most benchmarks, `multipart-parser` is as fast or faster than `busboy`. +`multipart-parser` is designed to be as efficient as possible, operating mainly on streams of data and rarely buffering in common usage. This design yields exceptional performance when handling multipart payloads of any size. In most benchmarks, `multipart-parser` is as fast or faster than `busboy`. -Important: Benchmarking can be tricky, and results vary greatly depending on platform, parameters, and other factors. So take these results with a grain of salt. The main point of this library is to be portable between JavaScript runtimes. To this end, we run the benchmarks on three major open source JavaScript runtimes: Node.js, Bun, and Deno. These benchmarks are only intended to show that multipart-parser is fast enough to get the job done wherever you run it. +Important: Benchmarking can be tricky, and results vary greatly depending on platform, parameters, and other factors. So take these results with a grain of salt. The main point of this library is to be portable between JavaScript runtimes. To this end, we run the benchmarks on three major open source JavaScript runtimes: Node.js, Bun, and Deno. The results of running the benchmarks on my laptop: ``` -> @mjackson/multipart-parser@0.4.2 bench:node /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.6.0 bench:node /Users/michael/Projects/multipart-parser > node --import tsimp/import ./bench/runner.ts Platform: Darwin (23.5.0) -CPU: Apple M1 Pro -Date: 8/13/2024, 6:47:34 PM -Node.js v22.1.0 +CPU: Apple M2 Pro +Date: 8/17/2024, 11:00:59 AM +Node.js v20.15.1 ┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ multipart-parser │ '0.01 ms ± 0.08' │ '1.17 ms ± 0.27' │ '0.12 ms ± 0.03' │ '10.94 ms ± 0.24' │ -│ busboy │ '0.03 ms ± 0.08' │ '3.00 ms ± 0.09' │ '0.21 ms ± 0.03' │ '30.10 ms ± 2.73' │ -│ @fastify/busboy │ '0.02 ms ± 0.07' │ '1.19 ms ± 0.07' │ '0.38 ms ± 0.07' │ '12.15 ms ± 2.30' │ +│ multipart-parser │ '0.01 ms ± 0.03' │ '1.00 ms ± 0.04' │ '0.30 ms ± 0.15' │ '9.99 ms ± 0.18' │ +│ busboy │ '0.03 ms ± 0.07' │ '2.91 ms ± 0.08' │ '0.22 ms ± 0.03' │ '43.27 ms ± 0.47' │ +│ @fastify/busboy │ '0.03 ms ± 0.09' │ '1.14 ms ± 0.06' │ '0.39 ms ± 0.04' │ '11.48 ms ± 0.38' │ └──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ -> @mjackson/multipart-parser@0.4.2 bench:bun /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.6.0 bench:bun /Users/michael/Projects/multipart-parser > bun run ./bench/runner.ts Platform: Darwin (23.5.0) -CPU: Apple M1 Pro -Date: 8/13/2024, 6:49:45 PM +CPU: Apple M2 Pro +Date: 8/17/2024, 11:03:01 AM Bun 1.1.21 ┌──────────────────┬────────────────┬────────────────┬─────────────────┬─────────────────┐ │ │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼────────────────┼────────────────┼─────────────────┼─────────────────┤ -│ multipart-parser │ 0.01 ms ± 0.07 │ 0.95 ms ± 0.12 │ 0.13 ms ± 0.09 │ 9.13 ms ± 0.29 │ -│ busboy │ 0.03 ms ± 0.10 │ 3.55 ms ± 0.10 │ 0.35 ms ± 0.17 │ 35.54 ms ± 2.57 │ -│ @fastify/busboy │ 0.04 ms ± 0.10 │ 7.17 ms ± 0.10 │ 0.62 ms ± 0.13 │ 71.99 ms ± 3.01 │ +│ multipart-parser │ 0.01 ms ± 0.04 │ 0.81 ms ± 0.07 │ 0.11 ms ± 0.09 │ 7.87 ms ± 0.28 │ +│ busboy │ 0.02 ms ± 0.08 │ 3.36 ms ± 0.15 │ 0.34 ms ± 0.15 │ 33.28 ms ± 0.90 │ +│ @fastify/busboy │ 0.03 ms ± 0.11 │ 6.79 ms ± 0.14 │ 0.61 ms ± 0.13 │ 67.84 ms ± 0.54 │ └──────────────────┴────────────────┴────────────────┴─────────────────┴─────────────────┘ -> @mjackson/multipart-parser@0.4.2 bench:deno /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.6.0 bench:deno /Users/michael/Projects/multipart-parser > deno --unstable-byonm --unstable-sloppy-imports run --allow-sys ./bench/runner.ts Platform: Darwin (23.5.0) -CPU: Apple M1 Pro -Date: 8/13/2024, 6:52:51 PM +CPU: Apple M2 Pro +Date: 8/17/2024, 11:05:51 AM Deno 1.45.5 ┌──────────────────┬──────────────────┬───────────────────┬──────────────────┬────────────────────┐ │ (idx) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼───────────────────┼──────────────────┼────────────────────┤ -│ multipart-parser │ "0.02 ms ± 0.18" │ "1.18 ms ± 1.07" │ "0.10 ms ± 0.43" │ "11.00 ms ± 1.18" │ -│ busboy │ "0.04 ms ± 0.27" │ "3.02 ms ± 1.00" │ "0.29 ms ± 0.71" │ "30.22 ms ± 2.61" │ -│ @fastify/busboy │ "0.05 ms ± 0.31" │ "12.32 ms ± 0.73" │ "0.77 ms ± 0.97" │ "125.04 ms ± 8.39" │ +│ multipart-parser │ "0.01 ms ± 0.17" │ "1.01 ms ± 1.00" │ "0.08 ms ± 0.39" │ "9.69 ms ± 0.74" │ +│ busboy │ "0.04 ms ± 0.29" │ "2.92 ms ± 1.00" │ "0.28 ms ± 0.70" │ "29.07 ms ± 1.00" │ +│ @fastify/busboy │ "0.04 ms ± 0.29" │ "11.44 ms ± 2.90" │ "0.74 ms ± 0.97" │ "114.45 ms ± 1.42" │ └──────────────────┴──────────────────┴───────────────────┴──────────────────┴────────────────────┘ ``` From e3d61d2c72a107d3ee4a8a087bf64a3919d70f29 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 17 Aug 2024 11:32:45 -0700 Subject: [PATCH 255/730] Add multipasta to benchmarks --- README.md | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 40efc21f438..b18fb2d374d 100644 --- a/README.md +++ b/README.md @@ -157,14 +157,15 @@ The results of running the benchmarks on my laptop: Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/17/2024, 11:00:59 AM +Date: 8/17/2024, 11:26:11 AM Node.js v20.15.1 ┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ multipart-parser │ '0.01 ms ± 0.03' │ '1.00 ms ± 0.04' │ '0.30 ms ± 0.15' │ '9.99 ms ± 0.18' │ -│ busboy │ '0.03 ms ± 0.07' │ '2.91 ms ± 0.08' │ '0.22 ms ± 0.03' │ '43.27 ms ± 0.47' │ -│ @fastify/busboy │ '0.03 ms ± 0.09' │ '1.14 ms ± 0.06' │ '0.39 ms ± 0.04' │ '11.48 ms ± 0.38' │ +│ multipart-parser │ '0.01 ms ± 0.02' │ '1.00 ms ± 0.05' │ '0.31 ms ± 0.15' │ '9.97 ms ± 0.26' │ +│ busboy │ '0.03 ms ± 0.08' │ '2.92 ms ± 0.08' │ '0.22 ms ± 0.03' │ '43.44 ms ± 1.83' │ +│ @fastify/busboy │ '0.03 ms ± 0.09' │ '1.11 ms ± 0.05' │ '0.38 ms ± 0.03' │ '11.19 ms ± 0.24' │ +│ multipasta │ '0.01 ms ± 0.03' │ '0.97 ms ± 0.06' │ '0.16 ms ± 0.02' │ '9.92 ms ± 1.48' │ └──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ > @mjackson/multipart-parser@0.6.0 bench:bun /Users/michael/Projects/multipart-parser @@ -172,14 +173,15 @@ Node.js v20.15.1 Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/17/2024, 11:03:01 AM +Date: 8/17/2024, 11:28:20 AM Bun 1.1.21 ┌──────────────────┬────────────────┬────────────────┬─────────────────┬─────────────────┐ │ │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼────────────────┼────────────────┼─────────────────┼─────────────────┤ -│ multipart-parser │ 0.01 ms ± 0.04 │ 0.81 ms ± 0.07 │ 0.11 ms ± 0.09 │ 7.87 ms ± 0.28 │ -│ busboy │ 0.02 ms ± 0.08 │ 3.36 ms ± 0.15 │ 0.34 ms ± 0.15 │ 33.28 ms ± 0.90 │ -│ @fastify/busboy │ 0.03 ms ± 0.11 │ 6.79 ms ± 0.14 │ 0.61 ms ± 0.13 │ 67.84 ms ± 0.54 │ +│ multipart-parser │ 0.01 ms ± 0.05 │ 0.79 ms ± 0.06 │ 0.11 ms ± 0.09 │ 7.76 ms ± 0.28 │ +│ busboy │ 0.03 ms ± 0.10 │ 3.30 ms ± 0.09 │ 0.33 ms ± 0.15 │ 33.15 ms ± 2.07 │ +│ @fastify/busboy │ 0.04 ms ± 0.14 │ 6.67 ms ± 0.10 │ 0.59 ms ± 0.13 │ 67.41 ms ± 3.33 │ +│ multipasta │ 0.01 ms ± 0.07 │ 0.93 ms ± 0.70 │ 0.23 ms ± 0.39 │ 7.57 ms ± 0.65 │ └──────────────────┴────────────────┴────────────────┴─────────────────┴─────────────────┘ > @mjackson/multipart-parser@0.6.0 bench:deno /Users/michael/Projects/multipart-parser @@ -187,14 +189,15 @@ Bun 1.1.21 Platform: Darwin (23.5.0) CPU: Apple M2 Pro -Date: 8/17/2024, 11:05:51 AM +Date: 8/17/2024, 11:31:27 AM Deno 1.45.5 ┌──────────────────┬──────────────────┬───────────────────┬──────────────────┬────────────────────┐ │ (idx) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼───────────────────┼──────────────────┼────────────────────┤ -│ multipart-parser │ "0.01 ms ± 0.17" │ "1.01 ms ± 1.00" │ "0.08 ms ± 0.39" │ "9.69 ms ± 0.74" │ -│ busboy │ "0.04 ms ± 0.29" │ "2.92 ms ± 1.00" │ "0.28 ms ± 0.70" │ "29.07 ms ± 1.00" │ -│ @fastify/busboy │ "0.04 ms ± 0.29" │ "11.44 ms ± 2.90" │ "0.74 ms ± 0.97" │ "114.45 ms ± 1.42" │ +│ multipart-parser │ "0.01 ms ± 0.17" │ "1.00 ms ± 1.00" │ "0.08 ms ± 0.39" │ "9.77 ms ± 1.02" │ +│ busboy │ "0.03 ms ± 0.25" │ "2.90 ms ± 0.99" │ "0.28 ms ± 0.70" │ "29.18 ms ± 2.17" │ +│ @fastify/busboy │ "0.05 ms ± 0.30" │ "11.40 ms ± 1.01" │ "0.74 ms ± 0.97" │ "114.81 ms ± 6.03" │ +│ multipasta │ "0.02 ms ± 0.18" │ "1.41 ms ± 0.91" │ "0.19 ms ± 0.58" │ "13.96 ms ± 2.40" │ └──────────────────┴──────────────────┴───────────────────┴──────────────────┴────────────────────┘ ``` From 9338be0085804d571a0a420d66ce739b7ef5a220 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sat, 17 Aug 2024 11:33:55 -0700 Subject: [PATCH 256/730] Move multipasta up in benchmark results --- README.md | 6 +++--- bench/runner.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b18fb2d374d..4d821c825b6 100644 --- a/README.md +++ b/README.md @@ -163,9 +163,9 @@ Node.js v20.15.1 │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ │ multipart-parser │ '0.01 ms ± 0.02' │ '1.00 ms ± 0.05' │ '0.31 ms ± 0.15' │ '9.97 ms ± 0.26' │ +│ multipasta │ '0.01 ms ± 0.03' │ '0.97 ms ± 0.06' │ '0.16 ms ± 0.02' │ '9.92 ms ± 1.48' │ │ busboy │ '0.03 ms ± 0.08' │ '2.92 ms ± 0.08' │ '0.22 ms ± 0.03' │ '43.44 ms ± 1.83' │ │ @fastify/busboy │ '0.03 ms ± 0.09' │ '1.11 ms ± 0.05' │ '0.38 ms ± 0.03' │ '11.19 ms ± 0.24' │ -│ multipasta │ '0.01 ms ± 0.03' │ '0.97 ms ± 0.06' │ '0.16 ms ± 0.02' │ '9.92 ms ± 1.48' │ └──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ > @mjackson/multipart-parser@0.6.0 bench:bun /Users/michael/Projects/multipart-parser @@ -179,9 +179,9 @@ Bun 1.1.21 │ │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼────────────────┼────────────────┼─────────────────┼─────────────────┤ │ multipart-parser │ 0.01 ms ± 0.05 │ 0.79 ms ± 0.06 │ 0.11 ms ± 0.09 │ 7.76 ms ± 0.28 │ +│ multipasta │ 0.01 ms ± 0.07 │ 0.93 ms ± 0.70 │ 0.23 ms ± 0.39 │ 7.57 ms ± 0.65 │ │ busboy │ 0.03 ms ± 0.10 │ 3.30 ms ± 0.09 │ 0.33 ms ± 0.15 │ 33.15 ms ± 2.07 │ │ @fastify/busboy │ 0.04 ms ± 0.14 │ 6.67 ms ± 0.10 │ 0.59 ms ± 0.13 │ 67.41 ms ± 3.33 │ -│ multipasta │ 0.01 ms ± 0.07 │ 0.93 ms ± 0.70 │ 0.23 ms ± 0.39 │ 7.57 ms ± 0.65 │ └──────────────────┴────────────────┴────────────────┴─────────────────┴─────────────────┘ > @mjackson/multipart-parser@0.6.0 bench:deno /Users/michael/Projects/multipart-parser @@ -195,9 +195,9 @@ Deno 1.45.5 │ (idx) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼───────────────────┼──────────────────┼────────────────────┤ │ multipart-parser │ "0.01 ms ± 0.17" │ "1.00 ms ± 1.00" │ "0.08 ms ± 0.39" │ "9.77 ms ± 1.02" │ +│ multipasta │ "0.02 ms ± 0.18" │ "1.41 ms ± 0.91" │ "0.19 ms ± 0.58" │ "13.96 ms ± 2.40" │ │ busboy │ "0.03 ms ± 0.25" │ "2.90 ms ± 0.99" │ "0.28 ms ± 0.70" │ "29.18 ms ± 2.17" │ │ @fastify/busboy │ "0.05 ms ± 0.30" │ "11.40 ms ± 1.01" │ "0.74 ms ± 0.97" │ "114.81 ms ± 6.03" │ -│ multipasta │ "0.02 ms ± 0.18" │ "1.41 ms ± 0.91" │ "0.19 ms ± 0.58" │ "13.96 ms ± 2.40" │ └──────────────────┴──────────────────┴───────────────────┴──────────────────┴────────────────────┘ ``` diff --git a/bench/runner.ts b/bench/runner.ts index 8359ba47cb1..538b81087f0 100644 --- a/bench/runner.ts +++ b/bench/runner.ts @@ -55,15 +55,15 @@ async function runBenchmarks(parserName?: string): Promise { if (parserName === 'multipart-parser' || parserName === undefined) { results['multipart-parser'] = await runParserBenchmarks(multipartParser); } + if (parserName === 'multipasta' || parserName === undefined) { + results['multipasta'] = await runParserBenchmarks(multipasta); + } if (parserName === 'busboy' || parserName === undefined) { results.busboy = await runParserBenchmarks(busboy); } if (parserName === 'fastify-busboy' || parserName === undefined) { results['@fastify/busboy'] = await runParserBenchmarks(fastifyBusboy); } - if (parserName === 'multipasta' || parserName === undefined) { - results['multipasta'] = await runParserBenchmarks(multipasta); - } return results; } From 4ead7c9582b669d4e79c184d5e630d3df5762871 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 18 Aug 2024 15:00:00 -0700 Subject: [PATCH 257/730] Small performance improvements Re-order the inner loop to optimize for streaming large files --- CHANGELOG.md | 4 +++ src/lib/multipart.ts | 81 ++++++++++++++++++++++---------------------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8718ac5c57..7f78f612f61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # `multipart-parser` CHANGELOG +## HEAD + +- More small performance improvements + ## v0.6.0 (Aug 17, 2024) - BREAKING: Removed some low-level API (`parser.push()` and `parser.reset()`) that was duplicating higher-level API. Use `parser.parse()` instead. diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 9bc65b87f0f..ad3dab444a0 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -219,36 +219,50 @@ export class MultipartParser { } let index = 0; - let length = chunk.length; + let chunkLength = chunk.length; if (this.#buffer !== null) { - let newChunk = new Uint8Array(this.#buffer.length + length); + let newChunk = new Uint8Array(this.#buffer.length + chunkLength); newChunk.set(this.#buffer, 0); newChunk.set(chunk, this.#buffer.length); chunk = newChunk; - length = chunk.length; + chunkLength = chunk.length; this.#buffer = null; } - if (this.#state === MultipartParserState.Start) { - if (length < this.#openingBoundaryLength) { - this.#buffer = chunk; - return; - } + while (true) { + if (this.#state === MultipartParserState.Body) { + if (chunkLength - index < this.#boundaryLength) { + this.#buffer = chunk.subarray(index); + break; + } - let boundaryIndex = this.#findOpeningBoundary(chunk); - if (boundaryIndex !== 0) { - throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); - } + let boundaryIndex = this.#findBoundary(chunk, index); - index += this.#openingBoundaryLength; + if (boundaryIndex === -1) { + // No boundary found, but there may be a partial match at the end of the chunk. + let partialTailIndex = this.#findPartialTailBoundary(chunk); - this.#state = MultipartParserState.AfterBoundary; - } + if (partialTailIndex === -1) { + this.#writeBody(index === 0 ? chunk : chunk.subarray(index)); + } else { + this.#writeBody(chunk.subarray(index, partialTailIndex)); + this.#buffer = chunk.subarray(partialTailIndex); + } + + break; + } + + this.#writeBody(chunk.subarray(index, boundaryIndex)); + this.#closeBody(); + + index = boundaryIndex + this.#boundaryLength; + + this.#state = MultipartParserState.AfterBoundary; + } - while (true) { if (this.#state === MultipartParserState.AfterBoundary) { - if (length - index < 2) { + if (chunkLength - index < 2) { this.#buffer = chunk.subarray(index); break; } @@ -264,7 +278,7 @@ export class MultipartParser { } if (this.#state === MultipartParserState.Header) { - if (length - index < 4) { + if (chunkLength - index < 4) { this.#buffer = chunk.subarray(index); break; } @@ -272,7 +286,7 @@ export class MultipartParser { let headerEndIndex = findDoubleNewline(chunk, index); if (headerEndIndex === -1) { - if (length - index > this.maxHeaderSize) { + if (chunkLength - index > this.maxHeaderSize) { throw new MultipartParseError( `Header size exceeds maximum allowed size of ${this.maxHeaderSize} bytes`, ); @@ -303,34 +317,21 @@ export class MultipartParser { handler(part); this.#state = MultipartParserState.Body; + + continue; } - if (this.#state === MultipartParserState.Body) { - if (length - index < this.#boundaryLength) { - this.#buffer = chunk.subarray(index); + if (this.#state === MultipartParserState.Start) { + if (chunkLength < this.#openingBoundaryLength) { + this.#buffer = chunk; break; } - let boundaryIndex = this.#findBoundary(chunk, index); - - if (boundaryIndex === -1) { - // No boundary found, but there may be a partial match at the end of the chunk. - let partialTailIndex = this.#findPartialTailBoundary(chunk); - - if (partialTailIndex === -1) { - this.#writeBody(chunk.subarray(index)); - } else { - this.#writeBody(chunk.subarray(index, partialTailIndex)); - this.#buffer = chunk.subarray(partialTailIndex); - } - - break; + if (this.#findOpeningBoundary(chunk) !== 0) { + throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); } - this.#writeBody(chunk.subarray(index, boundaryIndex)); - this.#closeBody(); - - index = boundaryIndex + this.#boundaryLength; + index += this.#openingBoundaryLength; this.#state = MultipartParserState.AfterBoundary; } From 74cf15c937d7e3dfc9d19592930f3afcbff817b1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 18 Aug 2024 15:38:07 -0700 Subject: [PATCH 258/730] Version 0.6.1 --- CHANGELOG.md | 2 +- jsr.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f78f612f61..1de9e1d9d16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # `multipart-parser` CHANGELOG -## HEAD +## v0.6.1 (Aug 18, 2024) - More small performance improvements diff --git a/jsr.json b/jsr.json index 45ae7dc749a..c25294a04c1 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.6.0", + "version": "0.6.1", "exports": "./src/multipart-parser.ts", "publish": { "include": [ diff --git a/package.json b/package.json index 22a3dfdfcaa..040cd63ca5e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mjackson/multipart-parser", - "version": "0.6.0", + "version": "0.6.1", "description": "A fast, efficient parser for multipart streams in any JavaScript environment", "author": "Michael Jackson ", "repository": { From b6de75ca59402cc3ab3230ed031473b1e43a4050 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 18 Aug 2024 16:26:43 -0700 Subject: [PATCH 259/730] Update benchmark results for v0.6.1 --- README.md | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 4d821c825b6..2fe1ab8cf99 100644 --- a/README.md +++ b/README.md @@ -152,52 +152,52 @@ Important: Benchmarking can be tricky, and results vary greatly depending on pla The results of running the benchmarks on my laptop: ``` -> @mjackson/multipart-parser@0.6.0 bench:node /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.6.1 bench:node /Users/michael/Projects/multipart-parser > node --import tsimp/import ./bench/runner.ts Platform: Darwin (23.5.0) -CPU: Apple M2 Pro -Date: 8/17/2024, 11:26:11 AM -Node.js v20.15.1 +CPU: Apple M1 Pro +Date: 8/18/2024, 4:18:39 PM +Node.js v22.1.0 ┌──────────────────┬──────────────────┬──────────────────┬──────────────────┬───────────────────┐ │ (index) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼──────────────────┼──────────────────┼───────────────────┤ -│ multipart-parser │ '0.01 ms ± 0.02' │ '1.00 ms ± 0.05' │ '0.31 ms ± 0.15' │ '9.97 ms ± 0.26' │ -│ multipasta │ '0.01 ms ± 0.03' │ '0.97 ms ± 0.06' │ '0.16 ms ± 0.02' │ '9.92 ms ± 1.48' │ -│ busboy │ '0.03 ms ± 0.08' │ '2.92 ms ± 0.08' │ '0.22 ms ± 0.03' │ '43.44 ms ± 1.83' │ -│ @fastify/busboy │ '0.03 ms ± 0.09' │ '1.11 ms ± 0.05' │ '0.38 ms ± 0.03' │ '11.19 ms ± 0.24' │ +│ multipart-parser │ '0.01 ms ± 0.03' │ '1.06 ms ± 0.04' │ '0.10 ms ± 0.03' │ '10.60 ms ± 0.22' │ +│ multipasta │ '0.01 ms ± 0.03' │ '1.06 ms ± 0.03' │ '0.15 ms ± 0.02' │ '10.70 ms ± 2.70' │ +│ busboy │ '0.03 ms ± 0.09' │ '3.01 ms ± 0.08' │ '0.22 ms ± 0.03' │ '29.91 ms ± 0.91' │ +│ @fastify/busboy │ '0.03 ms ± 0.07' │ '1.20 ms ± 0.08' │ '0.39 ms ± 0.07' │ '11.86 ms ± 0.17' │ └──────────────────┴──────────────────┴──────────────────┴──────────────────┴───────────────────┘ -> @mjackson/multipart-parser@0.6.0 bench:bun /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.6.1 bench:bun /Users/michael/Projects/multipart-parser > bun run ./bench/runner.ts Platform: Darwin (23.5.0) -CPU: Apple M2 Pro -Date: 8/17/2024, 11:28:20 AM +CPU: Apple M1 Pro +Date: 8/18/2024, 4:20:58 PM Bun 1.1.21 ┌──────────────────┬────────────────┬────────────────┬─────────────────┬─────────────────┐ │ │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼────────────────┼────────────────┼─────────────────┼─────────────────┤ -│ multipart-parser │ 0.01 ms ± 0.05 │ 0.79 ms ± 0.06 │ 0.11 ms ± 0.09 │ 7.76 ms ± 0.28 │ -│ multipasta │ 0.01 ms ± 0.07 │ 0.93 ms ± 0.70 │ 0.23 ms ± 0.39 │ 7.57 ms ± 0.65 │ -│ busboy │ 0.03 ms ± 0.10 │ 3.30 ms ± 0.09 │ 0.33 ms ± 0.15 │ 33.15 ms ± 2.07 │ -│ @fastify/busboy │ 0.04 ms ± 0.14 │ 6.67 ms ± 0.10 │ 0.59 ms ± 0.13 │ 67.41 ms ± 3.33 │ +│ multipart-parser │ 0.01 ms ± 0.04 │ 0.91 ms ± 0.09 │ 0.11 ms ± 0.05 │ 8.23 ms ± 0.18 │ +│ multipasta │ 0.01 ms ± 0.03 │ 0.87 ms ± 0.08 │ 0.22 ms ± 0.15 │ 8.09 ms ± 0.15 │ +│ busboy │ 0.03 ms ± 0.07 │ 3.59 ms ± 0.13 │ 0.36 ms ± 0.17 │ 35.26 ms ± 0.39 │ +│ @fastify/busboy │ 0.04 ms ± 0.11 │ 7.23 ms ± 0.15 │ 0.63 ms ± 0.15 │ 71.86 ms ± 0.53 │ └──────────────────┴────────────────┴────────────────┴─────────────────┴─────────────────┘ -> @mjackson/multipart-parser@0.6.0 bench:deno /Users/michael/Projects/multipart-parser +> @mjackson/multipart-parser@0.6.1 bench:deno /Users/michael/Projects/multipart-parser > deno --unstable-byonm --unstable-sloppy-imports run --allow-sys ./bench/runner.ts Platform: Darwin (23.5.0) -CPU: Apple M2 Pro -Date: 8/17/2024, 11:31:27 AM +CPU: Apple M1 Pro +Date: 8/18/2024, 4:24:16 PM Deno 1.45.5 ┌──────────────────┬──────────────────┬───────────────────┬──────────────────┬────────────────────┐ │ (idx) │ 1 small file │ 1 large file │ 100 small files │ 5 large files │ ├──────────────────┼──────────────────┼───────────────────┼──────────────────┼────────────────────┤ -│ multipart-parser │ "0.01 ms ± 0.17" │ "1.00 ms ± 1.00" │ "0.08 ms ± 0.39" │ "9.77 ms ± 1.02" │ -│ multipasta │ "0.02 ms ± 0.18" │ "1.41 ms ± 0.91" │ "0.19 ms ± 0.58" │ "13.96 ms ± 2.40" │ -│ busboy │ "0.03 ms ± 0.25" │ "2.90 ms ± 0.99" │ "0.28 ms ± 0.70" │ "29.18 ms ± 2.17" │ -│ @fastify/busboy │ "0.05 ms ± 0.30" │ "11.40 ms ± 1.01" │ "0.74 ms ± 0.97" │ "114.81 ms ± 6.03" │ +│ multipart-parser │ "0.01 ms ± 0.15" │ "1.00 ms ± 1.00" │ "0.08 ms ± 0.39" │ "10.08 ms ± 0.41" │ +│ multipasta │ "0.01 ms ± 0.14" │ "1.02 ms ± 1.00" │ "0.17 ms ± 0.56" │ "14.59 ms ± 0.92" │ +│ busboy │ "0.04 ms ± 0.28" │ "3.04 ms ± 1.00" │ "0.30 ms ± 0.71" │ "29.86 ms ± 0.83" │ +│ @fastify/busboy │ "0.05 ms ± 0.31" │ "12.36 ms ± 0.78" │ "0.78 ms ± 0.98" │ "123.54 ms ± 5.04" │ └──────────────────┴──────────────────┴───────────────────┴──────────────────┴────────────────────┘ ``` From 24fcbe04ed84505fa0764c1e9d56c04f0c156773 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 18 Aug 2024 20:51:05 -0700 Subject: [PATCH 260/730] Small readability tweaks --- src/lib/multipart.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index ad3dab444a0..3cf2a442b0f 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -303,8 +303,6 @@ export class MultipartParser { } let header = chunk.subarray(index, headerEndIndex); - index = headerEndIndex + 4; // Skip header + \r\n\r\n - let part = new MultipartPart( header, new ReadableStream({ @@ -316,6 +314,8 @@ export class MultipartParser { handler(part); + index = headerEndIndex + 4; // Skip header + \r\n\r\n + this.#state = MultipartParserState.Body; continue; @@ -331,7 +331,7 @@ export class MultipartParser { throw new MultipartParseError('Invalid multipart stream: missing initial boundary'); } - index += this.#openingBoundaryLength; + index = this.#openingBoundaryLength; this.#state = MultipartParserState.AfterBoundary; } From c5607462027598319694a27434c089aa8208d390 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Sun, 18 Aug 2024 23:07:37 -0700 Subject: [PATCH 261/730] Fix `part.arrayBuffer()` type --- CHANGELOG.md | 5 +++++ src/lib/multipart.ts | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1de9e1d9d16..a5a07e0ecc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # `multipart-parser` CHANGELOG +## HEAD + +- Provide correct type for `part.arrayBuffer()` +- `part.isFile` now defaults to `true` if `part.mediaType === 'application/octet-stream'` + ## v0.6.1 (Aug 18, 2024) - More small performance improvements diff --git a/src/lib/multipart.ts b/src/lib/multipart.ts index 3cf2a442b0f..eafb05bb1c3 100644 --- a/src/lib/multipart.ts +++ b/src/lib/multipart.ts @@ -386,8 +386,8 @@ export class MultipartPart { /** * The content of this part as an `ArrayBuffer`. */ - async arrayBuffer(): Promise { - return (await this.bytes()).buffer; + async arrayBuffer(): Promise { + return (await this.bytes()).buffer as ArrayBuffer; } /** @@ -448,7 +448,7 @@ export class MultipartPart { * True if this part originated from a file upload. */ get isFile(): boolean { - return this.filename !== undefined; + return this.filename !== undefined || this.mediaType === 'application/octet-stream'; } /** From 905bd21d60133b581efb5a4b0e8d303e9063775f Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 19 Aug 2024 12:55:10 -0700 Subject: [PATCH 262/730] Initial commit --- .github/workflows/publish.yml | 32 +++ .gitignore | 5 + package.json | 21 ++ pnpm-lock.yaml | 403 ++++++++++++++++++++++++++++++++++ scripts/version.js | 30 +++ src/form-data-parser.ts | 5 + src/lib/form-data.spec.ts | 22 ++ src/lib/form-data.ts | 75 +++++++ 8 files changed, 593 insertions(+) create mode 100644 .github/workflows/publish.yml create mode 100644 .gitignore create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 scripts/version.js create mode 100644 src/form-data-parser.ts create mode 100644 src/lib/form-data.spec.ts create mode 100644 src/lib/form-data.ts diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000000..cbdc3b17796 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,32 @@ +name: Publish + +on: + push: + tags: + - v[0-9]* + +jobs: + build: + runs-on: ubuntu-latest + + permissions: + contents: write + id-token: write + + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '20.x' + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - run: pnpm install + + - name: Publish to npm + run: npm publish --provenance --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..c9282d7e5e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.tsimp +dist +node_modules + +*.tsbuildinfo \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000000..53a619bc4bd --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "form-data-parser", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@mjackson/multipart-parser": "^0.6.1" + }, + "devDependencies": { + "@types/node": "^22.4.1", + "prettier": "^3.3.3", + "tsimp": "^2.0.11", + "typescript": "^5.5.4" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000000..d937e438594 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,403 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@mjackson/multipart-parser': + specifier: ^0.6.1 + version: 0.6.1 + devDependencies: + '@types/node': + specifier: ^22.4.1 + version: 22.4.1 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + tsimp: + specifier: ^2.0.11 + version: 2.0.11(typescript@5.5.4) + typescript: + specifier: ^5.5.4 + version: 5.5.4 + +packages: + + '@isaacs/cached@1.0.1': + resolution: {integrity: sha512-7kGcJ9Hc1f4qpTApWz3swxbF9Qv1NF/GxuPtXeTptbsgvJIoufSd0h854Nq/2bw80F5C1onsFgEI05l+q0e4vw==} + + '@isaacs/catcher@1.0.4': + resolution: {integrity: sha512-g2klMwbnguClWNnCeQ1zYaDJsvPbIbnjdJPDE0z09MqoejJDZSLK5vIKiClq2Bkg5ubuI8vaN6wfIUi5GYzMVA==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@mjackson/headers@0.5.1': + resolution: {integrity: sha512-sJpFgecPT/zJvwk3GRNVWNs8EkwaJoUNU2D0VMlp+gDJs6cuSTm1q/aCZi3ZtuV6CgDEQ4l2ZjUG3A9JrQlbNA==} + + '@mjackson/multipart-parser@0.6.1': + resolution: {integrity: sha512-blI4HObze3ge1VQnSZSmhWv9tCm06Y23vVNBTffndhhmkdUpRsoIkw/3GXjcJXEOiciR3MjeTkBskJz6DMgspg==} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@types/node@22.4.1': + resolution: {integrity: sha512-1tbpb9325+gPnKK0dMm+/LMriX0vKxf6RnB0SZUqfyVkQ4fMgUSySqhxE/y8Jvs4NyF1yHzTfG9KlnkIODxPKg==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sock-daemon@1.4.2: + resolution: {integrity: sha512-IzbegWshWWR+UzQ7487mbdYNmfJ1jXUXQBUHooqtpylO+aW0vMVbFN2d2ug3CSPZ0wbG7ZTTGwpUuthIDFIOGg==} + engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} + + socket-post-message@1.0.3: + resolution: {integrity: sha512-UhJaB3xR2oF+HvddFOq2cBZi4zVKOHvdiBo+BaScNxsEUg3TLWSP8BkweKfe07kfH1thjn1hJR0af/w1EtBFjg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + tsimp@2.0.11: + resolution: {integrity: sha512-wRhMmvar8tWHN3ZmykD8f4B4sjCn/f8DFM67LRY+stf/LPa2Kq8ATE2PIi570/DiDJA8kjjxzos3EgP0LmnFLA==} + engines: {node: 16 >=16.17.0 || 18 >= 18.6.0 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.1.0 + + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + walk-up-path@3.0.1: + resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + +snapshots: + + '@isaacs/cached@1.0.1': + dependencies: + '@isaacs/catcher': 1.0.4 + + '@isaacs/catcher@1.0.4': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@mjackson/headers@0.5.1': {} + + '@mjackson/multipart-parser@0.6.1': + dependencies: + '@mjackson/headers': 0.5.1 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@types/node@22.4.1': + dependencies: + undici-types: 6.19.8 + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + balanced-match@1.0.2: {} + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 1.11.1 + + is-fullwidth-code-point@3.0.0: {} + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + lru-cache@10.4.3: {} + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + + mkdirp@3.0.1: {} + + package-json-from-dist@1.0.0: {} + + path-key@3.1.1: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + pirates@4.0.6: {} + + prettier@3.3.3: {} + + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + sock-daemon@1.4.2: + dependencies: + rimraf: 5.0.10 + signal-exit: 4.1.0 + socket-post-message: 1.0.3 + + socket-post-message@1.0.3: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + tsimp@2.0.11(typescript@5.5.4): + dependencies: + '@isaacs/cached': 1.0.1 + '@isaacs/catcher': 1.0.4 + foreground-child: 3.3.0 + mkdirp: 3.0.1 + pirates: 4.0.6 + rimraf: 5.0.10 + signal-exit: 4.1.0 + sock-daemon: 1.4.2 + typescript: 5.5.4 + walk-up-path: 3.0.1 + + typescript@5.5.4: {} + + undici-types@6.19.8: {} + + walk-up-path@3.0.1: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 diff --git a/scripts/version.js b/scripts/version.js new file mode 100644 index 00000000000..3c140ddd756 --- /dev/null +++ b/scripts/version.js @@ -0,0 +1,30 @@ +import * as cp from "node:child_process"; +import * as fs from "node:fs"; +import * as path from "node:path"; +import * as process from "node:process"; + +const __dirname = path.dirname(new URL(import.meta.url).pathname); +const packageVersion = process.env.npm_package_version; + +// Update CHANGELOG.md with the current version +let changelogPath = path.resolve(__dirname, "../CHANGELOG.md"); +let changelog = fs.readFileSync(changelogPath, "utf-8"); +let match = /^## HEAD\n/m.exec(changelog); +if (match) { + let today = new Date().toLocaleDateString("en-US", { + month: "short", + day: "numeric", + year: "numeric" + }); + + changelog = + changelog.slice(0, match.index) + + `## v${packageVersion} (${today})\n` + + changelog.slice(match.index + match[0].length); + + fs.writeFileSync(changelogPath, changelog); + cp.execSync("git add CHANGELOG.md"); +} else { + console.error('Could not find "## HEAD" in CHANGELOG.md'); + process.exit(1); +} diff --git a/src/form-data-parser.ts b/src/form-data-parser.ts new file mode 100644 index 00000000000..63fdc81a1ab --- /dev/null +++ b/src/form-data-parser.ts @@ -0,0 +1,5 @@ +export { + isUrlEncodedRequest, + type FileUploadHandler, + parseFormData +} from "./lib/form-data.js"; diff --git a/src/lib/form-data.spec.ts b/src/lib/form-data.spec.ts new file mode 100644 index 00000000000..cf49ddb18c1 --- /dev/null +++ b/src/lib/form-data.spec.ts @@ -0,0 +1,22 @@ +import * as assert from "node:assert/strict"; +import { describe, it } from "node:test"; + +import { isUrlEncodedRequest, parseFormData } from "./form-data.js"; + +describe("isUrlEncodedRequest", () => { + it('returns true for "application/x-www-form-urlencoded" requests', () => { + let request = new Request("https://example.com", { + headers: { "Content-Type": "application/x-www-form-urlencoded" } + }); + + assert.ok(isUrlEncodedRequest(request)); + }); + + it('returns false for "multipart/form-data" requests', () => { + let request = new Request("https://example.com", { + headers: { "Content-Type": "multipart/form-data" } + }); + + assert.ok(!isUrlEncodedRequest(request)); + }); +}); diff --git a/src/lib/form-data.ts b/src/lib/form-data.ts new file mode 100644 index 00000000000..bf05d0c68b5 --- /dev/null +++ b/src/lib/form-data.ts @@ -0,0 +1,75 @@ +import { + isMultipartRequest, + parseMultipartRequest, + type MultipartPart +} from "@mjackson/multipart-parser"; + +/** + * Returns true if the request is URL encoded. + */ +export function isUrlEncodedRequest(request: Request): boolean { + let contentType = request.headers.get("Content-Type"); + return ( + contentType != null && + contentType.startsWith("application/x-www-form-urlencoded") + ); +} + +/** + * A function used for handling file uploads. + */ +export interface FileUploadHandler { + (part: MultipartPart): Promise; +} + +async function defaultFileUploadHandler(part: MultipartPart): Promise { + return new File([await part.arrayBuffer()], part.filename ?? "", { + type: part.mediaType + }); +} + +/** + * Parses a `Request` body into a `FormData` object. This is useful for accessing the data contained + * in a HTTP `POST` request generated by a HTML `