├── .github └── workflows │ ├── cd.yaml │ └── ci.yaml ├── .gitignore ├── README.md ├── biome.json ├── package.json ├── pnpm-lock.yaml ├── src ├── impl.ts ├── index.ts └── types.ts ├── tests ├── global.d.ts ├── index.test.ts ├── util.ts └── worker.ts ├── tsconfig.build.json ├── tsconfig.json └── vitest.config.ts /.github/workflows/cd.yaml: -------------------------------------------------------------------------------- 1 | name: Publish to NPM 2 | on: 3 | release: 4 | types: [published] 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v3 10 | - uses: pnpm/action-setup@v3 11 | with: 12 | version: 8 13 | - uses: actions/setup-node@v3 14 | with: 15 | node-version: "20.x" 16 | registry-url: "https://registry.npmjs.org" 17 | - run: pnpm install 18 | - run: pnpm build 19 | - run: pnpm publish --no-git-checks 20 | env: 21 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 22 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | strategy: 15 | matrix: 16 | node-version: [22] 17 | steps: 18 | - uses: actions/checkout@v3 19 | - uses: pnpm/action-setup@v3 20 | with: 21 | version: 9 22 | 23 | - name: Use Node.js 24 | uses: actions/setup-node@v3 25 | with: 26 | node-version: ${{ matrix.node-version }} 27 | cache: "pnpm" 28 | 29 | - name: Install dependencies 30 | run: pnpm install --frozen-lockfile 31 | 32 | - name: Biome format check 33 | run: pnpm check:format 34 | 35 | - name: Biome lint 36 | run: pnpm check:lint 37 | 38 | - name: Run tests 39 | run: pnpm test 40 | 41 | - name: Build 42 | run: pnpm build 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

react-router-durable

2 | 3 |

4 | A package for using Cloudflare's Durable Objects as React Router loaders and actions. 5 |

6 | 7 |

8 | 9 | downloads 10 | 11 | 12 | npm version 13 | 14 | 15 | MIT license 16 | 17 |

18 | 19 | ## Example 20 | 21 | ```tsx 22 | // /app/durable-objects.ts 23 | import type { LoaderFunctionArgs } from "react-router"; 24 | import { DurableObject } from "cloudflare:workers"; 25 | 26 | export class SampleDurableObject extends DurableObject { 27 | async sampleLoader({ request }: LoaderFunctionArgs) { 28 | return { url: request.url }; 29 | } 30 | } 31 | 32 | // /app/routes/home.tsx 33 | import { durableLoader } from "react-router-durable"; 34 | import { SampleDurableObject } from "../durable-objects"; 35 | 36 | // Makes a react-router loader that proxies the load to the SampleDurableObject 37 | export const loader = durableLoader( 38 | SampleDurableObject, 39 | (env) => env.sample.sampleLoader, 40 | "sample" // the name of the DurableObject to use 41 | ); 42 | 43 | export default function Home() { 44 | const { url } = useLoaderData(); 45 | 46 | return

url: {url}

; 47 | } 48 | ``` 49 | 50 | ## Installation 51 | 52 | ``` 53 | # NPM 54 | $ npm install --save react-router-durable 55 | # Yarn 56 | $ yarn add react-router-durable 57 | # PNPM 58 | $ pnpm add react-router-durable 59 | # Bun 60 | $ bun add react-router-durable 61 | ``` 62 | 63 | ## License 64 | 65 | Distributed under the MIT License. See [LICENSE](LICENSE) for more information. 66 | -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", 3 | "vcs": { 4 | "enabled": false, 5 | "clientKind": "git", 6 | "useIgnoreFile": false 7 | }, 8 | "files": { 9 | "ignoreUnknown": false, 10 | "ignore": ["dist/**/*", "node_modules/**/*"] 11 | }, 12 | "formatter": { 13 | "enabled": true, 14 | "indentStyle": "space", 15 | "indentWidth": 2 16 | }, 17 | "organizeImports": { 18 | "enabled": true 19 | }, 20 | "linter": { 21 | "enabled": true, 22 | "rules": { 23 | "recommended": true, 24 | "suspicious": { 25 | "noExplicitAny": "off" 26 | }, 27 | "complexity": { 28 | "noBannedTypes": "off" 29 | } 30 | } 31 | }, 32 | "javascript": { 33 | "formatter": { 34 | "quoteStyle": "double" 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-router-durable", 3 | "version": "0.1.1", 4 | "description": "A package for using Cloudflare Durable Objects as React Router loaders and actions ", 5 | "author": "Zeb Piasecki ", 6 | "repository": "https://github.com/zebp/react-router-durable", 7 | "license": "MIT", 8 | "keywords": ["cloudflare", "workers", "durable-objects", "react-router"], 9 | "type": "module", 10 | "main": "dist/index.js", 11 | "types": "dist/index.d.ts", 12 | "exports": { 13 | ".": { 14 | "import": "./dist/index.js", 15 | "types": "./dist/index.d.ts" 16 | } 17 | }, 18 | "scripts": { 19 | "build": "tsc -p tsconfig.build.json", 20 | "build:watch": "tsc -p tsconfig.build.json -w", 21 | "format": "biome format --write", 22 | "check:lint": "biome lint", 23 | "check:format": "biome format", 24 | "test": "vitest run" 25 | }, 26 | "devDependencies": { 27 | "@biomejs/biome": "^1.9.4", 28 | "@cloudflare/vitest-pool-workers": "^0.5.40", 29 | "@cloudflare/workers-types": "^1.20250124.0", 30 | "typescript": "^5.7.3", 31 | "vitest": "2.1.8" 32 | }, 33 | "peerDependencies": { 34 | "react-router": "^7.1.3" 35 | }, 36 | "files": ["dist", "LICENSE"] 37 | } 38 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | react-router: 12 | specifier: ^7.1.3 13 | version: 7.1.3(react@19.0.0) 14 | devDependencies: 15 | '@biomejs/biome': 16 | specifier: ^1.9.4 17 | version: 1.9.4 18 | '@cloudflare/vitest-pool-workers': 19 | specifier: ^0.5.40 20 | version: 0.5.41(@cloudflare/workers-types@1.20250124.0)(@vitest/runner@2.1.8)(@vitest/snapshot@2.1.8)(vitest@2.1.8(@types/node@22.10.10)) 21 | '@cloudflare/workers-types': 22 | specifier: ^1.20250124.0 23 | version: 1.20250124.0 24 | typescript: 25 | specifier: ^5.7.3 26 | version: 5.7.3 27 | vitest: 28 | specifier: 2.1.8 29 | version: 2.1.8(@types/node@22.10.10) 30 | 31 | packages: 32 | 33 | '@biomejs/biome@1.9.4': 34 | resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} 35 | engines: {node: '>=14.21.3'} 36 | hasBin: true 37 | 38 | '@biomejs/cli-darwin-arm64@1.9.4': 39 | resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} 40 | engines: {node: '>=14.21.3'} 41 | cpu: [arm64] 42 | os: [darwin] 43 | 44 | '@biomejs/cli-darwin-x64@1.9.4': 45 | resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} 46 | engines: {node: '>=14.21.3'} 47 | cpu: [x64] 48 | os: [darwin] 49 | 50 | '@biomejs/cli-linux-arm64-musl@1.9.4': 51 | resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} 52 | engines: {node: '>=14.21.3'} 53 | cpu: [arm64] 54 | os: [linux] 55 | 56 | '@biomejs/cli-linux-arm64@1.9.4': 57 | resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} 58 | engines: {node: '>=14.21.3'} 59 | cpu: [arm64] 60 | os: [linux] 61 | 62 | '@biomejs/cli-linux-x64-musl@1.9.4': 63 | resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} 64 | engines: {node: '>=14.21.3'} 65 | cpu: [x64] 66 | os: [linux] 67 | 68 | '@biomejs/cli-linux-x64@1.9.4': 69 | resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} 70 | engines: {node: '>=14.21.3'} 71 | cpu: [x64] 72 | os: [linux] 73 | 74 | '@biomejs/cli-win32-arm64@1.9.4': 75 | resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} 76 | engines: {node: '>=14.21.3'} 77 | cpu: [arm64] 78 | os: [win32] 79 | 80 | '@biomejs/cli-win32-x64@1.9.4': 81 | resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} 82 | engines: {node: '>=14.21.3'} 83 | cpu: [x64] 84 | os: [win32] 85 | 86 | '@cloudflare/kv-asset-handler@0.3.4': 87 | resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} 88 | engines: {node: '>=16.13'} 89 | 90 | '@cloudflare/vitest-pool-workers@0.5.41': 91 | resolution: {integrity: sha512-J0uYmOKJgyo/az5nV8QHlR6xQ+HHB6S65tOEutkvUPbuPDbFlBPRT+XHJhSTNNvZGeM1t2qZIzxp0WGmXLtNlQ==} 92 | peerDependencies: 93 | '@vitest/runner': 2.0.x - 2.1.x 94 | '@vitest/snapshot': 2.0.x - 2.1.x 95 | vitest: 2.0.x - 2.1.x 96 | 97 | '@cloudflare/workerd-darwin-64@1.20241230.0': 98 | resolution: {integrity: sha512-BZHLg4bbhNQoaY1Uan81O3FV/zcmWueC55juhnaI7NAobiQth9RppadPNpxNAmS9fK2mR5z8xrwMQSQrHmztyQ==} 99 | engines: {node: '>=16'} 100 | cpu: [x64] 101 | os: [darwin] 102 | 103 | '@cloudflare/workerd-darwin-arm64@1.20241230.0': 104 | resolution: {integrity: sha512-lllxycj7EzYoJ0VOJh8M3palUgoonVrILnzGrgsworgWlIpgjfXGS7b41tEGCw6AxSxL9prmTIGtfSPUvn/rjg==} 105 | engines: {node: '>=16'} 106 | cpu: [arm64] 107 | os: [darwin] 108 | 109 | '@cloudflare/workerd-linux-64@1.20241230.0': 110 | resolution: {integrity: sha512-Y3mHcW0KghOmWdNZyHYpEOG4Ba/ga8tht5vj1a+WXfagEjMO8Y98XhZUlCaYa9yB7Wh5jVcK5LM2jlO/BLgqpA==} 111 | engines: {node: '>=16'} 112 | cpu: [x64] 113 | os: [linux] 114 | 115 | '@cloudflare/workerd-linux-arm64@1.20241230.0': 116 | resolution: {integrity: sha512-IAjhsWPlHzhhkJ6I49sDG6XfMnhPvv0szKGXxTWQK/IWMrbGdHm4RSfNKBSoLQm67jGMIzbmcrX9UIkms27Y1g==} 117 | engines: {node: '>=16'} 118 | cpu: [arm64] 119 | os: [linux] 120 | 121 | '@cloudflare/workerd-windows-64@1.20241230.0': 122 | resolution: {integrity: sha512-y5SPIk9iOb2gz+yWtHxoeMnjPnkYQswiCJ480oHC6zexnJLlKTpcmBCjDH1nWCT4pQi8F25gaH8thgElf4NvXQ==} 123 | engines: {node: '>=16'} 124 | cpu: [x64] 125 | os: [win32] 126 | 127 | '@cloudflare/workers-types@1.20250124.0': 128 | resolution: {integrity: sha512-MKQNB8br+Gc7VtufJGJRAfbnGwo4dizp+HesiT8mLG8u8fZzeqanS/5RVwRcqV0tt6OBMkDej0LYoq6jVsns/g==} 129 | 130 | '@cspotcode/source-map-support@0.8.1': 131 | resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} 132 | engines: {node: '>=12'} 133 | 134 | '@esbuild-plugins/node-globals-polyfill@0.2.3': 135 | resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} 136 | peerDependencies: 137 | esbuild: '*' 138 | 139 | '@esbuild-plugins/node-modules-polyfill@0.2.2': 140 | resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} 141 | peerDependencies: 142 | esbuild: '*' 143 | 144 | '@esbuild/aix-ppc64@0.21.5': 145 | resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} 146 | engines: {node: '>=12'} 147 | cpu: [ppc64] 148 | os: [aix] 149 | 150 | '@esbuild/android-arm64@0.17.19': 151 | resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} 152 | engines: {node: '>=12'} 153 | cpu: [arm64] 154 | os: [android] 155 | 156 | '@esbuild/android-arm64@0.21.5': 157 | resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} 158 | engines: {node: '>=12'} 159 | cpu: [arm64] 160 | os: [android] 161 | 162 | '@esbuild/android-arm@0.17.19': 163 | resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} 164 | engines: {node: '>=12'} 165 | cpu: [arm] 166 | os: [android] 167 | 168 | '@esbuild/android-arm@0.21.5': 169 | resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} 170 | engines: {node: '>=12'} 171 | cpu: [arm] 172 | os: [android] 173 | 174 | '@esbuild/android-x64@0.17.19': 175 | resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} 176 | engines: {node: '>=12'} 177 | cpu: [x64] 178 | os: [android] 179 | 180 | '@esbuild/android-x64@0.21.5': 181 | resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} 182 | engines: {node: '>=12'} 183 | cpu: [x64] 184 | os: [android] 185 | 186 | '@esbuild/darwin-arm64@0.17.19': 187 | resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} 188 | engines: {node: '>=12'} 189 | cpu: [arm64] 190 | os: [darwin] 191 | 192 | '@esbuild/darwin-arm64@0.21.5': 193 | resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} 194 | engines: {node: '>=12'} 195 | cpu: [arm64] 196 | os: [darwin] 197 | 198 | '@esbuild/darwin-x64@0.17.19': 199 | resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} 200 | engines: {node: '>=12'} 201 | cpu: [x64] 202 | os: [darwin] 203 | 204 | '@esbuild/darwin-x64@0.21.5': 205 | resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} 206 | engines: {node: '>=12'} 207 | cpu: [x64] 208 | os: [darwin] 209 | 210 | '@esbuild/freebsd-arm64@0.17.19': 211 | resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} 212 | engines: {node: '>=12'} 213 | cpu: [arm64] 214 | os: [freebsd] 215 | 216 | '@esbuild/freebsd-arm64@0.21.5': 217 | resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} 218 | engines: {node: '>=12'} 219 | cpu: [arm64] 220 | os: [freebsd] 221 | 222 | '@esbuild/freebsd-x64@0.17.19': 223 | resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} 224 | engines: {node: '>=12'} 225 | cpu: [x64] 226 | os: [freebsd] 227 | 228 | '@esbuild/freebsd-x64@0.21.5': 229 | resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} 230 | engines: {node: '>=12'} 231 | cpu: [x64] 232 | os: [freebsd] 233 | 234 | '@esbuild/linux-arm64@0.17.19': 235 | resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} 236 | engines: {node: '>=12'} 237 | cpu: [arm64] 238 | os: [linux] 239 | 240 | '@esbuild/linux-arm64@0.21.5': 241 | resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} 242 | engines: {node: '>=12'} 243 | cpu: [arm64] 244 | os: [linux] 245 | 246 | '@esbuild/linux-arm@0.17.19': 247 | resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} 248 | engines: {node: '>=12'} 249 | cpu: [arm] 250 | os: [linux] 251 | 252 | '@esbuild/linux-arm@0.21.5': 253 | resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} 254 | engines: {node: '>=12'} 255 | cpu: [arm] 256 | os: [linux] 257 | 258 | '@esbuild/linux-ia32@0.17.19': 259 | resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} 260 | engines: {node: '>=12'} 261 | cpu: [ia32] 262 | os: [linux] 263 | 264 | '@esbuild/linux-ia32@0.21.5': 265 | resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} 266 | engines: {node: '>=12'} 267 | cpu: [ia32] 268 | os: [linux] 269 | 270 | '@esbuild/linux-loong64@0.17.19': 271 | resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} 272 | engines: {node: '>=12'} 273 | cpu: [loong64] 274 | os: [linux] 275 | 276 | '@esbuild/linux-loong64@0.21.5': 277 | resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} 278 | engines: {node: '>=12'} 279 | cpu: [loong64] 280 | os: [linux] 281 | 282 | '@esbuild/linux-mips64el@0.17.19': 283 | resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} 284 | engines: {node: '>=12'} 285 | cpu: [mips64el] 286 | os: [linux] 287 | 288 | '@esbuild/linux-mips64el@0.21.5': 289 | resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} 290 | engines: {node: '>=12'} 291 | cpu: [mips64el] 292 | os: [linux] 293 | 294 | '@esbuild/linux-ppc64@0.17.19': 295 | resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} 296 | engines: {node: '>=12'} 297 | cpu: [ppc64] 298 | os: [linux] 299 | 300 | '@esbuild/linux-ppc64@0.21.5': 301 | resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} 302 | engines: {node: '>=12'} 303 | cpu: [ppc64] 304 | os: [linux] 305 | 306 | '@esbuild/linux-riscv64@0.17.19': 307 | resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} 308 | engines: {node: '>=12'} 309 | cpu: [riscv64] 310 | os: [linux] 311 | 312 | '@esbuild/linux-riscv64@0.21.5': 313 | resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} 314 | engines: {node: '>=12'} 315 | cpu: [riscv64] 316 | os: [linux] 317 | 318 | '@esbuild/linux-s390x@0.17.19': 319 | resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} 320 | engines: {node: '>=12'} 321 | cpu: [s390x] 322 | os: [linux] 323 | 324 | '@esbuild/linux-s390x@0.21.5': 325 | resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} 326 | engines: {node: '>=12'} 327 | cpu: [s390x] 328 | os: [linux] 329 | 330 | '@esbuild/linux-x64@0.17.19': 331 | resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} 332 | engines: {node: '>=12'} 333 | cpu: [x64] 334 | os: [linux] 335 | 336 | '@esbuild/linux-x64@0.21.5': 337 | resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} 338 | engines: {node: '>=12'} 339 | cpu: [x64] 340 | os: [linux] 341 | 342 | '@esbuild/netbsd-x64@0.17.19': 343 | resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} 344 | engines: {node: '>=12'} 345 | cpu: [x64] 346 | os: [netbsd] 347 | 348 | '@esbuild/netbsd-x64@0.21.5': 349 | resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} 350 | engines: {node: '>=12'} 351 | cpu: [x64] 352 | os: [netbsd] 353 | 354 | '@esbuild/openbsd-x64@0.17.19': 355 | resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} 356 | engines: {node: '>=12'} 357 | cpu: [x64] 358 | os: [openbsd] 359 | 360 | '@esbuild/openbsd-x64@0.21.5': 361 | resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} 362 | engines: {node: '>=12'} 363 | cpu: [x64] 364 | os: [openbsd] 365 | 366 | '@esbuild/sunos-x64@0.17.19': 367 | resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} 368 | engines: {node: '>=12'} 369 | cpu: [x64] 370 | os: [sunos] 371 | 372 | '@esbuild/sunos-x64@0.21.5': 373 | resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} 374 | engines: {node: '>=12'} 375 | cpu: [x64] 376 | os: [sunos] 377 | 378 | '@esbuild/win32-arm64@0.17.19': 379 | resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} 380 | engines: {node: '>=12'} 381 | cpu: [arm64] 382 | os: [win32] 383 | 384 | '@esbuild/win32-arm64@0.21.5': 385 | resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} 386 | engines: {node: '>=12'} 387 | cpu: [arm64] 388 | os: [win32] 389 | 390 | '@esbuild/win32-ia32@0.17.19': 391 | resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} 392 | engines: {node: '>=12'} 393 | cpu: [ia32] 394 | os: [win32] 395 | 396 | '@esbuild/win32-ia32@0.21.5': 397 | resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} 398 | engines: {node: '>=12'} 399 | cpu: [ia32] 400 | os: [win32] 401 | 402 | '@esbuild/win32-x64@0.17.19': 403 | resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} 404 | engines: {node: '>=12'} 405 | cpu: [x64] 406 | os: [win32] 407 | 408 | '@esbuild/win32-x64@0.21.5': 409 | resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} 410 | engines: {node: '>=12'} 411 | cpu: [x64] 412 | os: [win32] 413 | 414 | '@fastify/busboy@2.1.1': 415 | resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} 416 | engines: {node: '>=14'} 417 | 418 | '@jridgewell/resolve-uri@3.1.2': 419 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 420 | engines: {node: '>=6.0.0'} 421 | 422 | '@jridgewell/sourcemap-codec@1.5.0': 423 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} 424 | 425 | '@jridgewell/trace-mapping@0.3.9': 426 | resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} 427 | 428 | '@rollup/rollup-android-arm-eabi@4.32.0': 429 | resolution: {integrity: sha512-G2fUQQANtBPsNwiVFg4zKiPQyjVKZCUdQUol53R8E71J7AsheRMV/Yv/nB8giOcOVqP7//eB5xPqieBYZe9bGg==} 430 | cpu: [arm] 431 | os: [android] 432 | 433 | '@rollup/rollup-android-arm64@4.32.0': 434 | resolution: {integrity: sha512-qhFwQ+ljoymC+j5lXRv8DlaJYY/+8vyvYmVx074zrLsu5ZGWYsJNLjPPVJJjhZQpyAKUGPydOq9hRLLNvh1s3A==} 435 | cpu: [arm64] 436 | os: [android] 437 | 438 | '@rollup/rollup-darwin-arm64@4.32.0': 439 | resolution: {integrity: sha512-44n/X3lAlWsEY6vF8CzgCx+LQaoqWGN7TzUfbJDiTIOjJm4+L2Yq+r5a8ytQRGyPqgJDs3Rgyo8eVL7n9iW6AQ==} 440 | cpu: [arm64] 441 | os: [darwin] 442 | 443 | '@rollup/rollup-darwin-x64@4.32.0': 444 | resolution: {integrity: sha512-F9ct0+ZX5Np6+ZDztxiGCIvlCaW87HBdHcozUfsHnj1WCUTBUubAoanhHUfnUHZABlElyRikI0mgcw/qdEm2VQ==} 445 | cpu: [x64] 446 | os: [darwin] 447 | 448 | '@rollup/rollup-freebsd-arm64@4.32.0': 449 | resolution: {integrity: sha512-JpsGxLBB2EFXBsTLHfkZDsXSpSmKD3VxXCgBQtlPcuAqB8TlqtLcbeMhxXQkCDv1avgwNjF8uEIbq5p+Cee0PA==} 450 | cpu: [arm64] 451 | os: [freebsd] 452 | 453 | '@rollup/rollup-freebsd-x64@4.32.0': 454 | resolution: {integrity: sha512-wegiyBT6rawdpvnD9lmbOpx5Sph+yVZKHbhnSP9MqUEDX08G4UzMU+D87jrazGE7lRSyTRs6NEYHtzfkJ3FjjQ==} 455 | cpu: [x64] 456 | os: [freebsd] 457 | 458 | '@rollup/rollup-linux-arm-gnueabihf@4.32.0': 459 | resolution: {integrity: sha512-3pA7xecItbgOs1A5H58dDvOUEboG5UfpTq3WzAdF54acBbUM+olDJAPkgj1GRJ4ZqE12DZ9/hNS2QZk166v92A==} 460 | cpu: [arm] 461 | os: [linux] 462 | 463 | '@rollup/rollup-linux-arm-musleabihf@4.32.0': 464 | resolution: {integrity: sha512-Y7XUZEVISGyge51QbYyYAEHwpGgmRrAxQXO3siyYo2kmaj72USSG8LtlQQgAtlGfxYiOwu+2BdbPjzEpcOpRmQ==} 465 | cpu: [arm] 466 | os: [linux] 467 | 468 | '@rollup/rollup-linux-arm64-gnu@4.32.0': 469 | resolution: {integrity: sha512-r7/OTF5MqeBrZo5omPXcTnjvv1GsrdH8a8RerARvDFiDwFpDVDnJyByYM/nX+mvks8XXsgPUxkwe/ltaX2VH7w==} 470 | cpu: [arm64] 471 | os: [linux] 472 | 473 | '@rollup/rollup-linux-arm64-musl@4.32.0': 474 | resolution: {integrity: sha512-HJbifC9vex9NqnlodV2BHVFNuzKL5OnsV2dvTw6e1dpZKkNjPG6WUq+nhEYV6Hv2Bv++BXkwcyoGlXnPrjAKXw==} 475 | cpu: [arm64] 476 | os: [linux] 477 | 478 | '@rollup/rollup-linux-loongarch64-gnu@4.32.0': 479 | resolution: {integrity: sha512-VAEzZTD63YglFlWwRj3taofmkV1V3xhebDXffon7msNz4b14xKsz7utO6F8F4cqt8K/ktTl9rm88yryvDpsfOw==} 480 | cpu: [loong64] 481 | os: [linux] 482 | 483 | '@rollup/rollup-linux-powerpc64le-gnu@4.32.0': 484 | resolution: {integrity: sha512-Sts5DST1jXAc9YH/iik1C9QRsLcCoOScf3dfbY5i4kH9RJpKxiTBXqm7qU5O6zTXBTEZry69bGszr3SMgYmMcQ==} 485 | cpu: [ppc64] 486 | os: [linux] 487 | 488 | '@rollup/rollup-linux-riscv64-gnu@4.32.0': 489 | resolution: {integrity: sha512-qhlXeV9AqxIyY9/R1h1hBD6eMvQCO34ZmdYvry/K+/MBs6d1nRFLm6BOiITLVI+nFAAB9kUB6sdJRKyVHXnqZw==} 490 | cpu: [riscv64] 491 | os: [linux] 492 | 493 | '@rollup/rollup-linux-s390x-gnu@4.32.0': 494 | resolution: {integrity: sha512-8ZGN7ExnV0qjXa155Rsfi6H8M4iBBwNLBM9lcVS+4NcSzOFaNqmt7djlox8pN1lWrRPMRRQ8NeDlozIGx3Omsw==} 495 | cpu: [s390x] 496 | os: [linux] 497 | 498 | '@rollup/rollup-linux-x64-gnu@4.32.0': 499 | resolution: {integrity: sha512-VDzNHtLLI5s7xd/VubyS10mq6TxvZBp+4NRWoW+Hi3tgV05RtVm4qK99+dClwTN1McA6PHwob6DEJ6PlXbY83A==} 500 | cpu: [x64] 501 | os: [linux] 502 | 503 | '@rollup/rollup-linux-x64-musl@4.32.0': 504 | resolution: {integrity: sha512-qcb9qYDlkxz9DxJo7SDhWxTWV1gFuwznjbTiov289pASxlfGbaOD54mgbs9+z94VwrXtKTu+2RqwlSTbiOqxGg==} 505 | cpu: [x64] 506 | os: [linux] 507 | 508 | '@rollup/rollup-win32-arm64-msvc@4.32.0': 509 | resolution: {integrity: sha512-pFDdotFDMXW2AXVbfdUEfidPAk/OtwE/Hd4eYMTNVVaCQ6Yl8et0meDaKNL63L44Haxv4UExpv9ydSf3aSayDg==} 510 | cpu: [arm64] 511 | os: [win32] 512 | 513 | '@rollup/rollup-win32-ia32-msvc@4.32.0': 514 | resolution: {integrity: sha512-/TG7WfrCAjeRNDvI4+0AAMoHxea/USWhAzf9PVDFHbcqrQ7hMMKp4jZIy4VEjk72AAfN5k4TiSMRXRKf/0akSw==} 515 | cpu: [ia32] 516 | os: [win32] 517 | 518 | '@rollup/rollup-win32-x64-msvc@4.32.0': 519 | resolution: {integrity: sha512-5hqO5S3PTEO2E5VjCePxv40gIgyS2KvO7E7/vvC/NbIW4SIRamkMr1hqj+5Y67fbBWv/bQLB6KelBQmXlyCjWA==} 520 | cpu: [x64] 521 | os: [win32] 522 | 523 | '@types/cookie@0.6.0': 524 | resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} 525 | 526 | '@types/estree@1.0.6': 527 | resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} 528 | 529 | '@types/node-forge@1.3.11': 530 | resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} 531 | 532 | '@types/node@22.10.10': 533 | resolution: {integrity: sha512-X47y/mPNzxviAGY5TcYPtYL8JsY3kAq2n8fMmKoRCxq/c4v4pyGNCzM2R6+M5/umG4ZfHuT+sgqDYqWc9rJ6ww==} 534 | 535 | '@vitest/expect@2.1.8': 536 | resolution: {integrity: sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==} 537 | 538 | '@vitest/mocker@2.1.8': 539 | resolution: {integrity: sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==} 540 | peerDependencies: 541 | msw: ^2.4.9 542 | vite: ^5.0.0 543 | peerDependenciesMeta: 544 | msw: 545 | optional: true 546 | vite: 547 | optional: true 548 | 549 | '@vitest/pretty-format@2.1.8': 550 | resolution: {integrity: sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==} 551 | 552 | '@vitest/runner@2.1.8': 553 | resolution: {integrity: sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==} 554 | 555 | '@vitest/snapshot@2.1.8': 556 | resolution: {integrity: sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==} 557 | 558 | '@vitest/spy@2.1.8': 559 | resolution: {integrity: sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==} 560 | 561 | '@vitest/utils@2.1.8': 562 | resolution: {integrity: sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==} 563 | 564 | acorn-walk@8.3.4: 565 | resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} 566 | engines: {node: '>=0.4.0'} 567 | 568 | acorn@8.14.0: 569 | resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} 570 | engines: {node: '>=0.4.0'} 571 | hasBin: true 572 | 573 | as-table@1.0.55: 574 | resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} 575 | 576 | assertion-error@2.0.1: 577 | resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} 578 | engines: {node: '>=12'} 579 | 580 | birpc@0.2.14: 581 | resolution: {integrity: sha512-37FHE8rqsYM5JEKCnXFyHpBCzvgHEExwVVTq+nUmloInU7l8ezD1TpOhKpS8oe1DTYFqEK27rFZVKG43oTqXRA==} 582 | 583 | blake3-wasm@2.1.5: 584 | resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} 585 | 586 | cac@6.7.14: 587 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 588 | engines: {node: '>=8'} 589 | 590 | capnp-ts@0.7.0: 591 | resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} 592 | 593 | chai@5.1.2: 594 | resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} 595 | engines: {node: '>=12'} 596 | 597 | check-error@2.1.1: 598 | resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} 599 | engines: {node: '>= 16'} 600 | 601 | chokidar@4.0.3: 602 | resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} 603 | engines: {node: '>= 14.16.0'} 604 | 605 | cjs-module-lexer@1.4.1: 606 | resolution: {integrity: sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==} 607 | 608 | confbox@0.1.8: 609 | resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} 610 | 611 | cookie@0.7.2: 612 | resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} 613 | engines: {node: '>= 0.6'} 614 | 615 | cookie@1.0.2: 616 | resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} 617 | engines: {node: '>=18'} 618 | 619 | data-uri-to-buffer@2.0.2: 620 | resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} 621 | 622 | date-fns@4.1.0: 623 | resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} 624 | 625 | debug@4.4.0: 626 | resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} 627 | engines: {node: '>=6.0'} 628 | peerDependencies: 629 | supports-color: '*' 630 | peerDependenciesMeta: 631 | supports-color: 632 | optional: true 633 | 634 | deep-eql@5.0.2: 635 | resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} 636 | engines: {node: '>=6'} 637 | 638 | defu@6.1.4: 639 | resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} 640 | 641 | devalue@4.3.3: 642 | resolution: {integrity: sha512-UH8EL6H2ifcY8TbD2QsxwCC/pr5xSwPvv85LrLXVihmHVC3T3YqTCIwnR5ak0yO1KYqlxrPVOA/JVZJYPy2ATg==} 643 | 644 | es-module-lexer@1.6.0: 645 | resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} 646 | 647 | esbuild@0.17.19: 648 | resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} 649 | engines: {node: '>=12'} 650 | hasBin: true 651 | 652 | esbuild@0.21.5: 653 | resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} 654 | engines: {node: '>=12'} 655 | hasBin: true 656 | 657 | escape-string-regexp@4.0.0: 658 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 659 | engines: {node: '>=10'} 660 | 661 | estree-walker@0.6.1: 662 | resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} 663 | 664 | estree-walker@3.0.3: 665 | resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} 666 | 667 | exit-hook@2.2.1: 668 | resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} 669 | engines: {node: '>=6'} 670 | 671 | expect-type@1.1.0: 672 | resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} 673 | engines: {node: '>=12.0.0'} 674 | 675 | fsevents@2.3.3: 676 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 677 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 678 | os: [darwin] 679 | 680 | function-bind@1.1.2: 681 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} 682 | 683 | get-source@2.0.12: 684 | resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} 685 | 686 | glob-to-regexp@0.4.1: 687 | resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} 688 | 689 | hasown@2.0.2: 690 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} 691 | engines: {node: '>= 0.4'} 692 | 693 | is-core-module@2.16.1: 694 | resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} 695 | engines: {node: '>= 0.4'} 696 | 697 | itty-time@1.0.6: 698 | resolution: {integrity: sha512-+P8IZaLLBtFv8hCkIjcymZOp4UJ+xW6bSlQsXGqrkmJh7vSiMFSlNne0mCYagEE0N7HDNR5jJBRxwN0oYv61Rw==} 699 | 700 | loupe@3.1.2: 701 | resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} 702 | 703 | magic-string@0.25.9: 704 | resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} 705 | 706 | magic-string@0.30.17: 707 | resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} 708 | 709 | mime@3.0.0: 710 | resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} 711 | engines: {node: '>=10.0.0'} 712 | hasBin: true 713 | 714 | miniflare@3.20241230.0: 715 | resolution: {integrity: sha512-ZtWNoNAIj5Q0Vb3B4SPEKr7DDmVG8a0Stsp/AuRkYXoJniA5hsbKjFNIGhTXGMIHVP5bvDrKJWt/POIDGfpiKg==} 716 | engines: {node: '>=16.13'} 717 | hasBin: true 718 | 719 | mlly@1.7.4: 720 | resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} 721 | 722 | ms@2.1.3: 723 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 724 | 725 | mustache@4.2.0: 726 | resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} 727 | hasBin: true 728 | 729 | nanoid@3.3.8: 730 | resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} 731 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 732 | hasBin: true 733 | 734 | node-forge@1.3.1: 735 | resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} 736 | engines: {node: '>= 6.13.0'} 737 | 738 | ohash@1.1.4: 739 | resolution: {integrity: sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==} 740 | 741 | path-parse@1.0.7: 742 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 743 | 744 | path-to-regexp@6.3.0: 745 | resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} 746 | 747 | pathe@1.1.2: 748 | resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} 749 | 750 | pathe@2.0.2: 751 | resolution: {integrity: sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==} 752 | 753 | pathval@2.0.0: 754 | resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} 755 | engines: {node: '>= 14.16'} 756 | 757 | picocolors@1.1.1: 758 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 759 | 760 | pkg-types@1.3.1: 761 | resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} 762 | 763 | postcss@8.5.1: 764 | resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==} 765 | engines: {node: ^10 || ^12 || >=14} 766 | 767 | printable-characters@1.0.42: 768 | resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} 769 | 770 | react-router@7.1.3: 771 | resolution: {integrity: sha512-EezYymLY6Guk/zLQ2vRA8WvdUhWFEj5fcE3RfWihhxXBW7+cd1LsIiA3lmx+KCmneAGQuyBv820o44L2+TtkSA==} 772 | engines: {node: '>=20.0.0'} 773 | peerDependencies: 774 | react: '>=18' 775 | react-dom: '>=18' 776 | peerDependenciesMeta: 777 | react-dom: 778 | optional: true 779 | 780 | react@19.0.0: 781 | resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} 782 | engines: {node: '>=0.10.0'} 783 | 784 | readdirp@4.1.1: 785 | resolution: {integrity: sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==} 786 | engines: {node: '>= 14.18.0'} 787 | 788 | resolve@1.22.10: 789 | resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} 790 | engines: {node: '>= 0.4'} 791 | hasBin: true 792 | 793 | rollup-plugin-inject@3.0.2: 794 | resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} 795 | deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. 796 | 797 | rollup-plugin-node-polyfills@0.2.1: 798 | resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} 799 | 800 | rollup-pluginutils@2.8.2: 801 | resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} 802 | 803 | rollup@4.32.0: 804 | resolution: {integrity: sha512-JmrhfQR31Q4AuNBjjAX4s+a/Pu/Q8Q9iwjWBsjRH1q52SPFE2NqRMK6fUZKKnvKO6id+h7JIRf0oYsph53eATg==} 805 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 806 | hasBin: true 807 | 808 | selfsigned@2.4.1: 809 | resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} 810 | engines: {node: '>=10'} 811 | 812 | semver@7.6.3: 813 | resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} 814 | engines: {node: '>=10'} 815 | hasBin: true 816 | 817 | set-cookie-parser@2.7.1: 818 | resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} 819 | 820 | siginfo@2.0.0: 821 | resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} 822 | 823 | source-map-js@1.2.1: 824 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 825 | engines: {node: '>=0.10.0'} 826 | 827 | source-map@0.6.1: 828 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 829 | engines: {node: '>=0.10.0'} 830 | 831 | sourcemap-codec@1.4.8: 832 | resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} 833 | deprecated: Please use @jridgewell/sourcemap-codec instead 834 | 835 | stackback@0.0.2: 836 | resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} 837 | 838 | stacktracey@2.1.8: 839 | resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} 840 | 841 | std-env@3.8.0: 842 | resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} 843 | 844 | stoppable@1.1.0: 845 | resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} 846 | engines: {node: '>=4', npm: '>=6'} 847 | 848 | supports-preserve-symlinks-flag@1.0.0: 849 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 850 | engines: {node: '>= 0.4'} 851 | 852 | tinybench@2.9.0: 853 | resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} 854 | 855 | tinyexec@0.3.2: 856 | resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} 857 | 858 | tinypool@1.0.2: 859 | resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} 860 | engines: {node: ^18.0.0 || >=20.0.0} 861 | 862 | tinyrainbow@1.2.0: 863 | resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} 864 | engines: {node: '>=14.0.0'} 865 | 866 | tinyspy@3.0.2: 867 | resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} 868 | engines: {node: '>=14.0.0'} 869 | 870 | tslib@2.8.1: 871 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 872 | 873 | turbo-stream@2.4.0: 874 | resolution: {integrity: sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==} 875 | 876 | typescript@5.7.3: 877 | resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} 878 | engines: {node: '>=14.17'} 879 | hasBin: true 880 | 881 | ufo@1.5.4: 882 | resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} 883 | 884 | undici-types@6.20.0: 885 | resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} 886 | 887 | undici@5.28.5: 888 | resolution: {integrity: sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==} 889 | engines: {node: '>=14.0'} 890 | 891 | unenv-nightly@2.0.0-20241218-183400-5d6aec3: 892 | resolution: {integrity: sha512-7Xpi29CJRbOV1/IrC03DawMJ0hloklDLq/cigSe+J2jkcC+iDres2Cy0r4ltj5f0x7DqsaGaB4/dLuCPPFZnZA==} 893 | 894 | vite-node@2.1.8: 895 | resolution: {integrity: sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==} 896 | engines: {node: ^18.0.0 || >=20.0.0} 897 | hasBin: true 898 | 899 | vite@5.4.14: 900 | resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==} 901 | engines: {node: ^18.0.0 || >=20.0.0} 902 | hasBin: true 903 | peerDependencies: 904 | '@types/node': ^18.0.0 || >=20.0.0 905 | less: '*' 906 | lightningcss: ^1.21.0 907 | sass: '*' 908 | sass-embedded: '*' 909 | stylus: '*' 910 | sugarss: '*' 911 | terser: ^5.4.0 912 | peerDependenciesMeta: 913 | '@types/node': 914 | optional: true 915 | less: 916 | optional: true 917 | lightningcss: 918 | optional: true 919 | sass: 920 | optional: true 921 | sass-embedded: 922 | optional: true 923 | stylus: 924 | optional: true 925 | sugarss: 926 | optional: true 927 | terser: 928 | optional: true 929 | 930 | vitest@2.1.8: 931 | resolution: {integrity: sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==} 932 | engines: {node: ^18.0.0 || >=20.0.0} 933 | hasBin: true 934 | peerDependencies: 935 | '@edge-runtime/vm': '*' 936 | '@types/node': ^18.0.0 || >=20.0.0 937 | '@vitest/browser': 2.1.8 938 | '@vitest/ui': 2.1.8 939 | happy-dom: '*' 940 | jsdom: '*' 941 | peerDependenciesMeta: 942 | '@edge-runtime/vm': 943 | optional: true 944 | '@types/node': 945 | optional: true 946 | '@vitest/browser': 947 | optional: true 948 | '@vitest/ui': 949 | optional: true 950 | happy-dom: 951 | optional: true 952 | jsdom: 953 | optional: true 954 | 955 | why-is-node-running@2.3.0: 956 | resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} 957 | engines: {node: '>=8'} 958 | hasBin: true 959 | 960 | workerd@1.20241230.0: 961 | resolution: {integrity: sha512-EgixXP0JGXGq6J9lz17TKIZtfNDUvJNG+cl9paPMfZuYWT920fFpBx+K04YmnbQRLnglsivF1GT9pxh1yrlWhg==} 962 | engines: {node: '>=16'} 963 | hasBin: true 964 | 965 | wrangler@3.100.0: 966 | resolution: {integrity: sha512-+nsZK374Xnp2BEQQuB/18pnObgsOey0AHVlg75pAdwNaKAmB2aa0/E5rFb7i89DiiwFYoZMz3cARY1UKcm/WQQ==} 967 | engines: {node: '>=16.17.0'} 968 | deprecated: Downgrade to 3.99.0 969 | hasBin: true 970 | peerDependencies: 971 | '@cloudflare/workers-types': ^4.20241230.0 972 | peerDependenciesMeta: 973 | '@cloudflare/workers-types': 974 | optional: true 975 | 976 | ws@8.18.0: 977 | resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} 978 | engines: {node: '>=10.0.0'} 979 | peerDependencies: 980 | bufferutil: ^4.0.1 981 | utf-8-validate: '>=5.0.2' 982 | peerDependenciesMeta: 983 | bufferutil: 984 | optional: true 985 | utf-8-validate: 986 | optional: true 987 | 988 | xxhash-wasm@1.1.0: 989 | resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} 990 | 991 | youch@3.3.4: 992 | resolution: {integrity: sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==} 993 | 994 | zod@3.24.1: 995 | resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==} 996 | 997 | snapshots: 998 | 999 | '@biomejs/biome@1.9.4': 1000 | optionalDependencies: 1001 | '@biomejs/cli-darwin-arm64': 1.9.4 1002 | '@biomejs/cli-darwin-x64': 1.9.4 1003 | '@biomejs/cli-linux-arm64': 1.9.4 1004 | '@biomejs/cli-linux-arm64-musl': 1.9.4 1005 | '@biomejs/cli-linux-x64': 1.9.4 1006 | '@biomejs/cli-linux-x64-musl': 1.9.4 1007 | '@biomejs/cli-win32-arm64': 1.9.4 1008 | '@biomejs/cli-win32-x64': 1.9.4 1009 | 1010 | '@biomejs/cli-darwin-arm64@1.9.4': 1011 | optional: true 1012 | 1013 | '@biomejs/cli-darwin-x64@1.9.4': 1014 | optional: true 1015 | 1016 | '@biomejs/cli-linux-arm64-musl@1.9.4': 1017 | optional: true 1018 | 1019 | '@biomejs/cli-linux-arm64@1.9.4': 1020 | optional: true 1021 | 1022 | '@biomejs/cli-linux-x64-musl@1.9.4': 1023 | optional: true 1024 | 1025 | '@biomejs/cli-linux-x64@1.9.4': 1026 | optional: true 1027 | 1028 | '@biomejs/cli-win32-arm64@1.9.4': 1029 | optional: true 1030 | 1031 | '@biomejs/cli-win32-x64@1.9.4': 1032 | optional: true 1033 | 1034 | '@cloudflare/kv-asset-handler@0.3.4': 1035 | dependencies: 1036 | mime: 3.0.0 1037 | 1038 | '@cloudflare/vitest-pool-workers@0.5.41(@cloudflare/workers-types@1.20250124.0)(@vitest/runner@2.1.8)(@vitest/snapshot@2.1.8)(vitest@2.1.8(@types/node@22.10.10))': 1039 | dependencies: 1040 | '@vitest/runner': 2.1.8 1041 | '@vitest/snapshot': 2.1.8 1042 | birpc: 0.2.14 1043 | cjs-module-lexer: 1.4.1 1044 | devalue: 4.3.3 1045 | esbuild: 0.17.19 1046 | miniflare: 3.20241230.0 1047 | semver: 7.6.3 1048 | vitest: 2.1.8(@types/node@22.10.10) 1049 | wrangler: 3.100.0(@cloudflare/workers-types@1.20250124.0) 1050 | zod: 3.24.1 1051 | transitivePeerDependencies: 1052 | - '@cloudflare/workers-types' 1053 | - bufferutil 1054 | - supports-color 1055 | - utf-8-validate 1056 | 1057 | '@cloudflare/workerd-darwin-64@1.20241230.0': 1058 | optional: true 1059 | 1060 | '@cloudflare/workerd-darwin-arm64@1.20241230.0': 1061 | optional: true 1062 | 1063 | '@cloudflare/workerd-linux-64@1.20241230.0': 1064 | optional: true 1065 | 1066 | '@cloudflare/workerd-linux-arm64@1.20241230.0': 1067 | optional: true 1068 | 1069 | '@cloudflare/workerd-windows-64@1.20241230.0': 1070 | optional: true 1071 | 1072 | '@cloudflare/workers-types@1.20250124.0': {} 1073 | 1074 | '@cspotcode/source-map-support@0.8.1': 1075 | dependencies: 1076 | '@jridgewell/trace-mapping': 0.3.9 1077 | 1078 | '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': 1079 | dependencies: 1080 | esbuild: 0.17.19 1081 | 1082 | '@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19)': 1083 | dependencies: 1084 | esbuild: 0.17.19 1085 | escape-string-regexp: 4.0.0 1086 | rollup-plugin-node-polyfills: 0.2.1 1087 | 1088 | '@esbuild/aix-ppc64@0.21.5': 1089 | optional: true 1090 | 1091 | '@esbuild/android-arm64@0.17.19': 1092 | optional: true 1093 | 1094 | '@esbuild/android-arm64@0.21.5': 1095 | optional: true 1096 | 1097 | '@esbuild/android-arm@0.17.19': 1098 | optional: true 1099 | 1100 | '@esbuild/android-arm@0.21.5': 1101 | optional: true 1102 | 1103 | '@esbuild/android-x64@0.17.19': 1104 | optional: true 1105 | 1106 | '@esbuild/android-x64@0.21.5': 1107 | optional: true 1108 | 1109 | '@esbuild/darwin-arm64@0.17.19': 1110 | optional: true 1111 | 1112 | '@esbuild/darwin-arm64@0.21.5': 1113 | optional: true 1114 | 1115 | '@esbuild/darwin-x64@0.17.19': 1116 | optional: true 1117 | 1118 | '@esbuild/darwin-x64@0.21.5': 1119 | optional: true 1120 | 1121 | '@esbuild/freebsd-arm64@0.17.19': 1122 | optional: true 1123 | 1124 | '@esbuild/freebsd-arm64@0.21.5': 1125 | optional: true 1126 | 1127 | '@esbuild/freebsd-x64@0.17.19': 1128 | optional: true 1129 | 1130 | '@esbuild/freebsd-x64@0.21.5': 1131 | optional: true 1132 | 1133 | '@esbuild/linux-arm64@0.17.19': 1134 | optional: true 1135 | 1136 | '@esbuild/linux-arm64@0.21.5': 1137 | optional: true 1138 | 1139 | '@esbuild/linux-arm@0.17.19': 1140 | optional: true 1141 | 1142 | '@esbuild/linux-arm@0.21.5': 1143 | optional: true 1144 | 1145 | '@esbuild/linux-ia32@0.17.19': 1146 | optional: true 1147 | 1148 | '@esbuild/linux-ia32@0.21.5': 1149 | optional: true 1150 | 1151 | '@esbuild/linux-loong64@0.17.19': 1152 | optional: true 1153 | 1154 | '@esbuild/linux-loong64@0.21.5': 1155 | optional: true 1156 | 1157 | '@esbuild/linux-mips64el@0.17.19': 1158 | optional: true 1159 | 1160 | '@esbuild/linux-mips64el@0.21.5': 1161 | optional: true 1162 | 1163 | '@esbuild/linux-ppc64@0.17.19': 1164 | optional: true 1165 | 1166 | '@esbuild/linux-ppc64@0.21.5': 1167 | optional: true 1168 | 1169 | '@esbuild/linux-riscv64@0.17.19': 1170 | optional: true 1171 | 1172 | '@esbuild/linux-riscv64@0.21.5': 1173 | optional: true 1174 | 1175 | '@esbuild/linux-s390x@0.17.19': 1176 | optional: true 1177 | 1178 | '@esbuild/linux-s390x@0.21.5': 1179 | optional: true 1180 | 1181 | '@esbuild/linux-x64@0.17.19': 1182 | optional: true 1183 | 1184 | '@esbuild/linux-x64@0.21.5': 1185 | optional: true 1186 | 1187 | '@esbuild/netbsd-x64@0.17.19': 1188 | optional: true 1189 | 1190 | '@esbuild/netbsd-x64@0.21.5': 1191 | optional: true 1192 | 1193 | '@esbuild/openbsd-x64@0.17.19': 1194 | optional: true 1195 | 1196 | '@esbuild/openbsd-x64@0.21.5': 1197 | optional: true 1198 | 1199 | '@esbuild/sunos-x64@0.17.19': 1200 | optional: true 1201 | 1202 | '@esbuild/sunos-x64@0.21.5': 1203 | optional: true 1204 | 1205 | '@esbuild/win32-arm64@0.17.19': 1206 | optional: true 1207 | 1208 | '@esbuild/win32-arm64@0.21.5': 1209 | optional: true 1210 | 1211 | '@esbuild/win32-ia32@0.17.19': 1212 | optional: true 1213 | 1214 | '@esbuild/win32-ia32@0.21.5': 1215 | optional: true 1216 | 1217 | '@esbuild/win32-x64@0.17.19': 1218 | optional: true 1219 | 1220 | '@esbuild/win32-x64@0.21.5': 1221 | optional: true 1222 | 1223 | '@fastify/busboy@2.1.1': {} 1224 | 1225 | '@jridgewell/resolve-uri@3.1.2': {} 1226 | 1227 | '@jridgewell/sourcemap-codec@1.5.0': {} 1228 | 1229 | '@jridgewell/trace-mapping@0.3.9': 1230 | dependencies: 1231 | '@jridgewell/resolve-uri': 3.1.2 1232 | '@jridgewell/sourcemap-codec': 1.5.0 1233 | 1234 | '@rollup/rollup-android-arm-eabi@4.32.0': 1235 | optional: true 1236 | 1237 | '@rollup/rollup-android-arm64@4.32.0': 1238 | optional: true 1239 | 1240 | '@rollup/rollup-darwin-arm64@4.32.0': 1241 | optional: true 1242 | 1243 | '@rollup/rollup-darwin-x64@4.32.0': 1244 | optional: true 1245 | 1246 | '@rollup/rollup-freebsd-arm64@4.32.0': 1247 | optional: true 1248 | 1249 | '@rollup/rollup-freebsd-x64@4.32.0': 1250 | optional: true 1251 | 1252 | '@rollup/rollup-linux-arm-gnueabihf@4.32.0': 1253 | optional: true 1254 | 1255 | '@rollup/rollup-linux-arm-musleabihf@4.32.0': 1256 | optional: true 1257 | 1258 | '@rollup/rollup-linux-arm64-gnu@4.32.0': 1259 | optional: true 1260 | 1261 | '@rollup/rollup-linux-arm64-musl@4.32.0': 1262 | optional: true 1263 | 1264 | '@rollup/rollup-linux-loongarch64-gnu@4.32.0': 1265 | optional: true 1266 | 1267 | '@rollup/rollup-linux-powerpc64le-gnu@4.32.0': 1268 | optional: true 1269 | 1270 | '@rollup/rollup-linux-riscv64-gnu@4.32.0': 1271 | optional: true 1272 | 1273 | '@rollup/rollup-linux-s390x-gnu@4.32.0': 1274 | optional: true 1275 | 1276 | '@rollup/rollup-linux-x64-gnu@4.32.0': 1277 | optional: true 1278 | 1279 | '@rollup/rollup-linux-x64-musl@4.32.0': 1280 | optional: true 1281 | 1282 | '@rollup/rollup-win32-arm64-msvc@4.32.0': 1283 | optional: true 1284 | 1285 | '@rollup/rollup-win32-ia32-msvc@4.32.0': 1286 | optional: true 1287 | 1288 | '@rollup/rollup-win32-x64-msvc@4.32.0': 1289 | optional: true 1290 | 1291 | '@types/cookie@0.6.0': {} 1292 | 1293 | '@types/estree@1.0.6': {} 1294 | 1295 | '@types/node-forge@1.3.11': 1296 | dependencies: 1297 | '@types/node': 22.10.10 1298 | 1299 | '@types/node@22.10.10': 1300 | dependencies: 1301 | undici-types: 6.20.0 1302 | 1303 | '@vitest/expect@2.1.8': 1304 | dependencies: 1305 | '@vitest/spy': 2.1.8 1306 | '@vitest/utils': 2.1.8 1307 | chai: 5.1.2 1308 | tinyrainbow: 1.2.0 1309 | 1310 | '@vitest/mocker@2.1.8(vite@5.4.14(@types/node@22.10.10))': 1311 | dependencies: 1312 | '@vitest/spy': 2.1.8 1313 | estree-walker: 3.0.3 1314 | magic-string: 0.30.17 1315 | optionalDependencies: 1316 | vite: 5.4.14(@types/node@22.10.10) 1317 | 1318 | '@vitest/pretty-format@2.1.8': 1319 | dependencies: 1320 | tinyrainbow: 1.2.0 1321 | 1322 | '@vitest/runner@2.1.8': 1323 | dependencies: 1324 | '@vitest/utils': 2.1.8 1325 | pathe: 1.1.2 1326 | 1327 | '@vitest/snapshot@2.1.8': 1328 | dependencies: 1329 | '@vitest/pretty-format': 2.1.8 1330 | magic-string: 0.30.17 1331 | pathe: 1.1.2 1332 | 1333 | '@vitest/spy@2.1.8': 1334 | dependencies: 1335 | tinyspy: 3.0.2 1336 | 1337 | '@vitest/utils@2.1.8': 1338 | dependencies: 1339 | '@vitest/pretty-format': 2.1.8 1340 | loupe: 3.1.2 1341 | tinyrainbow: 1.2.0 1342 | 1343 | acorn-walk@8.3.4: 1344 | dependencies: 1345 | acorn: 8.14.0 1346 | 1347 | acorn@8.14.0: {} 1348 | 1349 | as-table@1.0.55: 1350 | dependencies: 1351 | printable-characters: 1.0.42 1352 | 1353 | assertion-error@2.0.1: {} 1354 | 1355 | birpc@0.2.14: {} 1356 | 1357 | blake3-wasm@2.1.5: {} 1358 | 1359 | cac@6.7.14: {} 1360 | 1361 | capnp-ts@0.7.0: 1362 | dependencies: 1363 | debug: 4.4.0 1364 | tslib: 2.8.1 1365 | transitivePeerDependencies: 1366 | - supports-color 1367 | 1368 | chai@5.1.2: 1369 | dependencies: 1370 | assertion-error: 2.0.1 1371 | check-error: 2.1.1 1372 | deep-eql: 5.0.2 1373 | loupe: 3.1.2 1374 | pathval: 2.0.0 1375 | 1376 | check-error@2.1.1: {} 1377 | 1378 | chokidar@4.0.3: 1379 | dependencies: 1380 | readdirp: 4.1.1 1381 | 1382 | cjs-module-lexer@1.4.1: {} 1383 | 1384 | confbox@0.1.8: {} 1385 | 1386 | cookie@0.7.2: {} 1387 | 1388 | cookie@1.0.2: {} 1389 | 1390 | data-uri-to-buffer@2.0.2: {} 1391 | 1392 | date-fns@4.1.0: {} 1393 | 1394 | debug@4.4.0: 1395 | dependencies: 1396 | ms: 2.1.3 1397 | 1398 | deep-eql@5.0.2: {} 1399 | 1400 | defu@6.1.4: {} 1401 | 1402 | devalue@4.3.3: {} 1403 | 1404 | es-module-lexer@1.6.0: {} 1405 | 1406 | esbuild@0.17.19: 1407 | optionalDependencies: 1408 | '@esbuild/android-arm': 0.17.19 1409 | '@esbuild/android-arm64': 0.17.19 1410 | '@esbuild/android-x64': 0.17.19 1411 | '@esbuild/darwin-arm64': 0.17.19 1412 | '@esbuild/darwin-x64': 0.17.19 1413 | '@esbuild/freebsd-arm64': 0.17.19 1414 | '@esbuild/freebsd-x64': 0.17.19 1415 | '@esbuild/linux-arm': 0.17.19 1416 | '@esbuild/linux-arm64': 0.17.19 1417 | '@esbuild/linux-ia32': 0.17.19 1418 | '@esbuild/linux-loong64': 0.17.19 1419 | '@esbuild/linux-mips64el': 0.17.19 1420 | '@esbuild/linux-ppc64': 0.17.19 1421 | '@esbuild/linux-riscv64': 0.17.19 1422 | '@esbuild/linux-s390x': 0.17.19 1423 | '@esbuild/linux-x64': 0.17.19 1424 | '@esbuild/netbsd-x64': 0.17.19 1425 | '@esbuild/openbsd-x64': 0.17.19 1426 | '@esbuild/sunos-x64': 0.17.19 1427 | '@esbuild/win32-arm64': 0.17.19 1428 | '@esbuild/win32-ia32': 0.17.19 1429 | '@esbuild/win32-x64': 0.17.19 1430 | 1431 | esbuild@0.21.5: 1432 | optionalDependencies: 1433 | '@esbuild/aix-ppc64': 0.21.5 1434 | '@esbuild/android-arm': 0.21.5 1435 | '@esbuild/android-arm64': 0.21.5 1436 | '@esbuild/android-x64': 0.21.5 1437 | '@esbuild/darwin-arm64': 0.21.5 1438 | '@esbuild/darwin-x64': 0.21.5 1439 | '@esbuild/freebsd-arm64': 0.21.5 1440 | '@esbuild/freebsd-x64': 0.21.5 1441 | '@esbuild/linux-arm': 0.21.5 1442 | '@esbuild/linux-arm64': 0.21.5 1443 | '@esbuild/linux-ia32': 0.21.5 1444 | '@esbuild/linux-loong64': 0.21.5 1445 | '@esbuild/linux-mips64el': 0.21.5 1446 | '@esbuild/linux-ppc64': 0.21.5 1447 | '@esbuild/linux-riscv64': 0.21.5 1448 | '@esbuild/linux-s390x': 0.21.5 1449 | '@esbuild/linux-x64': 0.21.5 1450 | '@esbuild/netbsd-x64': 0.21.5 1451 | '@esbuild/openbsd-x64': 0.21.5 1452 | '@esbuild/sunos-x64': 0.21.5 1453 | '@esbuild/win32-arm64': 0.21.5 1454 | '@esbuild/win32-ia32': 0.21.5 1455 | '@esbuild/win32-x64': 0.21.5 1456 | 1457 | escape-string-regexp@4.0.0: {} 1458 | 1459 | estree-walker@0.6.1: {} 1460 | 1461 | estree-walker@3.0.3: 1462 | dependencies: 1463 | '@types/estree': 1.0.6 1464 | 1465 | exit-hook@2.2.1: {} 1466 | 1467 | expect-type@1.1.0: {} 1468 | 1469 | fsevents@2.3.3: 1470 | optional: true 1471 | 1472 | function-bind@1.1.2: {} 1473 | 1474 | get-source@2.0.12: 1475 | dependencies: 1476 | data-uri-to-buffer: 2.0.2 1477 | source-map: 0.6.1 1478 | 1479 | glob-to-regexp@0.4.1: {} 1480 | 1481 | hasown@2.0.2: 1482 | dependencies: 1483 | function-bind: 1.1.2 1484 | 1485 | is-core-module@2.16.1: 1486 | dependencies: 1487 | hasown: 2.0.2 1488 | 1489 | itty-time@1.0.6: {} 1490 | 1491 | loupe@3.1.2: {} 1492 | 1493 | magic-string@0.25.9: 1494 | dependencies: 1495 | sourcemap-codec: 1.4.8 1496 | 1497 | magic-string@0.30.17: 1498 | dependencies: 1499 | '@jridgewell/sourcemap-codec': 1.5.0 1500 | 1501 | mime@3.0.0: {} 1502 | 1503 | miniflare@3.20241230.0: 1504 | dependencies: 1505 | '@cspotcode/source-map-support': 0.8.1 1506 | acorn: 8.14.0 1507 | acorn-walk: 8.3.4 1508 | capnp-ts: 0.7.0 1509 | exit-hook: 2.2.1 1510 | glob-to-regexp: 0.4.1 1511 | stoppable: 1.1.0 1512 | undici: 5.28.5 1513 | workerd: 1.20241230.0 1514 | ws: 8.18.0 1515 | youch: 3.3.4 1516 | zod: 3.24.1 1517 | transitivePeerDependencies: 1518 | - bufferutil 1519 | - supports-color 1520 | - utf-8-validate 1521 | 1522 | mlly@1.7.4: 1523 | dependencies: 1524 | acorn: 8.14.0 1525 | pathe: 2.0.2 1526 | pkg-types: 1.3.1 1527 | ufo: 1.5.4 1528 | 1529 | ms@2.1.3: {} 1530 | 1531 | mustache@4.2.0: {} 1532 | 1533 | nanoid@3.3.8: {} 1534 | 1535 | node-forge@1.3.1: {} 1536 | 1537 | ohash@1.1.4: {} 1538 | 1539 | path-parse@1.0.7: {} 1540 | 1541 | path-to-regexp@6.3.0: {} 1542 | 1543 | pathe@1.1.2: {} 1544 | 1545 | pathe@2.0.2: {} 1546 | 1547 | pathval@2.0.0: {} 1548 | 1549 | picocolors@1.1.1: {} 1550 | 1551 | pkg-types@1.3.1: 1552 | dependencies: 1553 | confbox: 0.1.8 1554 | mlly: 1.7.4 1555 | pathe: 2.0.2 1556 | 1557 | postcss@8.5.1: 1558 | dependencies: 1559 | nanoid: 3.3.8 1560 | picocolors: 1.1.1 1561 | source-map-js: 1.2.1 1562 | 1563 | printable-characters@1.0.42: {} 1564 | 1565 | react-router@7.1.3(react@19.0.0): 1566 | dependencies: 1567 | '@types/cookie': 0.6.0 1568 | cookie: 1.0.2 1569 | react: 19.0.0 1570 | set-cookie-parser: 2.7.1 1571 | turbo-stream: 2.4.0 1572 | 1573 | react@19.0.0: {} 1574 | 1575 | readdirp@4.1.1: {} 1576 | 1577 | resolve@1.22.10: 1578 | dependencies: 1579 | is-core-module: 2.16.1 1580 | path-parse: 1.0.7 1581 | supports-preserve-symlinks-flag: 1.0.0 1582 | 1583 | rollup-plugin-inject@3.0.2: 1584 | dependencies: 1585 | estree-walker: 0.6.1 1586 | magic-string: 0.25.9 1587 | rollup-pluginutils: 2.8.2 1588 | 1589 | rollup-plugin-node-polyfills@0.2.1: 1590 | dependencies: 1591 | rollup-plugin-inject: 3.0.2 1592 | 1593 | rollup-pluginutils@2.8.2: 1594 | dependencies: 1595 | estree-walker: 0.6.1 1596 | 1597 | rollup@4.32.0: 1598 | dependencies: 1599 | '@types/estree': 1.0.6 1600 | optionalDependencies: 1601 | '@rollup/rollup-android-arm-eabi': 4.32.0 1602 | '@rollup/rollup-android-arm64': 4.32.0 1603 | '@rollup/rollup-darwin-arm64': 4.32.0 1604 | '@rollup/rollup-darwin-x64': 4.32.0 1605 | '@rollup/rollup-freebsd-arm64': 4.32.0 1606 | '@rollup/rollup-freebsd-x64': 4.32.0 1607 | '@rollup/rollup-linux-arm-gnueabihf': 4.32.0 1608 | '@rollup/rollup-linux-arm-musleabihf': 4.32.0 1609 | '@rollup/rollup-linux-arm64-gnu': 4.32.0 1610 | '@rollup/rollup-linux-arm64-musl': 4.32.0 1611 | '@rollup/rollup-linux-loongarch64-gnu': 4.32.0 1612 | '@rollup/rollup-linux-powerpc64le-gnu': 4.32.0 1613 | '@rollup/rollup-linux-riscv64-gnu': 4.32.0 1614 | '@rollup/rollup-linux-s390x-gnu': 4.32.0 1615 | '@rollup/rollup-linux-x64-gnu': 4.32.0 1616 | '@rollup/rollup-linux-x64-musl': 4.32.0 1617 | '@rollup/rollup-win32-arm64-msvc': 4.32.0 1618 | '@rollup/rollup-win32-ia32-msvc': 4.32.0 1619 | '@rollup/rollup-win32-x64-msvc': 4.32.0 1620 | fsevents: 2.3.3 1621 | 1622 | selfsigned@2.4.1: 1623 | dependencies: 1624 | '@types/node-forge': 1.3.11 1625 | node-forge: 1.3.1 1626 | 1627 | semver@7.6.3: {} 1628 | 1629 | set-cookie-parser@2.7.1: {} 1630 | 1631 | siginfo@2.0.0: {} 1632 | 1633 | source-map-js@1.2.1: {} 1634 | 1635 | source-map@0.6.1: {} 1636 | 1637 | sourcemap-codec@1.4.8: {} 1638 | 1639 | stackback@0.0.2: {} 1640 | 1641 | stacktracey@2.1.8: 1642 | dependencies: 1643 | as-table: 1.0.55 1644 | get-source: 2.0.12 1645 | 1646 | std-env@3.8.0: {} 1647 | 1648 | stoppable@1.1.0: {} 1649 | 1650 | supports-preserve-symlinks-flag@1.0.0: {} 1651 | 1652 | tinybench@2.9.0: {} 1653 | 1654 | tinyexec@0.3.2: {} 1655 | 1656 | tinypool@1.0.2: {} 1657 | 1658 | tinyrainbow@1.2.0: {} 1659 | 1660 | tinyspy@3.0.2: {} 1661 | 1662 | tslib@2.8.1: {} 1663 | 1664 | turbo-stream@2.4.0: {} 1665 | 1666 | typescript@5.7.3: {} 1667 | 1668 | ufo@1.5.4: {} 1669 | 1670 | undici-types@6.20.0: {} 1671 | 1672 | undici@5.28.5: 1673 | dependencies: 1674 | '@fastify/busboy': 2.1.1 1675 | 1676 | unenv-nightly@2.0.0-20241218-183400-5d6aec3: 1677 | dependencies: 1678 | defu: 6.1.4 1679 | mlly: 1.7.4 1680 | ohash: 1.1.4 1681 | pathe: 1.1.2 1682 | ufo: 1.5.4 1683 | 1684 | vite-node@2.1.8(@types/node@22.10.10): 1685 | dependencies: 1686 | cac: 6.7.14 1687 | debug: 4.4.0 1688 | es-module-lexer: 1.6.0 1689 | pathe: 1.1.2 1690 | vite: 5.4.14(@types/node@22.10.10) 1691 | transitivePeerDependencies: 1692 | - '@types/node' 1693 | - less 1694 | - lightningcss 1695 | - sass 1696 | - sass-embedded 1697 | - stylus 1698 | - sugarss 1699 | - supports-color 1700 | - terser 1701 | 1702 | vite@5.4.14(@types/node@22.10.10): 1703 | dependencies: 1704 | esbuild: 0.21.5 1705 | postcss: 8.5.1 1706 | rollup: 4.32.0 1707 | optionalDependencies: 1708 | '@types/node': 22.10.10 1709 | fsevents: 2.3.3 1710 | 1711 | vitest@2.1.8(@types/node@22.10.10): 1712 | dependencies: 1713 | '@vitest/expect': 2.1.8 1714 | '@vitest/mocker': 2.1.8(vite@5.4.14(@types/node@22.10.10)) 1715 | '@vitest/pretty-format': 2.1.8 1716 | '@vitest/runner': 2.1.8 1717 | '@vitest/snapshot': 2.1.8 1718 | '@vitest/spy': 2.1.8 1719 | '@vitest/utils': 2.1.8 1720 | chai: 5.1.2 1721 | debug: 4.4.0 1722 | expect-type: 1.1.0 1723 | magic-string: 0.30.17 1724 | pathe: 1.1.2 1725 | std-env: 3.8.0 1726 | tinybench: 2.9.0 1727 | tinyexec: 0.3.2 1728 | tinypool: 1.0.2 1729 | tinyrainbow: 1.2.0 1730 | vite: 5.4.14(@types/node@22.10.10) 1731 | vite-node: 2.1.8(@types/node@22.10.10) 1732 | why-is-node-running: 2.3.0 1733 | optionalDependencies: 1734 | '@types/node': 22.10.10 1735 | transitivePeerDependencies: 1736 | - less 1737 | - lightningcss 1738 | - msw 1739 | - sass 1740 | - sass-embedded 1741 | - stylus 1742 | - sugarss 1743 | - supports-color 1744 | - terser 1745 | 1746 | why-is-node-running@2.3.0: 1747 | dependencies: 1748 | siginfo: 2.0.0 1749 | stackback: 0.0.2 1750 | 1751 | workerd@1.20241230.0: 1752 | optionalDependencies: 1753 | '@cloudflare/workerd-darwin-64': 1.20241230.0 1754 | '@cloudflare/workerd-darwin-arm64': 1.20241230.0 1755 | '@cloudflare/workerd-linux-64': 1.20241230.0 1756 | '@cloudflare/workerd-linux-arm64': 1.20241230.0 1757 | '@cloudflare/workerd-windows-64': 1.20241230.0 1758 | 1759 | wrangler@3.100.0(@cloudflare/workers-types@1.20250124.0): 1760 | dependencies: 1761 | '@cloudflare/kv-asset-handler': 0.3.4 1762 | '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) 1763 | '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) 1764 | blake3-wasm: 2.1.5 1765 | chokidar: 4.0.3 1766 | date-fns: 4.1.0 1767 | esbuild: 0.17.19 1768 | itty-time: 1.0.6 1769 | miniflare: 3.20241230.0 1770 | nanoid: 3.3.8 1771 | path-to-regexp: 6.3.0 1772 | resolve: 1.22.10 1773 | selfsigned: 2.4.1 1774 | source-map: 0.6.1 1775 | unenv: unenv-nightly@2.0.0-20241218-183400-5d6aec3 1776 | workerd: 1.20241230.0 1777 | xxhash-wasm: 1.1.0 1778 | optionalDependencies: 1779 | '@cloudflare/workers-types': 1.20250124.0 1780 | fsevents: 2.3.3 1781 | transitivePeerDependencies: 1782 | - bufferutil 1783 | - supports-color 1784 | - utf-8-validate 1785 | 1786 | ws@8.18.0: {} 1787 | 1788 | xxhash-wasm@1.1.0: {} 1789 | 1790 | youch@3.3.4: 1791 | dependencies: 1792 | cookie: 0.7.2 1793 | mustache: 4.2.0 1794 | stacktracey: 2.1.8 1795 | 1796 | zod@3.24.1: {} 1797 | -------------------------------------------------------------------------------- /src/impl.ts: -------------------------------------------------------------------------------- 1 | import { RpcStub } from "cloudflare:workers"; 2 | import type { EnvGetter, NameGetter, StubGetter } from "./types.js"; 3 | 4 | export function constructWrapper< 5 | Args extends { context?: unknown; request: Request }, 6 | T extends (...args: any[]) => unknown, 7 | Env extends {} = {}, 8 | >( 9 | stubGetter: StubGetter, 10 | idGetter: NameGetter, 11 | envGetter: EnvGetter, 12 | ): (args: Args) => Promise>> { 13 | return async (args) => { 14 | const env = envGetter(args.context) as unknown as Env; 15 | if (!env) { 16 | throw new Error( 17 | "No env found in context, if your env is not in `context.cloudflare.env` ensure you've called `setEnvFromContextGetter`.", 18 | ); 19 | } 20 | 21 | const proxiedEnv = proxyFor(env); 22 | const { durableObject, method } = stubGetter(proxiedEnv) as unknown as { 23 | durableObject: keyof Env; 24 | method: string; 25 | }; 26 | 27 | const namespace = env[durableObject] as DurableObjectNamespace; 28 | const name = 29 | typeof idGetter === "function" 30 | ? await idGetter({ 31 | ...args, 32 | request: args.request?.clone(), 33 | }) 34 | : idGetter; 35 | const doID = namespace.idFromName(name); 36 | const stub = namespace.get(doID); 37 | 38 | const ret = await (stub as any)[method]({ 39 | ...args, 40 | context: undefined, 41 | }); 42 | 43 | if (ret instanceof Response) { 44 | return ret; 45 | } 46 | 47 | if (ret instanceof RpcStub) { 48 | throw new Error( 49 | "`RpcStub`s cannot be used as loader or action data, wrap your return data in the `data` function to avoid this error.", 50 | ); 51 | } 52 | 53 | // @ts-ignore 54 | return ret; 55 | }; 56 | } 57 | 58 | function proxyFor(env: object): any { 59 | return new Proxy( 60 | {}, 61 | { 62 | get(_, envProp: string) { 63 | if (!(envProp in env)) { 64 | throw new Error(`Property ${envProp} not found in env`); 65 | } 66 | 67 | return new Proxy( 68 | {}, 69 | { 70 | get(_, namespaceProp: string) { 71 | return { durableObject: envProp, method: namespaceProp }; 72 | }, 73 | }, 74 | ); 75 | }, 76 | }, 77 | ); 78 | } 79 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import type { DurableObject } from "cloudflare:workers"; 2 | import type { 3 | ActionFunctionArgs, 4 | AppLoadContext, 5 | LoaderFunctionArgs, 6 | } from "react-router"; 7 | import type { 8 | EnvGetter, 9 | NameGetter, 10 | RouteDurable, 11 | StubSelector, 12 | } from "./types.js"; 13 | import { constructWrapper } from "./impl.js"; 14 | 15 | let envGetter: EnvGetter = (context) => context?.cloudflare?.env; 16 | 17 | /** 18 | * Since react-router doesn't have an opinion on where to embed the Cloudflare `Env` 19 | * object in the context, this function allows you to set a custom getter to extract 20 | * the `Env` object from the context if you don't store it in `context.cloudflare.env`. 21 | */ 22 | export function setEnvFromContextGetter( 23 | fn: (context: Context) => unknown, 24 | ) { 25 | envGetter = fn; 26 | } 27 | 28 | /** 29 | * Creates a React Router loader from a Durable Object object method. 30 | * 31 | * @param loaderSelector Provides a loader method on a Durable Object from the Env object. 32 | * @param name The name (or name function) of the Durable Object to execute. 33 | * @returns A React Router loader. 34 | */ 35 | export function durableLoader< 36 | LoaderDurableObject extends DurableObject, 37 | LoaderFn extends (...args: any[]) => unknown, 38 | Env extends {}, 39 | >( 40 | _: new (ctx: DurableObjectState, env: Env) => LoaderDurableObject, 41 | loaderSelector: (env: StubSelector) => LoaderFn, 42 | name: NameGetter, 43 | ): ( 44 | args: LoaderFunctionArgs, 45 | ) => Promise>> { 46 | return constructWrapper(loaderSelector, name, envGetter); 47 | } 48 | 49 | /** 50 | * Creates a React Router action from a Durable Object object method. 51 | * 52 | * @param actionSelector Provides a action method on a Durable Object from the Env object. 53 | * @param name The name (or name function) of the Durable Object to execute 54 | * @returns A React Router action. 55 | */ 56 | export function durableAction< 57 | ActionDurableObject extends DurableObject, 58 | ActionFn extends (...args: any[]) => unknown, 59 | Env extends {}, 60 | >( 61 | _: new (ctx: DurableObjectState, env: Env) => ActionDurableObject, 62 | actionSelector: (env: StubSelector) => ActionFn, 63 | name: NameGetter, 64 | ): ( 65 | args: ActionFunctionArgs, 66 | ) => Promise>> { 67 | return constructWrapper(actionSelector, name, envGetter); 68 | } 69 | 70 | type RouteInfo = { params: Params }; 71 | 72 | type InferParams = T extends RouteInfo ? Params : never; 73 | 74 | /** 75 | * Provides the route's Info type for a way to create type-safe Durable Object 76 | * loaders and actions. 77 | */ 78 | export function route>(): RouteDurable< 79 | InferParams 80 | > { 81 | return { 82 | loader: durableLoader, 83 | action: durableAction, 84 | }; 85 | } 86 | 87 | /** 88 | * Clones the input object to remove `RpcStub` instances, this prevents 89 | * rendering issues when used in a route component since `RpcStub`s can't 90 | * be rendered. 91 | */ 92 | export function data(data: T): T { 93 | return JSON.parse(JSON.stringify(data)); 94 | } 95 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | ActionFunctionArgs, 3 | AppLoadContext, 4 | LoaderFunctionArgs, 5 | } from "react-router"; 6 | import type { DurableObject } from "cloudflare:workers"; 7 | 8 | type NonLoaders = keyof DurableObject; 9 | 10 | export type StubSelector = { 11 | [K in keyof Env]: Env[K] extends DurableObjectNamespace 12 | ? Omit 13 | : never; 14 | }; 15 | 16 | export type StubGetter = (env: StubSelector) => T; 17 | export type EnvGetter = (context: Context) => unknown; 18 | export type NameGetter = 19 | | string 20 | | ((args: Args) => string | Promise); 21 | 22 | type WithParams = Omit & { 23 | params: Params; 24 | }; 25 | 26 | export interface RouteDurable { 27 | /** 28 | * Creates a React Router loader from a Durable Object object method. 29 | * 30 | * @param loaderSelector Provides a loader method on a Durable Object from the Env object. 31 | * @param name The name (or name function) of the Durable Object to execute. 32 | * @returns A React Router loader. 33 | */ 34 | loader< 35 | LoaderDurableObject extends DurableObject, 36 | LoaderFn extends (...args: any[]) => unknown, 37 | Env extends {}, 38 | >( 39 | _: new (ctx: DurableObjectState, env: Env) => LoaderDurableObject, 40 | loaderSelector: (env: StubSelector) => LoaderFn, 41 | name: NameGetter>, 42 | ): ( 43 | args: LoaderFunctionArgs, 44 | ) => Promise>>; 45 | 46 | /** 47 | * Creates a React Router action from a Durable Object object method. 48 | * 49 | * @param actionSelector Provides a action method on a Durable Object from the Env object. 50 | * @param name The name (or name function) of the Durable Object to execute 51 | * @returns A React Router action. 52 | */ 53 | action< 54 | ActionDurableObject extends DurableObject, 55 | ActionFn extends (...args: any[]) => unknown, 56 | Env extends {}, 57 | >( 58 | _: new (ctx: DurableObjectState, env: Env) => ActionDurableObject, 59 | actionSelector: (env: StubSelector) => ActionFn, 60 | name: NameGetter>, 61 | ): ( 62 | args: ActionFunctionArgs, 63 | ) => Promise>>; 64 | } 65 | -------------------------------------------------------------------------------- /tests/global.d.ts: -------------------------------------------------------------------------------- 1 | declare module "cloudflare:test" { 2 | interface ProvidedEnv { 3 | test: DurableObjectNamespace; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it, vitest } from "vitest"; 2 | import { actionArgs, loaderArgs, unreachable } from "./util.js"; 3 | import { durableAction, durableLoader } from "../src/index.js"; 4 | import { TestDurableObject } from "./worker.js"; 5 | 6 | describe("calling loaders/actions", () => { 7 | it("should be able to call a loader with a static id", async () => { 8 | const loader = durableLoader( 9 | TestDurableObject, 10 | (env) => env.test.testLoader, 11 | "testLoader", 12 | ); 13 | 14 | const result = await loader(loaderArgs()); 15 | expect(result).toEqual({ called: "testLoader" }); 16 | }); 17 | 18 | it("should be able to call a loader with a dynamic id", async () => { 19 | const loader = durableLoader( 20 | TestDurableObject, 21 | (env) => env.test.testLoader, 22 | () => Math.random().toString(36), 23 | ); 24 | 25 | const result = await loader(loaderArgs()); 26 | expect(result).toEqual({ called: "testLoader" }); 27 | }); 28 | 29 | it("should be able to call a loader with a dynamic id", async () => { 30 | const loader = durableLoader( 31 | TestDurableObject, 32 | (env) => env.test.argsDataLoader, 33 | "name", 34 | ); 35 | 36 | const result = await loader( 37 | loaderArgs({ 38 | params: { foo: "bar" }, 39 | request: new Request("https://example.com", { 40 | method: "POST", 41 | headers: { 42 | "x-test": "true", 43 | }, 44 | body: "Hello, world!", 45 | }), 46 | }), 47 | ); 48 | 49 | expect(result).toEqual({ 50 | params: { 51 | foo: "bar", 52 | }, 53 | request: { 54 | url: "https://example.com", 55 | headers: { 56 | "content-type": "text/plain;charset=UTF-8", 57 | "x-test": "true", 58 | }, 59 | body: "Hello, world!", 60 | }, 61 | }); 62 | }); 63 | 64 | it("should be able to use form in both name getter and action", async () => { 65 | const request = new Request("https://example.com", { 66 | method: "POST", 67 | body: new URLSearchParams({ foo: "bar" }), 68 | }); 69 | 70 | const nameGetter = vitest.fn(async ({ request }) => { 71 | const form = await request.formData(); 72 | return form.get("foo")?.toString() ?? unreachable(); 73 | }); 74 | 75 | const action = durableAction( 76 | TestDurableObject, 77 | (env) => env.test.formAction, 78 | nameGetter, 79 | ); 80 | 81 | const result = await action(actionArgs({ request })); 82 | expect(result).toEqual({ foo: "bar" }); 83 | expect(nameGetter).toHaveResolvedWith("bar"); 84 | }); 85 | 86 | it("should be able to return a response from an action", async () => { 87 | const action = durableAction( 88 | TestDurableObject, 89 | (env) => env.test.redirectAction, 90 | "testLoader", 91 | ); 92 | 93 | const result = await action(actionArgs()); 94 | expect(result).toBeInstanceOf(Response); 95 | expect(result.url).toBe(""); 96 | expect(result.headers.get("location")).toBe("/"); 97 | }); 98 | }); 99 | -------------------------------------------------------------------------------- /tests/util.ts: -------------------------------------------------------------------------------- 1 | import { env } from "cloudflare:test"; 2 | import type { ActionFunctionArgs, LoaderFunctionArgs } from "react-router"; 3 | 4 | export const context = { cloudflare: { env } }; 5 | 6 | export function loaderArgs( 7 | opts: Partial = {}, 8 | ): LoaderFunctionArgs { 9 | return { 10 | context, 11 | request: new Request("https://example.com"), 12 | params: {}, 13 | ...opts, 14 | }; 15 | } 16 | 17 | export function actionArgs( 18 | opts: Partial = {}, 19 | ): ActionFunctionArgs { 20 | return { 21 | context, 22 | request: new Request("https://example.com"), 23 | params: {}, 24 | ...opts, 25 | }; 26 | } 27 | 28 | export function unreachable(): never { 29 | throw new Error("unreachable"); 30 | } 31 | -------------------------------------------------------------------------------- /tests/worker.ts: -------------------------------------------------------------------------------- 1 | import { DurableObject, WorkerEntrypoint } from "cloudflare:workers"; 2 | import type { env } from "cloudflare:test"; 3 | import { 4 | type ActionFunctionArgs, 5 | type LoaderFunctionArgs, 6 | redirect, 7 | } from "react-router"; 8 | 9 | export class TestDurableObject extends DurableObject { 10 | async testLoader() { 11 | return { called: "testLoader" }; 12 | } 13 | 14 | async testAction() { 15 | return { called: "testAction" }; 16 | } 17 | 18 | async argsDataLoader(args: LoaderFunctionArgs) { 19 | return { 20 | params: args.params, 21 | request: { 22 | url: args.request.url, 23 | headers: Object.fromEntries(args.request.headers.entries()), 24 | body: await args.request.text(), 25 | }, 26 | }; 27 | } 28 | 29 | async formAction({ request }: ActionFunctionArgs) { 30 | const form = await request.formData(); 31 | return Object.fromEntries(form.entries()); 32 | } 33 | 34 | async redirectAction() { 35 | return redirect("/"); 36 | } 37 | } 38 | 39 | export default class Main extends WorkerEntrypoint {} 40 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["src/**/*.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "ES2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "NodeNext" /* Specify what module code is generated. */, 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | "moduleResolution": "nodenext" /* Specify how TypeScript looks up a file from a given module specifier. */, 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | "types": [ 36 | "@cloudflare/workers-types", 37 | "@cloudflare/vitest-pool-workers" 38 | ] /* Specify type package names to be included without being referenced in a source file. */, 39 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 40 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 41 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 42 | // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ 43 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 44 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 45 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 46 | // "noUncheckedSideEffectImports": true, /* Check side effect imports. */ 47 | // "resolveJsonModule": true, /* Enable importing .json files. */ 48 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 49 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 50 | 51 | /* JavaScript Support */ 52 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 53 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 54 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 55 | 56 | /* Emit */ 57 | "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */, 58 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 59 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 60 | // "sourceMap": true /* Create source map files for emitted JavaScript files. */, 61 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 62 | // "noEmit": true, /* Disable emitting files from a compilation. */ 63 | // "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. */ 64 | "outDir": "./dist" /* Specify an output folder for all emitted files. */, 65 | // "removeComments": true, /* Disable emitting comments. */ 66 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 67 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 68 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 69 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 70 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 71 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 72 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 73 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 74 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 75 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 76 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 77 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 78 | 79 | /* Interop Constraints */ 80 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 81 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 82 | // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ 83 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 84 | "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, 85 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 86 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 87 | 88 | /* Type Checking */ 89 | "strict": true /* Enable all strict type-checking options. */, 90 | "noImplicitAny": true /* Enable error reporting for expressions and declarations with an implied 'any' type. */, 91 | "strictNullChecks": true /* When type checking, take into account 'null' and 'undefined'. */, 92 | "strictFunctionTypes": true /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */, 93 | "strictBindCallApply": true /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */, 94 | "strictPropertyInitialization": true /* Check for class properties that are declared but not set in the constructor. */, 95 | "strictBuiltinIteratorReturn": true /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */, 96 | "noImplicitThis": true /* Enable error reporting when 'this' is given the type 'any'. */, 97 | "useUnknownInCatchVariables": true /* Default catch clause variables as 'unknown' instead of 'any'. */, 98 | "alwaysStrict": true /* Ensure 'use strict' is always emitted. */, 99 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 100 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 101 | "exactOptionalPropertyTypes": true /* Interpret optional property types as written, rather than adding 'undefined'. */, 102 | "noImplicitReturns": true /* Enable error reporting for codepaths that do not explicitly return in a function. */, 103 | "noFallthroughCasesInSwitch": true /* Enable error reporting for fallthrough cases in switch statements. */, 104 | "noUncheckedIndexedAccess": true /* Add 'undefined' to a type when accessed using an index. */, 105 | "noImplicitOverride": true /* Ensure overriding members in derived classes are marked with an override modifier. */, 106 | "noPropertyAccessFromIndexSignature": true /* Enforces using indexed accessors for keys declared using an indexed type. */, 107 | "allowUnusedLabels": true /* Disable error reporting for unused labels. */, 108 | "allowUnreachableCode": true /* Disable error reporting for unreachable code. */, 109 | 110 | /* Completeness */ 111 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 112 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineWorkersConfig } from "@cloudflare/vitest-pool-workers/config"; 2 | 3 | export default defineWorkersConfig({ 4 | test: { 5 | poolOptions: { 6 | workers: { 7 | main: "./tests/worker.ts", 8 | miniflare: { 9 | compatibilityDate: "2024-01-24", 10 | compatibilityFlags: ["nodejs_compat", "rpc"], 11 | durableObjects: { 12 | test: { 13 | className: "TestDurableObject", 14 | useSQLite: true, 15 | }, 16 | }, 17 | }, 18 | }, 19 | }, 20 | }, 21 | }); 22 | --------------------------------------------------------------------------------