├── .gitignore ├── .prettierignore ├── .prettierrc ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── src ├── UppyDecrypt.ts ├── UppyEncrypt.ts ├── constants.ts └── index.ts ├── tsconfig.json └── tsup.config.ts /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | dist 4 | 5 | # Log files 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | pnpm-debug.log* 10 | 11 | # Editor directories and files 12 | .idea 13 | .vscode 14 | *.suo 15 | *.ntvs* 16 | *.njsproj 17 | *.sln 18 | *.sw? 19 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /package 5 | .env 6 | .env.* 7 | !.env.example 8 | 9 | # Ignore files for PNPM, NPM and YARN 10 | pnpm-lock.yaml 11 | package-lock.json 12 | yarn.lock 13 | static -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": true, 6 | "bracketSpacing": true, 7 | "plugins": [], 8 | "overrides": [], 9 | "printWidth": 160 10 | } 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 0sum Co 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Uppy Encrypt 2 | 3 | An [Uppy](https://uppy.io/) Plugin to encrypt files via the browser before they're uploaded. Decryption is handled browser-side as well. 4 | 5 | Oh, also, it's fast AF. 🚀 6 | 7 | Uppy Encrypt uses [libsodium.js](https://github.com/jedisct1/libsodium.js) for all the cryptographical magic. 8 | 9 | A live implementation of Uppy Encrypt can be seen on [0up.io](https://0up.io) [[Source Code]](https://github.com/0sumcode/0up) 10 | 11 | ## Installation 12 | 13 | ```bash 14 | npm i uppy-encrypt 15 | ``` 16 | 17 | ## Encryption Example 18 | ```javascript 19 | import { Uppy } from '@uppy/core'; 20 | import UppyEncryptPlugin from 'uppy-encrypt'; 21 | 22 | const uppy = new Uppy(); 23 | uppy.use(UppyEncryptPlugin); 24 | 25 | // Optional: Set password manually, or disregard and a random password will be auto-generated 26 | // uppy.setMeta({ password: '$upers3cret!' }); 27 | 28 | uppy.on('complete', async (result) => { 29 | for (const file of result.successful) { 30 | const salt = file.meta.encryption.salt; // Salt value used to increase security 31 | const header = file.meta.encryption.header; // Header encryption data to kick off the decryption process 32 | const hash = file.meta.encryption.hash; // Secure 1-way hash of the password 33 | const meta = file.meta.encryption.meta; // Encrypted file meta data (file name, type) 34 | // ^ These are all safe to store in a database 35 | } 36 | }); 37 | ``` 38 | 39 | ## Decryption Example 40 | ```javascript 41 | import { UppyDecrypt, uppyEncryptReady } from 'uppy-encrypt'; 42 | 43 | // Use the values generated from the encryption process 44 | // Usually, these would be stored/retrieved from a database 45 | const decrypt = async (hash, password, salt, header, meta, encryptedFileUrl) => { 46 | // Ensure required libraries are loaded 47 | await uppyEncryptReady(); 48 | 49 | // Verify provided password against the stored hash value 50 | if (!UppyDecrypt.verifyPassword(hash, password)) { 51 | // Invalid password 52 | return; 53 | } 54 | 55 | // Decrypt Metadata 56 | const decryptor = new UppyDecrypt(password, salt, header); 57 | const decryptedMeta = decryptor.getDecryptedMetaData(meta.header, meta.data); 58 | 59 | // Fetch & Decrypt the encrypted file 60 | const file = await fetch(encryptedFileUrl); 61 | const blob = await file.blob(); 62 | const decrypted = await decryptor.decryptFile(blob); 63 | 64 | // Do something with the decrypted file, like download it 65 | if (decrypted) { 66 | const aElement = document.createElement('a'); 67 | aElement.setAttribute('download', decryptedMeta.name); 68 | const href = URL.createObjectURL(decrypted); 69 | aElement.href = href; 70 | aElement.setAttribute('target', '_blank'); 71 | aElement.click(); 72 | URL.revokeObjectURL(href); 73 | } 74 | } 75 | ``` 76 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "uppy-encrypt", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "uppy-encrypt", 9 | "version": "1.0.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@types/libsodium-wrappers-sumo": "^0.7.8", 13 | "@uppy/core": "^3.7.1", 14 | "libsodium-wrappers-sumo": "^0.7.13" 15 | }, 16 | "devDependencies": { 17 | "ts-node": "^10.9.1", 18 | "tsup": "^8.0.1", 19 | "typescript": "^5.3.2" 20 | } 21 | }, 22 | "node_modules/@cspotcode/source-map-support": { 23 | "version": "0.8.1", 24 | "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", 25 | "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", 26 | "dev": true, 27 | "dependencies": { 28 | "@jridgewell/trace-mapping": "0.3.9" 29 | }, 30 | "engines": { 31 | "node": ">=12" 32 | } 33 | }, 34 | "node_modules/@esbuild/android-arm": { 35 | "version": "0.19.8", 36 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.8.tgz", 37 | "integrity": "sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA==", 38 | "cpu": [ 39 | "arm" 40 | ], 41 | "dev": true, 42 | "optional": true, 43 | "os": [ 44 | "android" 45 | ], 46 | "engines": { 47 | "node": ">=12" 48 | } 49 | }, 50 | "node_modules/@esbuild/android-arm64": { 51 | "version": "0.19.8", 52 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.8.tgz", 53 | "integrity": "sha512-B8JbS61bEunhfx8kasogFENgQfr/dIp+ggYXwTqdbMAgGDhRa3AaPpQMuQU0rNxDLECj6FhDzk1cF9WHMVwrtA==", 54 | "cpu": [ 55 | "arm64" 56 | ], 57 | "dev": true, 58 | "optional": true, 59 | "os": [ 60 | "android" 61 | ], 62 | "engines": { 63 | "node": ">=12" 64 | } 65 | }, 66 | "node_modules/@esbuild/android-x64": { 67 | "version": "0.19.8", 68 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.8.tgz", 69 | "integrity": "sha512-rdqqYfRIn4jWOp+lzQttYMa2Xar3OK9Yt2fhOhzFXqg0rVWEfSclJvZq5fZslnz6ypHvVf3CT7qyf0A5pM682A==", 70 | "cpu": [ 71 | "x64" 72 | ], 73 | "dev": true, 74 | "optional": true, 75 | "os": [ 76 | "android" 77 | ], 78 | "engines": { 79 | "node": ">=12" 80 | } 81 | }, 82 | "node_modules/@esbuild/darwin-arm64": { 83 | "version": "0.19.8", 84 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.8.tgz", 85 | "integrity": "sha512-RQw9DemMbIq35Bprbboyf8SmOr4UXsRVxJ97LgB55VKKeJOOdvsIPy0nFyF2l8U+h4PtBx/1kRf0BelOYCiQcw==", 86 | "cpu": [ 87 | "arm64" 88 | ], 89 | "dev": true, 90 | "optional": true, 91 | "os": [ 92 | "darwin" 93 | ], 94 | "engines": { 95 | "node": ">=12" 96 | } 97 | }, 98 | "node_modules/@esbuild/darwin-x64": { 99 | "version": "0.19.8", 100 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.8.tgz", 101 | "integrity": "sha512-3sur80OT9YdeZwIVgERAysAbwncom7b4bCI2XKLjMfPymTud7e/oY4y+ci1XVp5TfQp/bppn7xLw1n/oSQY3/Q==", 102 | "cpu": [ 103 | "x64" 104 | ], 105 | "dev": true, 106 | "optional": true, 107 | "os": [ 108 | "darwin" 109 | ], 110 | "engines": { 111 | "node": ">=12" 112 | } 113 | }, 114 | "node_modules/@esbuild/freebsd-arm64": { 115 | "version": "0.19.8", 116 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.8.tgz", 117 | "integrity": "sha512-WAnPJSDattvS/XtPCTj1tPoTxERjcTpH6HsMr6ujTT+X6rylVe8ggxk8pVxzf5U1wh5sPODpawNicF5ta/9Tmw==", 118 | "cpu": [ 119 | "arm64" 120 | ], 121 | "dev": true, 122 | "optional": true, 123 | "os": [ 124 | "freebsd" 125 | ], 126 | "engines": { 127 | "node": ">=12" 128 | } 129 | }, 130 | "node_modules/@esbuild/freebsd-x64": { 131 | "version": "0.19.8", 132 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.8.tgz", 133 | "integrity": "sha512-ICvZyOplIjmmhjd6mxi+zxSdpPTKFfyPPQMQTK/w+8eNK6WV01AjIztJALDtwNNfFhfZLux0tZLC+U9nSyA5Zg==", 134 | "cpu": [ 135 | "x64" 136 | ], 137 | "dev": true, 138 | "optional": true, 139 | "os": [ 140 | "freebsd" 141 | ], 142 | "engines": { 143 | "node": ">=12" 144 | } 145 | }, 146 | "node_modules/@esbuild/linux-arm": { 147 | "version": "0.19.8", 148 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.8.tgz", 149 | "integrity": "sha512-H4vmI5PYqSvosPaTJuEppU9oz1dq2A7Mr2vyg5TF9Ga+3+MGgBdGzcyBP7qK9MrwFQZlvNyJrvz6GuCaj3OukQ==", 150 | "cpu": [ 151 | "arm" 152 | ], 153 | "dev": true, 154 | "optional": true, 155 | "os": [ 156 | "linux" 157 | ], 158 | "engines": { 159 | "node": ">=12" 160 | } 161 | }, 162 | "node_modules/@esbuild/linux-arm64": { 163 | "version": "0.19.8", 164 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.8.tgz", 165 | "integrity": "sha512-z1zMZivxDLHWnyGOctT9JP70h0beY54xDDDJt4VpTX+iwA77IFsE1vCXWmprajJGa+ZYSqkSbRQ4eyLCpCmiCQ==", 166 | "cpu": [ 167 | "arm64" 168 | ], 169 | "dev": true, 170 | "optional": true, 171 | "os": [ 172 | "linux" 173 | ], 174 | "engines": { 175 | "node": ">=12" 176 | } 177 | }, 178 | "node_modules/@esbuild/linux-ia32": { 179 | "version": "0.19.8", 180 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.8.tgz", 181 | "integrity": "sha512-1a8suQiFJmZz1khm/rDglOc8lavtzEMRo0v6WhPgxkrjcU0LkHj+TwBrALwoz/OtMExvsqbbMI0ChyelKabSvQ==", 182 | "cpu": [ 183 | "ia32" 184 | ], 185 | "dev": true, 186 | "optional": true, 187 | "os": [ 188 | "linux" 189 | ], 190 | "engines": { 191 | "node": ">=12" 192 | } 193 | }, 194 | "node_modules/@esbuild/linux-loong64": { 195 | "version": "0.19.8", 196 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.8.tgz", 197 | "integrity": "sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ==", 198 | "cpu": [ 199 | "loong64" 200 | ], 201 | "dev": true, 202 | "optional": true, 203 | "os": [ 204 | "linux" 205 | ], 206 | "engines": { 207 | "node": ">=12" 208 | } 209 | }, 210 | "node_modules/@esbuild/linux-mips64el": { 211 | "version": "0.19.8", 212 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.8.tgz", 213 | "integrity": "sha512-Wy/z0EL5qZYLX66dVnEg9riiwls5IYnziwuju2oUiuxVc+/edvqXa04qNtbrs0Ukatg5HEzqT94Zs7J207dN5Q==", 214 | "cpu": [ 215 | "mips64el" 216 | ], 217 | "dev": true, 218 | "optional": true, 219 | "os": [ 220 | "linux" 221 | ], 222 | "engines": { 223 | "node": ">=12" 224 | } 225 | }, 226 | "node_modules/@esbuild/linux-ppc64": { 227 | "version": "0.19.8", 228 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.8.tgz", 229 | "integrity": "sha512-ETaW6245wK23YIEufhMQ3HSeHO7NgsLx8gygBVldRHKhOlD1oNeNy/P67mIh1zPn2Hr2HLieQrt6tWrVwuqrxg==", 230 | "cpu": [ 231 | "ppc64" 232 | ], 233 | "dev": true, 234 | "optional": true, 235 | "os": [ 236 | "linux" 237 | ], 238 | "engines": { 239 | "node": ">=12" 240 | } 241 | }, 242 | "node_modules/@esbuild/linux-riscv64": { 243 | "version": "0.19.8", 244 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.8.tgz", 245 | "integrity": "sha512-T2DRQk55SgoleTP+DtPlMrxi/5r9AeFgkhkZ/B0ap99zmxtxdOixOMI570VjdRCs9pE4Wdkz7JYrsPvsl7eESg==", 246 | "cpu": [ 247 | "riscv64" 248 | ], 249 | "dev": true, 250 | "optional": true, 251 | "os": [ 252 | "linux" 253 | ], 254 | "engines": { 255 | "node": ">=12" 256 | } 257 | }, 258 | "node_modules/@esbuild/linux-s390x": { 259 | "version": "0.19.8", 260 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.8.tgz", 261 | "integrity": "sha512-NPxbdmmo3Bk7mbNeHmcCd7R7fptJaczPYBaELk6NcXxy7HLNyWwCyDJ/Xx+/YcNH7Im5dHdx9gZ5xIwyliQCbg==", 262 | "cpu": [ 263 | "s390x" 264 | ], 265 | "dev": true, 266 | "optional": true, 267 | "os": [ 268 | "linux" 269 | ], 270 | "engines": { 271 | "node": ">=12" 272 | } 273 | }, 274 | "node_modules/@esbuild/linux-x64": { 275 | "version": "0.19.8", 276 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.8.tgz", 277 | "integrity": "sha512-lytMAVOM3b1gPypL2TRmZ5rnXl7+6IIk8uB3eLsV1JwcizuolblXRrc5ShPrO9ls/b+RTp+E6gbsuLWHWi2zGg==", 278 | "cpu": [ 279 | "x64" 280 | ], 281 | "dev": true, 282 | "optional": true, 283 | "os": [ 284 | "linux" 285 | ], 286 | "engines": { 287 | "node": ">=12" 288 | } 289 | }, 290 | "node_modules/@esbuild/netbsd-x64": { 291 | "version": "0.19.8", 292 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.8.tgz", 293 | "integrity": "sha512-hvWVo2VsXz/8NVt1UhLzxwAfo5sioj92uo0bCfLibB0xlOmimU/DeAEsQILlBQvkhrGjamP0/el5HU76HAitGw==", 294 | "cpu": [ 295 | "x64" 296 | ], 297 | "dev": true, 298 | "optional": true, 299 | "os": [ 300 | "netbsd" 301 | ], 302 | "engines": { 303 | "node": ">=12" 304 | } 305 | }, 306 | "node_modules/@esbuild/openbsd-x64": { 307 | "version": "0.19.8", 308 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.8.tgz", 309 | "integrity": "sha512-/7Y7u77rdvmGTxR83PgaSvSBJCC2L3Kb1M/+dmSIvRvQPXXCuC97QAwMugBNG0yGcbEGfFBH7ojPzAOxfGNkwQ==", 310 | "cpu": [ 311 | "x64" 312 | ], 313 | "dev": true, 314 | "optional": true, 315 | "os": [ 316 | "openbsd" 317 | ], 318 | "engines": { 319 | "node": ">=12" 320 | } 321 | }, 322 | "node_modules/@esbuild/sunos-x64": { 323 | "version": "0.19.8", 324 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.8.tgz", 325 | "integrity": "sha512-9Lc4s7Oi98GqFA4HzA/W2JHIYfnXbUYgekUP/Sm4BG9sfLjyv6GKKHKKVs83SMicBF2JwAX6A1PuOLMqpD001w==", 326 | "cpu": [ 327 | "x64" 328 | ], 329 | "dev": true, 330 | "optional": true, 331 | "os": [ 332 | "sunos" 333 | ], 334 | "engines": { 335 | "node": ">=12" 336 | } 337 | }, 338 | "node_modules/@esbuild/win32-arm64": { 339 | "version": "0.19.8", 340 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.8.tgz", 341 | "integrity": "sha512-rq6WzBGjSzihI9deW3fC2Gqiak68+b7qo5/3kmB6Gvbh/NYPA0sJhrnp7wgV4bNwjqM+R2AApXGxMO7ZoGhIJg==", 342 | "cpu": [ 343 | "arm64" 344 | ], 345 | "dev": true, 346 | "optional": true, 347 | "os": [ 348 | "win32" 349 | ], 350 | "engines": { 351 | "node": ">=12" 352 | } 353 | }, 354 | "node_modules/@esbuild/win32-ia32": { 355 | "version": "0.19.8", 356 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.8.tgz", 357 | "integrity": "sha512-AIAbverbg5jMvJznYiGhrd3sumfwWs8572mIJL5NQjJa06P8KfCPWZQ0NwZbPQnbQi9OWSZhFVSUWjjIrn4hSw==", 358 | "cpu": [ 359 | "ia32" 360 | ], 361 | "dev": true, 362 | "optional": true, 363 | "os": [ 364 | "win32" 365 | ], 366 | "engines": { 367 | "node": ">=12" 368 | } 369 | }, 370 | "node_modules/@esbuild/win32-x64": { 371 | "version": "0.19.8", 372 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.8.tgz", 373 | "integrity": "sha512-bfZ0cQ1uZs2PqpulNL5j/3w+GDhP36k1K5c38QdQg+Swy51jFZWWeIkteNsufkQxp986wnqRRsb/bHbY1WQ7TA==", 374 | "cpu": [ 375 | "x64" 376 | ], 377 | "dev": true, 378 | "optional": true, 379 | "os": [ 380 | "win32" 381 | ], 382 | "engines": { 383 | "node": ">=12" 384 | } 385 | }, 386 | "node_modules/@jridgewell/gen-mapping": { 387 | "version": "0.3.3", 388 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", 389 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", 390 | "dev": true, 391 | "dependencies": { 392 | "@jridgewell/set-array": "^1.0.1", 393 | "@jridgewell/sourcemap-codec": "^1.4.10", 394 | "@jridgewell/trace-mapping": "^0.3.9" 395 | }, 396 | "engines": { 397 | "node": ">=6.0.0" 398 | } 399 | }, 400 | "node_modules/@jridgewell/resolve-uri": { 401 | "version": "3.1.1", 402 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", 403 | "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", 404 | "dev": true, 405 | "engines": { 406 | "node": ">=6.0.0" 407 | } 408 | }, 409 | "node_modules/@jridgewell/set-array": { 410 | "version": "1.1.2", 411 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", 412 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", 413 | "dev": true, 414 | "engines": { 415 | "node": ">=6.0.0" 416 | } 417 | }, 418 | "node_modules/@jridgewell/sourcemap-codec": { 419 | "version": "1.4.15", 420 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 421 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 422 | "dev": true 423 | }, 424 | "node_modules/@jridgewell/trace-mapping": { 425 | "version": "0.3.9", 426 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", 427 | "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", 428 | "dev": true, 429 | "dependencies": { 430 | "@jridgewell/resolve-uri": "^3.0.3", 431 | "@jridgewell/sourcemap-codec": "^1.4.10" 432 | } 433 | }, 434 | "node_modules/@nodelib/fs.scandir": { 435 | "version": "2.1.5", 436 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 437 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 438 | "dev": true, 439 | "dependencies": { 440 | "@nodelib/fs.stat": "2.0.5", 441 | "run-parallel": "^1.1.9" 442 | }, 443 | "engines": { 444 | "node": ">= 8" 445 | } 446 | }, 447 | "node_modules/@nodelib/fs.stat": { 448 | "version": "2.0.5", 449 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 450 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 451 | "dev": true, 452 | "engines": { 453 | "node": ">= 8" 454 | } 455 | }, 456 | "node_modules/@nodelib/fs.walk": { 457 | "version": "1.2.8", 458 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 459 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 460 | "dev": true, 461 | "dependencies": { 462 | "@nodelib/fs.scandir": "2.1.5", 463 | "fastq": "^1.6.0" 464 | }, 465 | "engines": { 466 | "node": ">= 8" 467 | } 468 | }, 469 | "node_modules/@rollup/rollup-android-arm-eabi": { 470 | "version": "4.6.1", 471 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.6.1.tgz", 472 | "integrity": "sha512-0WQ0ouLejaUCRsL93GD4uft3rOmB8qoQMU05Kb8CmMtMBe7XUDLAltxVZI1q6byNqEtU7N1ZX1Vw5lIpgulLQA==", 473 | "cpu": [ 474 | "arm" 475 | ], 476 | "dev": true, 477 | "optional": true, 478 | "os": [ 479 | "android" 480 | ] 481 | }, 482 | "node_modules/@rollup/rollup-android-arm64": { 483 | "version": "4.6.1", 484 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.6.1.tgz", 485 | "integrity": "sha512-1TKm25Rn20vr5aTGGZqo6E4mzPicCUD79k17EgTLAsXc1zysyi4xXKACfUbwyANEPAEIxkzwue6JZ+stYzWUTA==", 486 | "cpu": [ 487 | "arm64" 488 | ], 489 | "dev": true, 490 | "optional": true, 491 | "os": [ 492 | "android" 493 | ] 494 | }, 495 | "node_modules/@rollup/rollup-darwin-arm64": { 496 | "version": "4.6.1", 497 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.6.1.tgz", 498 | "integrity": "sha512-cEXJQY/ZqMACb+nxzDeX9IPLAg7S94xouJJCNVE5BJM8JUEP4HeTF+ti3cmxWeSJo+5D+o8Tc0UAWUkfENdeyw==", 499 | "cpu": [ 500 | "arm64" 501 | ], 502 | "dev": true, 503 | "optional": true, 504 | "os": [ 505 | "darwin" 506 | ] 507 | }, 508 | "node_modules/@rollup/rollup-darwin-x64": { 509 | "version": "4.6.1", 510 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.6.1.tgz", 511 | "integrity": "sha512-LoSU9Xu56isrkV2jLldcKspJ7sSXmZWkAxg7sW/RfF7GS4F5/v4EiqKSMCFbZtDu2Nc1gxxFdQdKwkKS4rwxNg==", 512 | "cpu": [ 513 | "x64" 514 | ], 515 | "dev": true, 516 | "optional": true, 517 | "os": [ 518 | "darwin" 519 | ] 520 | }, 521 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 522 | "version": "4.6.1", 523 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.6.1.tgz", 524 | "integrity": "sha512-EfI3hzYAy5vFNDqpXsNxXcgRDcFHUWSx5nnRSCKwXuQlI5J9dD84g2Usw81n3FLBNsGCegKGwwTVsSKK9cooSQ==", 525 | "cpu": [ 526 | "arm" 527 | ], 528 | "dev": true, 529 | "optional": true, 530 | "os": [ 531 | "linux" 532 | ] 533 | }, 534 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 535 | "version": "4.6.1", 536 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.6.1.tgz", 537 | "integrity": "sha512-9lhc4UZstsegbNLhH0Zu6TqvDfmhGzuCWtcTFXY10VjLLUe4Mr0Ye2L3rrtHaDd/J5+tFMEuo5LTCSCMXWfUKw==", 538 | "cpu": [ 539 | "arm64" 540 | ], 541 | "dev": true, 542 | "optional": true, 543 | "os": [ 544 | "linux" 545 | ] 546 | }, 547 | "node_modules/@rollup/rollup-linux-arm64-musl": { 548 | "version": "4.6.1", 549 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.6.1.tgz", 550 | "integrity": "sha512-FfoOK1yP5ksX3wwZ4Zk1NgyGHZyuRhf99j64I5oEmirV8EFT7+OhUZEnP+x17lcP/QHJNWGsoJwrz4PJ9fBEXw==", 551 | "cpu": [ 552 | "arm64" 553 | ], 554 | "dev": true, 555 | "optional": true, 556 | "os": [ 557 | "linux" 558 | ] 559 | }, 560 | "node_modules/@rollup/rollup-linux-x64-gnu": { 561 | "version": "4.6.1", 562 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.6.1.tgz", 563 | "integrity": "sha512-DNGZvZDO5YF7jN5fX8ZqmGLjZEXIJRdJEdTFMhiyXqyXubBa0WVLDWSNlQ5JR2PNgDbEV1VQowhVRUh+74D+RA==", 564 | "cpu": [ 565 | "x64" 566 | ], 567 | "dev": true, 568 | "optional": true, 569 | "os": [ 570 | "linux" 571 | ] 572 | }, 573 | "node_modules/@rollup/rollup-linux-x64-musl": { 574 | "version": "4.6.1", 575 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.6.1.tgz", 576 | "integrity": "sha512-RkJVNVRM+piYy87HrKmhbexCHg3A6Z6MU0W9GHnJwBQNBeyhCJG9KDce4SAMdicQnpURggSvtbGo9xAWOfSvIQ==", 577 | "cpu": [ 578 | "x64" 579 | ], 580 | "dev": true, 581 | "optional": true, 582 | "os": [ 583 | "linux" 584 | ] 585 | }, 586 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 587 | "version": "4.6.1", 588 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.6.1.tgz", 589 | "integrity": "sha512-v2FVT6xfnnmTe3W9bJXl6r5KwJglMK/iRlkKiIFfO6ysKs0rDgz7Cwwf3tjldxQUrHL9INT/1r4VA0n9L/F1vQ==", 590 | "cpu": [ 591 | "arm64" 592 | ], 593 | "dev": true, 594 | "optional": true, 595 | "os": [ 596 | "win32" 597 | ] 598 | }, 599 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 600 | "version": "4.6.1", 601 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.6.1.tgz", 602 | "integrity": "sha512-YEeOjxRyEjqcWphH9dyLbzgkF8wZSKAKUkldRY6dgNR5oKs2LZazqGB41cWJ4Iqqcy9/zqYgmzBkRoVz3Q9MLw==", 603 | "cpu": [ 604 | "ia32" 605 | ], 606 | "dev": true, 607 | "optional": true, 608 | "os": [ 609 | "win32" 610 | ] 611 | }, 612 | "node_modules/@rollup/rollup-win32-x64-msvc": { 613 | "version": "4.6.1", 614 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.6.1.tgz", 615 | "integrity": "sha512-0zfTlFAIhgz8V2G8STq8toAjsYYA6eci1hnXuyOTUFnymrtJwnS6uGKiv3v5UrPZkBlamLvrLV2iiaeqCKzb0A==", 616 | "cpu": [ 617 | "x64" 618 | ], 619 | "dev": true, 620 | "optional": true, 621 | "os": [ 622 | "win32" 623 | ] 624 | }, 625 | "node_modules/@transloadit/prettier-bytes": { 626 | "version": "0.0.9", 627 | "resolved": "https://registry.npmjs.org/@transloadit/prettier-bytes/-/prettier-bytes-0.0.9.tgz", 628 | "integrity": "sha512-pCvdmea/F3Tn4hAtHqNXmjcixSaroJJ+L3STXlYJdir1g1m2mRQpWbN8a4SvgQtaw2930Ckhdx8qXdXBFMKbAA==" 629 | }, 630 | "node_modules/@tsconfig/node10": { 631 | "version": "1.0.9", 632 | "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", 633 | "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", 634 | "dev": true 635 | }, 636 | "node_modules/@tsconfig/node12": { 637 | "version": "1.0.11", 638 | "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", 639 | "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", 640 | "dev": true 641 | }, 642 | "node_modules/@tsconfig/node14": { 643 | "version": "1.0.3", 644 | "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", 645 | "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", 646 | "dev": true 647 | }, 648 | "node_modules/@tsconfig/node16": { 649 | "version": "1.0.4", 650 | "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", 651 | "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", 652 | "dev": true 653 | }, 654 | "node_modules/@types/libsodium-wrappers": { 655 | "version": "0.7.13", 656 | "resolved": "https://registry.npmjs.org/@types/libsodium-wrappers/-/libsodium-wrappers-0.7.13.tgz", 657 | "integrity": "sha512-KeAKtlObirLJk/na6jHBFEdTDjDfFS6Vcr0eG2FjiHKn3Nw8axJFfIu0Y9TpwaauRldQBj/pZm/MHtK76r6OWg==" 658 | }, 659 | "node_modules/@types/libsodium-wrappers-sumo": { 660 | "version": "0.7.8", 661 | "resolved": "https://registry.npmjs.org/@types/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.8.tgz", 662 | "integrity": "sha512-N2+df4MB/A+W0RAcTw7A5oxKgzD+Vh6Ye7lfjWIi5SdTzVLfHPzxUjhwPqHLO5Ev9fv/+VHl+sUaUuTg4fUPqw==", 663 | "dependencies": { 664 | "@types/libsodium-wrappers": "*" 665 | } 666 | }, 667 | "node_modules/@types/node": { 668 | "version": "20.10.3", 669 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz", 670 | "integrity": "sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==", 671 | "dev": true, 672 | "peer": true, 673 | "dependencies": { 674 | "undici-types": "~5.26.4" 675 | } 676 | }, 677 | "node_modules/@uppy/core": { 678 | "version": "3.7.1", 679 | "resolved": "https://registry.npmjs.org/@uppy/core/-/core-3.7.1.tgz", 680 | "integrity": "sha512-P8JoDbDYyJ5ZX35+IfrDj2WupKvfEpYwoMgyjutaLhaT/+hmHoTivZpJV256eaZahJMTYrQlZmGfXy1LRByV3A==", 681 | "dependencies": { 682 | "@transloadit/prettier-bytes": "0.0.9", 683 | "@uppy/store-default": "^3.0.5", 684 | "@uppy/utils": "^5.6.0", 685 | "lodash": "^4.17.21", 686 | "mime-match": "^1.0.2", 687 | "namespace-emitter": "^2.0.1", 688 | "nanoid": "^4.0.0", 689 | "preact": "^10.5.13" 690 | } 691 | }, 692 | "node_modules/@uppy/store-default": { 693 | "version": "3.1.0", 694 | "resolved": "https://registry.npmjs.org/@uppy/store-default/-/store-default-3.1.0.tgz", 695 | "integrity": "sha512-I0Ouxom5wPb/M4SQourDKq6nQXZobNwp6x91zdkDhGtOA9GgDKJ/eYDthFRV+lj9NKAjZWjbOhV+DO9rVnEUeA==" 696 | }, 697 | "node_modules/@uppy/utils": { 698 | "version": "5.6.0", 699 | "resolved": "https://registry.npmjs.org/@uppy/utils/-/utils-5.6.0.tgz", 700 | "integrity": "sha512-Blr6Po6a49niTugSzuguNtH9M1wSU4vdRnaGBsScv+JjcslzG3OkMmfnnhesj1ZIVyxMdVDjyPGXoqh4Wm2Dzg==", 701 | "dependencies": { 702 | "lodash": "^4.17.21", 703 | "preact": "^10.5.13" 704 | } 705 | }, 706 | "node_modules/acorn": { 707 | "version": "8.11.2", 708 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", 709 | "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", 710 | "dev": true, 711 | "bin": { 712 | "acorn": "bin/acorn" 713 | }, 714 | "engines": { 715 | "node": ">=0.4.0" 716 | } 717 | }, 718 | "node_modules/acorn-walk": { 719 | "version": "8.3.0", 720 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", 721 | "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==", 722 | "dev": true, 723 | "engines": { 724 | "node": ">=0.4.0" 725 | } 726 | }, 727 | "node_modules/any-promise": { 728 | "version": "1.3.0", 729 | "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", 730 | "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", 731 | "dev": true 732 | }, 733 | "node_modules/anymatch": { 734 | "version": "3.1.3", 735 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 736 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 737 | "dev": true, 738 | "dependencies": { 739 | "normalize-path": "^3.0.0", 740 | "picomatch": "^2.0.4" 741 | }, 742 | "engines": { 743 | "node": ">= 8" 744 | } 745 | }, 746 | "node_modules/arg": { 747 | "version": "4.1.3", 748 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 749 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", 750 | "dev": true 751 | }, 752 | "node_modules/array-union": { 753 | "version": "2.1.0", 754 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", 755 | "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", 756 | "dev": true, 757 | "engines": { 758 | "node": ">=8" 759 | } 760 | }, 761 | "node_modules/balanced-match": { 762 | "version": "1.0.2", 763 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 764 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 765 | "dev": true 766 | }, 767 | "node_modules/binary-extensions": { 768 | "version": "2.2.0", 769 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 770 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 771 | "dev": true, 772 | "engines": { 773 | "node": ">=8" 774 | } 775 | }, 776 | "node_modules/brace-expansion": { 777 | "version": "1.1.11", 778 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 779 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 780 | "dev": true, 781 | "dependencies": { 782 | "balanced-match": "^1.0.0", 783 | "concat-map": "0.0.1" 784 | } 785 | }, 786 | "node_modules/braces": { 787 | "version": "3.0.2", 788 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 789 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 790 | "dev": true, 791 | "dependencies": { 792 | "fill-range": "^7.0.1" 793 | }, 794 | "engines": { 795 | "node": ">=8" 796 | } 797 | }, 798 | "node_modules/bundle-require": { 799 | "version": "4.0.2", 800 | "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-4.0.2.tgz", 801 | "integrity": "sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag==", 802 | "dev": true, 803 | "dependencies": { 804 | "load-tsconfig": "^0.2.3" 805 | }, 806 | "engines": { 807 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 808 | }, 809 | "peerDependencies": { 810 | "esbuild": ">=0.17" 811 | } 812 | }, 813 | "node_modules/cac": { 814 | "version": "6.7.14", 815 | "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", 816 | "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", 817 | "dev": true, 818 | "engines": { 819 | "node": ">=8" 820 | } 821 | }, 822 | "node_modules/chokidar": { 823 | "version": "3.5.3", 824 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 825 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 826 | "dev": true, 827 | "funding": [ 828 | { 829 | "type": "individual", 830 | "url": "https://paulmillr.com/funding/" 831 | } 832 | ], 833 | "dependencies": { 834 | "anymatch": "~3.1.2", 835 | "braces": "~3.0.2", 836 | "glob-parent": "~5.1.2", 837 | "is-binary-path": "~2.1.0", 838 | "is-glob": "~4.0.1", 839 | "normalize-path": "~3.0.0", 840 | "readdirp": "~3.6.0" 841 | }, 842 | "engines": { 843 | "node": ">= 8.10.0" 844 | }, 845 | "optionalDependencies": { 846 | "fsevents": "~2.3.2" 847 | } 848 | }, 849 | "node_modules/commander": { 850 | "version": "4.1.1", 851 | "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", 852 | "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", 853 | "dev": true, 854 | "engines": { 855 | "node": ">= 6" 856 | } 857 | }, 858 | "node_modules/concat-map": { 859 | "version": "0.0.1", 860 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 861 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 862 | "dev": true 863 | }, 864 | "node_modules/create-require": { 865 | "version": "1.1.1", 866 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", 867 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", 868 | "dev": true 869 | }, 870 | "node_modules/cross-spawn": { 871 | "version": "7.0.3", 872 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 873 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 874 | "dev": true, 875 | "dependencies": { 876 | "path-key": "^3.1.0", 877 | "shebang-command": "^2.0.0", 878 | "which": "^2.0.1" 879 | }, 880 | "engines": { 881 | "node": ">= 8" 882 | } 883 | }, 884 | "node_modules/debug": { 885 | "version": "4.3.4", 886 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 887 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 888 | "dev": true, 889 | "dependencies": { 890 | "ms": "2.1.2" 891 | }, 892 | "engines": { 893 | "node": ">=6.0" 894 | }, 895 | "peerDependenciesMeta": { 896 | "supports-color": { 897 | "optional": true 898 | } 899 | } 900 | }, 901 | "node_modules/diff": { 902 | "version": "4.0.2", 903 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 904 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 905 | "dev": true, 906 | "engines": { 907 | "node": ">=0.3.1" 908 | } 909 | }, 910 | "node_modules/dir-glob": { 911 | "version": "3.0.1", 912 | "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", 913 | "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", 914 | "dev": true, 915 | "dependencies": { 916 | "path-type": "^4.0.0" 917 | }, 918 | "engines": { 919 | "node": ">=8" 920 | } 921 | }, 922 | "node_modules/esbuild": { 923 | "version": "0.19.8", 924 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.8.tgz", 925 | "integrity": "sha512-l7iffQpT2OrZfH2rXIp7/FkmaeZM0vxbxN9KfiCwGYuZqzMg/JdvX26R31Zxn/Pxvsrg3Y9N6XTcnknqDyyv4w==", 926 | "dev": true, 927 | "hasInstallScript": true, 928 | "bin": { 929 | "esbuild": "bin/esbuild" 930 | }, 931 | "engines": { 932 | "node": ">=12" 933 | }, 934 | "optionalDependencies": { 935 | "@esbuild/android-arm": "0.19.8", 936 | "@esbuild/android-arm64": "0.19.8", 937 | "@esbuild/android-x64": "0.19.8", 938 | "@esbuild/darwin-arm64": "0.19.8", 939 | "@esbuild/darwin-x64": "0.19.8", 940 | "@esbuild/freebsd-arm64": "0.19.8", 941 | "@esbuild/freebsd-x64": "0.19.8", 942 | "@esbuild/linux-arm": "0.19.8", 943 | "@esbuild/linux-arm64": "0.19.8", 944 | "@esbuild/linux-ia32": "0.19.8", 945 | "@esbuild/linux-loong64": "0.19.8", 946 | "@esbuild/linux-mips64el": "0.19.8", 947 | "@esbuild/linux-ppc64": "0.19.8", 948 | "@esbuild/linux-riscv64": "0.19.8", 949 | "@esbuild/linux-s390x": "0.19.8", 950 | "@esbuild/linux-x64": "0.19.8", 951 | "@esbuild/netbsd-x64": "0.19.8", 952 | "@esbuild/openbsd-x64": "0.19.8", 953 | "@esbuild/sunos-x64": "0.19.8", 954 | "@esbuild/win32-arm64": "0.19.8", 955 | "@esbuild/win32-ia32": "0.19.8", 956 | "@esbuild/win32-x64": "0.19.8" 957 | } 958 | }, 959 | "node_modules/execa": { 960 | "version": "5.1.1", 961 | "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", 962 | "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", 963 | "dev": true, 964 | "dependencies": { 965 | "cross-spawn": "^7.0.3", 966 | "get-stream": "^6.0.0", 967 | "human-signals": "^2.1.0", 968 | "is-stream": "^2.0.0", 969 | "merge-stream": "^2.0.0", 970 | "npm-run-path": "^4.0.1", 971 | "onetime": "^5.1.2", 972 | "signal-exit": "^3.0.3", 973 | "strip-final-newline": "^2.0.0" 974 | }, 975 | "engines": { 976 | "node": ">=10" 977 | }, 978 | "funding": { 979 | "url": "https://github.com/sindresorhus/execa?sponsor=1" 980 | } 981 | }, 982 | "node_modules/fast-glob": { 983 | "version": "3.3.2", 984 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", 985 | "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", 986 | "dev": true, 987 | "dependencies": { 988 | "@nodelib/fs.stat": "^2.0.2", 989 | "@nodelib/fs.walk": "^1.2.3", 990 | "glob-parent": "^5.1.2", 991 | "merge2": "^1.3.0", 992 | "micromatch": "^4.0.4" 993 | }, 994 | "engines": { 995 | "node": ">=8.6.0" 996 | } 997 | }, 998 | "node_modules/fastq": { 999 | "version": "1.15.0", 1000 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", 1001 | "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", 1002 | "dev": true, 1003 | "dependencies": { 1004 | "reusify": "^1.0.4" 1005 | } 1006 | }, 1007 | "node_modules/fill-range": { 1008 | "version": "7.0.1", 1009 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 1010 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 1011 | "dev": true, 1012 | "dependencies": { 1013 | "to-regex-range": "^5.0.1" 1014 | }, 1015 | "engines": { 1016 | "node": ">=8" 1017 | } 1018 | }, 1019 | "node_modules/fs.realpath": { 1020 | "version": "1.0.0", 1021 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1022 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 1023 | "dev": true 1024 | }, 1025 | "node_modules/fsevents": { 1026 | "version": "2.3.3", 1027 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1028 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1029 | "dev": true, 1030 | "hasInstallScript": true, 1031 | "optional": true, 1032 | "os": [ 1033 | "darwin" 1034 | ], 1035 | "engines": { 1036 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1037 | } 1038 | }, 1039 | "node_modules/get-stream": { 1040 | "version": "6.0.1", 1041 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", 1042 | "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", 1043 | "dev": true, 1044 | "engines": { 1045 | "node": ">=10" 1046 | }, 1047 | "funding": { 1048 | "url": "https://github.com/sponsors/sindresorhus" 1049 | } 1050 | }, 1051 | "node_modules/glob": { 1052 | "version": "7.1.6", 1053 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 1054 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 1055 | "dev": true, 1056 | "dependencies": { 1057 | "fs.realpath": "^1.0.0", 1058 | "inflight": "^1.0.4", 1059 | "inherits": "2", 1060 | "minimatch": "^3.0.4", 1061 | "once": "^1.3.0", 1062 | "path-is-absolute": "^1.0.0" 1063 | }, 1064 | "engines": { 1065 | "node": "*" 1066 | }, 1067 | "funding": { 1068 | "url": "https://github.com/sponsors/isaacs" 1069 | } 1070 | }, 1071 | "node_modules/glob-parent": { 1072 | "version": "5.1.2", 1073 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1074 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1075 | "dev": true, 1076 | "dependencies": { 1077 | "is-glob": "^4.0.1" 1078 | }, 1079 | "engines": { 1080 | "node": ">= 6" 1081 | } 1082 | }, 1083 | "node_modules/globby": { 1084 | "version": "11.1.0", 1085 | "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", 1086 | "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", 1087 | "dev": true, 1088 | "dependencies": { 1089 | "array-union": "^2.1.0", 1090 | "dir-glob": "^3.0.1", 1091 | "fast-glob": "^3.2.9", 1092 | "ignore": "^5.2.0", 1093 | "merge2": "^1.4.1", 1094 | "slash": "^3.0.0" 1095 | }, 1096 | "engines": { 1097 | "node": ">=10" 1098 | }, 1099 | "funding": { 1100 | "url": "https://github.com/sponsors/sindresorhus" 1101 | } 1102 | }, 1103 | "node_modules/human-signals": { 1104 | "version": "2.1.0", 1105 | "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", 1106 | "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", 1107 | "dev": true, 1108 | "engines": { 1109 | "node": ">=10.17.0" 1110 | } 1111 | }, 1112 | "node_modules/ignore": { 1113 | "version": "5.3.0", 1114 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", 1115 | "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", 1116 | "dev": true, 1117 | "engines": { 1118 | "node": ">= 4" 1119 | } 1120 | }, 1121 | "node_modules/inflight": { 1122 | "version": "1.0.6", 1123 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1124 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 1125 | "dev": true, 1126 | "dependencies": { 1127 | "once": "^1.3.0", 1128 | "wrappy": "1" 1129 | } 1130 | }, 1131 | "node_modules/inherits": { 1132 | "version": "2.0.4", 1133 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1134 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1135 | "dev": true 1136 | }, 1137 | "node_modules/is-binary-path": { 1138 | "version": "2.1.0", 1139 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 1140 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 1141 | "dev": true, 1142 | "dependencies": { 1143 | "binary-extensions": "^2.0.0" 1144 | }, 1145 | "engines": { 1146 | "node": ">=8" 1147 | } 1148 | }, 1149 | "node_modules/is-extglob": { 1150 | "version": "2.1.1", 1151 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1152 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 1153 | "dev": true, 1154 | "engines": { 1155 | "node": ">=0.10.0" 1156 | } 1157 | }, 1158 | "node_modules/is-glob": { 1159 | "version": "4.0.3", 1160 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1161 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1162 | "dev": true, 1163 | "dependencies": { 1164 | "is-extglob": "^2.1.1" 1165 | }, 1166 | "engines": { 1167 | "node": ">=0.10.0" 1168 | } 1169 | }, 1170 | "node_modules/is-number": { 1171 | "version": "7.0.0", 1172 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1173 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1174 | "dev": true, 1175 | "engines": { 1176 | "node": ">=0.12.0" 1177 | } 1178 | }, 1179 | "node_modules/is-stream": { 1180 | "version": "2.0.1", 1181 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", 1182 | "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", 1183 | "dev": true, 1184 | "engines": { 1185 | "node": ">=8" 1186 | }, 1187 | "funding": { 1188 | "url": "https://github.com/sponsors/sindresorhus" 1189 | } 1190 | }, 1191 | "node_modules/isexe": { 1192 | "version": "2.0.0", 1193 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1194 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1195 | "dev": true 1196 | }, 1197 | "node_modules/joycon": { 1198 | "version": "3.1.1", 1199 | "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", 1200 | "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", 1201 | "dev": true, 1202 | "engines": { 1203 | "node": ">=10" 1204 | } 1205 | }, 1206 | "node_modules/libsodium-sumo": { 1207 | "version": "0.7.13", 1208 | "resolved": "https://registry.npmjs.org/libsodium-sumo/-/libsodium-sumo-0.7.13.tgz", 1209 | "integrity": "sha512-zTGdLu4b9zSNLfovImpBCbdAA4xkpkZbMnSQjP8HShyOutnGjRHmSOKlsylh1okao6QhLiz7nG98EGn+04cZjQ==" 1210 | }, 1211 | "node_modules/libsodium-wrappers-sumo": { 1212 | "version": "0.7.13", 1213 | "resolved": "https://registry.npmjs.org/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.13.tgz", 1214 | "integrity": "sha512-lz4YdplzDRh6AhnLGF2Dj2IUj94xRN6Bh8T0HLNwzYGwPehQJX6c7iYVrFUPZ3QqxE0bqC+K0IIqqZJYWumwSQ==", 1215 | "dependencies": { 1216 | "libsodium-sumo": "^0.7.13" 1217 | } 1218 | }, 1219 | "node_modules/lilconfig": { 1220 | "version": "3.0.0", 1221 | "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", 1222 | "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", 1223 | "dev": true, 1224 | "engines": { 1225 | "node": ">=14" 1226 | } 1227 | }, 1228 | "node_modules/lines-and-columns": { 1229 | "version": "1.2.4", 1230 | "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", 1231 | "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", 1232 | "dev": true 1233 | }, 1234 | "node_modules/load-tsconfig": { 1235 | "version": "0.2.5", 1236 | "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", 1237 | "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", 1238 | "dev": true, 1239 | "engines": { 1240 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 1241 | } 1242 | }, 1243 | "node_modules/lodash": { 1244 | "version": "4.17.21", 1245 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1246 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 1247 | }, 1248 | "node_modules/lodash.sortby": { 1249 | "version": "4.7.0", 1250 | "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", 1251 | "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", 1252 | "dev": true 1253 | }, 1254 | "node_modules/make-error": { 1255 | "version": "1.3.6", 1256 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 1257 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", 1258 | "dev": true 1259 | }, 1260 | "node_modules/merge-stream": { 1261 | "version": "2.0.0", 1262 | "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", 1263 | "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", 1264 | "dev": true 1265 | }, 1266 | "node_modules/merge2": { 1267 | "version": "1.4.1", 1268 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 1269 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 1270 | "dev": true, 1271 | "engines": { 1272 | "node": ">= 8" 1273 | } 1274 | }, 1275 | "node_modules/micromatch": { 1276 | "version": "4.0.5", 1277 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", 1278 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", 1279 | "dev": true, 1280 | "dependencies": { 1281 | "braces": "^3.0.2", 1282 | "picomatch": "^2.3.1" 1283 | }, 1284 | "engines": { 1285 | "node": ">=8.6" 1286 | } 1287 | }, 1288 | "node_modules/mime-match": { 1289 | "version": "1.0.2", 1290 | "resolved": "https://registry.npmjs.org/mime-match/-/mime-match-1.0.2.tgz", 1291 | "integrity": "sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==", 1292 | "dependencies": { 1293 | "wildcard": "^1.1.0" 1294 | } 1295 | }, 1296 | "node_modules/mimic-fn": { 1297 | "version": "2.1.0", 1298 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", 1299 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", 1300 | "dev": true, 1301 | "engines": { 1302 | "node": ">=6" 1303 | } 1304 | }, 1305 | "node_modules/minimatch": { 1306 | "version": "3.1.2", 1307 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1308 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1309 | "dev": true, 1310 | "dependencies": { 1311 | "brace-expansion": "^1.1.7" 1312 | }, 1313 | "engines": { 1314 | "node": "*" 1315 | } 1316 | }, 1317 | "node_modules/ms": { 1318 | "version": "2.1.2", 1319 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1320 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1321 | "dev": true 1322 | }, 1323 | "node_modules/mz": { 1324 | "version": "2.7.0", 1325 | "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", 1326 | "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", 1327 | "dev": true, 1328 | "dependencies": { 1329 | "any-promise": "^1.0.0", 1330 | "object-assign": "^4.0.1", 1331 | "thenify-all": "^1.0.0" 1332 | } 1333 | }, 1334 | "node_modules/namespace-emitter": { 1335 | "version": "2.0.1", 1336 | "resolved": "https://registry.npmjs.org/namespace-emitter/-/namespace-emitter-2.0.1.tgz", 1337 | "integrity": "sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==" 1338 | }, 1339 | "node_modules/nanoid": { 1340 | "version": "4.0.2", 1341 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz", 1342 | "integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==", 1343 | "funding": [ 1344 | { 1345 | "type": "github", 1346 | "url": "https://github.com/sponsors/ai" 1347 | } 1348 | ], 1349 | "bin": { 1350 | "nanoid": "bin/nanoid.js" 1351 | }, 1352 | "engines": { 1353 | "node": "^14 || ^16 || >=18" 1354 | } 1355 | }, 1356 | "node_modules/normalize-path": { 1357 | "version": "3.0.0", 1358 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1359 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1360 | "dev": true, 1361 | "engines": { 1362 | "node": ">=0.10.0" 1363 | } 1364 | }, 1365 | "node_modules/npm-run-path": { 1366 | "version": "4.0.1", 1367 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", 1368 | "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", 1369 | "dev": true, 1370 | "dependencies": { 1371 | "path-key": "^3.0.0" 1372 | }, 1373 | "engines": { 1374 | "node": ">=8" 1375 | } 1376 | }, 1377 | "node_modules/object-assign": { 1378 | "version": "4.1.1", 1379 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1380 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 1381 | "dev": true, 1382 | "engines": { 1383 | "node": ">=0.10.0" 1384 | } 1385 | }, 1386 | "node_modules/once": { 1387 | "version": "1.4.0", 1388 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1389 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1390 | "dev": true, 1391 | "dependencies": { 1392 | "wrappy": "1" 1393 | } 1394 | }, 1395 | "node_modules/onetime": { 1396 | "version": "5.1.2", 1397 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", 1398 | "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", 1399 | "dev": true, 1400 | "dependencies": { 1401 | "mimic-fn": "^2.1.0" 1402 | }, 1403 | "engines": { 1404 | "node": ">=6" 1405 | }, 1406 | "funding": { 1407 | "url": "https://github.com/sponsors/sindresorhus" 1408 | } 1409 | }, 1410 | "node_modules/path-is-absolute": { 1411 | "version": "1.0.1", 1412 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1413 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1414 | "dev": true, 1415 | "engines": { 1416 | "node": ">=0.10.0" 1417 | } 1418 | }, 1419 | "node_modules/path-key": { 1420 | "version": "3.1.1", 1421 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1422 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1423 | "dev": true, 1424 | "engines": { 1425 | "node": ">=8" 1426 | } 1427 | }, 1428 | "node_modules/path-type": { 1429 | "version": "4.0.0", 1430 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", 1431 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", 1432 | "dev": true, 1433 | "engines": { 1434 | "node": ">=8" 1435 | } 1436 | }, 1437 | "node_modules/picomatch": { 1438 | "version": "2.3.1", 1439 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1440 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1441 | "dev": true, 1442 | "engines": { 1443 | "node": ">=8.6" 1444 | }, 1445 | "funding": { 1446 | "url": "https://github.com/sponsors/jonschlinkert" 1447 | } 1448 | }, 1449 | "node_modules/pirates": { 1450 | "version": "4.0.6", 1451 | "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", 1452 | "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", 1453 | "dev": true, 1454 | "engines": { 1455 | "node": ">= 6" 1456 | } 1457 | }, 1458 | "node_modules/postcss-load-config": { 1459 | "version": "4.0.2", 1460 | "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", 1461 | "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", 1462 | "dev": true, 1463 | "funding": [ 1464 | { 1465 | "type": "opencollective", 1466 | "url": "https://opencollective.com/postcss/" 1467 | }, 1468 | { 1469 | "type": "github", 1470 | "url": "https://github.com/sponsors/ai" 1471 | } 1472 | ], 1473 | "dependencies": { 1474 | "lilconfig": "^3.0.0", 1475 | "yaml": "^2.3.4" 1476 | }, 1477 | "engines": { 1478 | "node": ">= 14" 1479 | }, 1480 | "peerDependencies": { 1481 | "postcss": ">=8.0.9", 1482 | "ts-node": ">=9.0.0" 1483 | }, 1484 | "peerDependenciesMeta": { 1485 | "postcss": { 1486 | "optional": true 1487 | }, 1488 | "ts-node": { 1489 | "optional": true 1490 | } 1491 | } 1492 | }, 1493 | "node_modules/preact": { 1494 | "version": "10.19.2", 1495 | "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.2.tgz", 1496 | "integrity": "sha512-UA9DX/OJwv6YwP9Vn7Ti/vF80XL+YA5H2l7BpCtUr3ya8LWHFzpiO5R+N7dN16ujpIxhekRFuOOF82bXX7K/lg==", 1497 | "funding": { 1498 | "type": "opencollective", 1499 | "url": "https://opencollective.com/preact" 1500 | } 1501 | }, 1502 | "node_modules/punycode": { 1503 | "version": "2.3.1", 1504 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1505 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1506 | "dev": true, 1507 | "engines": { 1508 | "node": ">=6" 1509 | } 1510 | }, 1511 | "node_modules/queue-microtask": { 1512 | "version": "1.2.3", 1513 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 1514 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 1515 | "dev": true, 1516 | "funding": [ 1517 | { 1518 | "type": "github", 1519 | "url": "https://github.com/sponsors/feross" 1520 | }, 1521 | { 1522 | "type": "patreon", 1523 | "url": "https://www.patreon.com/feross" 1524 | }, 1525 | { 1526 | "type": "consulting", 1527 | "url": "https://feross.org/support" 1528 | } 1529 | ] 1530 | }, 1531 | "node_modules/readdirp": { 1532 | "version": "3.6.0", 1533 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 1534 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 1535 | "dev": true, 1536 | "dependencies": { 1537 | "picomatch": "^2.2.1" 1538 | }, 1539 | "engines": { 1540 | "node": ">=8.10.0" 1541 | } 1542 | }, 1543 | "node_modules/resolve-from": { 1544 | "version": "5.0.0", 1545 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", 1546 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", 1547 | "dev": true, 1548 | "engines": { 1549 | "node": ">=8" 1550 | } 1551 | }, 1552 | "node_modules/reusify": { 1553 | "version": "1.0.4", 1554 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 1555 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 1556 | "dev": true, 1557 | "engines": { 1558 | "iojs": ">=1.0.0", 1559 | "node": ">=0.10.0" 1560 | } 1561 | }, 1562 | "node_modules/rollup": { 1563 | "version": "4.6.1", 1564 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.6.1.tgz", 1565 | "integrity": "sha512-jZHaZotEHQaHLgKr8JnQiDT1rmatjgKlMekyksz+yk9jt/8z9quNjnKNRoaM0wd9DC2QKXjmWWuDYtM3jfF8pQ==", 1566 | "dev": true, 1567 | "bin": { 1568 | "rollup": "dist/bin/rollup" 1569 | }, 1570 | "engines": { 1571 | "node": ">=18.0.0", 1572 | "npm": ">=8.0.0" 1573 | }, 1574 | "optionalDependencies": { 1575 | "@rollup/rollup-android-arm-eabi": "4.6.1", 1576 | "@rollup/rollup-android-arm64": "4.6.1", 1577 | "@rollup/rollup-darwin-arm64": "4.6.1", 1578 | "@rollup/rollup-darwin-x64": "4.6.1", 1579 | "@rollup/rollup-linux-arm-gnueabihf": "4.6.1", 1580 | "@rollup/rollup-linux-arm64-gnu": "4.6.1", 1581 | "@rollup/rollup-linux-arm64-musl": "4.6.1", 1582 | "@rollup/rollup-linux-x64-gnu": "4.6.1", 1583 | "@rollup/rollup-linux-x64-musl": "4.6.1", 1584 | "@rollup/rollup-win32-arm64-msvc": "4.6.1", 1585 | "@rollup/rollup-win32-ia32-msvc": "4.6.1", 1586 | "@rollup/rollup-win32-x64-msvc": "4.6.1", 1587 | "fsevents": "~2.3.2" 1588 | } 1589 | }, 1590 | "node_modules/run-parallel": { 1591 | "version": "1.2.0", 1592 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 1593 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 1594 | "dev": true, 1595 | "funding": [ 1596 | { 1597 | "type": "github", 1598 | "url": "https://github.com/sponsors/feross" 1599 | }, 1600 | { 1601 | "type": "patreon", 1602 | "url": "https://www.patreon.com/feross" 1603 | }, 1604 | { 1605 | "type": "consulting", 1606 | "url": "https://feross.org/support" 1607 | } 1608 | ], 1609 | "dependencies": { 1610 | "queue-microtask": "^1.2.2" 1611 | } 1612 | }, 1613 | "node_modules/shebang-command": { 1614 | "version": "2.0.0", 1615 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1616 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1617 | "dev": true, 1618 | "dependencies": { 1619 | "shebang-regex": "^3.0.0" 1620 | }, 1621 | "engines": { 1622 | "node": ">=8" 1623 | } 1624 | }, 1625 | "node_modules/shebang-regex": { 1626 | "version": "3.0.0", 1627 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1628 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1629 | "dev": true, 1630 | "engines": { 1631 | "node": ">=8" 1632 | } 1633 | }, 1634 | "node_modules/signal-exit": { 1635 | "version": "3.0.7", 1636 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", 1637 | "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", 1638 | "dev": true 1639 | }, 1640 | "node_modules/slash": { 1641 | "version": "3.0.0", 1642 | "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", 1643 | "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", 1644 | "dev": true, 1645 | "engines": { 1646 | "node": ">=8" 1647 | } 1648 | }, 1649 | "node_modules/source-map": { 1650 | "version": "0.8.0-beta.0", 1651 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", 1652 | "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", 1653 | "dev": true, 1654 | "dependencies": { 1655 | "whatwg-url": "^7.0.0" 1656 | }, 1657 | "engines": { 1658 | "node": ">= 8" 1659 | } 1660 | }, 1661 | "node_modules/strip-final-newline": { 1662 | "version": "2.0.0", 1663 | "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", 1664 | "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", 1665 | "dev": true, 1666 | "engines": { 1667 | "node": ">=6" 1668 | } 1669 | }, 1670 | "node_modules/sucrase": { 1671 | "version": "3.34.0", 1672 | "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", 1673 | "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", 1674 | "dev": true, 1675 | "dependencies": { 1676 | "@jridgewell/gen-mapping": "^0.3.2", 1677 | "commander": "^4.0.0", 1678 | "glob": "7.1.6", 1679 | "lines-and-columns": "^1.1.6", 1680 | "mz": "^2.7.0", 1681 | "pirates": "^4.0.1", 1682 | "ts-interface-checker": "^0.1.9" 1683 | }, 1684 | "bin": { 1685 | "sucrase": "bin/sucrase", 1686 | "sucrase-node": "bin/sucrase-node" 1687 | }, 1688 | "engines": { 1689 | "node": ">=8" 1690 | } 1691 | }, 1692 | "node_modules/thenify": { 1693 | "version": "3.3.1", 1694 | "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", 1695 | "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", 1696 | "dev": true, 1697 | "dependencies": { 1698 | "any-promise": "^1.0.0" 1699 | } 1700 | }, 1701 | "node_modules/thenify-all": { 1702 | "version": "1.6.0", 1703 | "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", 1704 | "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", 1705 | "dev": true, 1706 | "dependencies": { 1707 | "thenify": ">= 3.1.0 < 4" 1708 | }, 1709 | "engines": { 1710 | "node": ">=0.8" 1711 | } 1712 | }, 1713 | "node_modules/to-regex-range": { 1714 | "version": "5.0.1", 1715 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1716 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1717 | "dev": true, 1718 | "dependencies": { 1719 | "is-number": "^7.0.0" 1720 | }, 1721 | "engines": { 1722 | "node": ">=8.0" 1723 | } 1724 | }, 1725 | "node_modules/tr46": { 1726 | "version": "1.0.1", 1727 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", 1728 | "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", 1729 | "dev": true, 1730 | "dependencies": { 1731 | "punycode": "^2.1.0" 1732 | } 1733 | }, 1734 | "node_modules/tree-kill": { 1735 | "version": "1.2.2", 1736 | "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", 1737 | "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", 1738 | "dev": true, 1739 | "bin": { 1740 | "tree-kill": "cli.js" 1741 | } 1742 | }, 1743 | "node_modules/ts-interface-checker": { 1744 | "version": "0.1.13", 1745 | "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", 1746 | "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", 1747 | "dev": true 1748 | }, 1749 | "node_modules/ts-node": { 1750 | "version": "10.9.1", 1751 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", 1752 | "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", 1753 | "dev": true, 1754 | "dependencies": { 1755 | "@cspotcode/source-map-support": "^0.8.0", 1756 | "@tsconfig/node10": "^1.0.7", 1757 | "@tsconfig/node12": "^1.0.7", 1758 | "@tsconfig/node14": "^1.0.0", 1759 | "@tsconfig/node16": "^1.0.2", 1760 | "acorn": "^8.4.1", 1761 | "acorn-walk": "^8.1.1", 1762 | "arg": "^4.1.0", 1763 | "create-require": "^1.1.0", 1764 | "diff": "^4.0.1", 1765 | "make-error": "^1.1.1", 1766 | "v8-compile-cache-lib": "^3.0.1", 1767 | "yn": "3.1.1" 1768 | }, 1769 | "bin": { 1770 | "ts-node": "dist/bin.js", 1771 | "ts-node-cwd": "dist/bin-cwd.js", 1772 | "ts-node-esm": "dist/bin-esm.js", 1773 | "ts-node-script": "dist/bin-script.js", 1774 | "ts-node-transpile-only": "dist/bin-transpile.js", 1775 | "ts-script": "dist/bin-script-deprecated.js" 1776 | }, 1777 | "peerDependencies": { 1778 | "@swc/core": ">=1.2.50", 1779 | "@swc/wasm": ">=1.2.50", 1780 | "@types/node": "*", 1781 | "typescript": ">=2.7" 1782 | }, 1783 | "peerDependenciesMeta": { 1784 | "@swc/core": { 1785 | "optional": true 1786 | }, 1787 | "@swc/wasm": { 1788 | "optional": true 1789 | } 1790 | } 1791 | }, 1792 | "node_modules/tsup": { 1793 | "version": "8.0.1", 1794 | "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.0.1.tgz", 1795 | "integrity": "sha512-hvW7gUSG96j53ZTSlT4j/KL0q1Q2l6TqGBFc6/mu/L46IoNWqLLUzLRLP1R8Q7xrJTmkDxxDoojV5uCVs1sVOg==", 1796 | "dev": true, 1797 | "dependencies": { 1798 | "bundle-require": "^4.0.0", 1799 | "cac": "^6.7.12", 1800 | "chokidar": "^3.5.1", 1801 | "debug": "^4.3.1", 1802 | "esbuild": "^0.19.2", 1803 | "execa": "^5.0.0", 1804 | "globby": "^11.0.3", 1805 | "joycon": "^3.0.1", 1806 | "postcss-load-config": "^4.0.1", 1807 | "resolve-from": "^5.0.0", 1808 | "rollup": "^4.0.2", 1809 | "source-map": "0.8.0-beta.0", 1810 | "sucrase": "^3.20.3", 1811 | "tree-kill": "^1.2.2" 1812 | }, 1813 | "bin": { 1814 | "tsup": "dist/cli-default.js", 1815 | "tsup-node": "dist/cli-node.js" 1816 | }, 1817 | "engines": { 1818 | "node": ">=18" 1819 | }, 1820 | "peerDependencies": { 1821 | "@microsoft/api-extractor": "^7.36.0", 1822 | "@swc/core": "^1", 1823 | "postcss": "^8.4.12", 1824 | "typescript": ">=4.5.0" 1825 | }, 1826 | "peerDependenciesMeta": { 1827 | "@microsoft/api-extractor": { 1828 | "optional": true 1829 | }, 1830 | "@swc/core": { 1831 | "optional": true 1832 | }, 1833 | "postcss": { 1834 | "optional": true 1835 | }, 1836 | "typescript": { 1837 | "optional": true 1838 | } 1839 | } 1840 | }, 1841 | "node_modules/typescript": { 1842 | "version": "5.3.2", 1843 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", 1844 | "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", 1845 | "dev": true, 1846 | "bin": { 1847 | "tsc": "bin/tsc", 1848 | "tsserver": "bin/tsserver" 1849 | }, 1850 | "engines": { 1851 | "node": ">=14.17" 1852 | } 1853 | }, 1854 | "node_modules/undici-types": { 1855 | "version": "5.26.5", 1856 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 1857 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 1858 | "dev": true, 1859 | "peer": true 1860 | }, 1861 | "node_modules/v8-compile-cache-lib": { 1862 | "version": "3.0.1", 1863 | "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", 1864 | "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", 1865 | "dev": true 1866 | }, 1867 | "node_modules/webidl-conversions": { 1868 | "version": "4.0.2", 1869 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", 1870 | "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", 1871 | "dev": true 1872 | }, 1873 | "node_modules/whatwg-url": { 1874 | "version": "7.1.0", 1875 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", 1876 | "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", 1877 | "dev": true, 1878 | "dependencies": { 1879 | "lodash.sortby": "^4.7.0", 1880 | "tr46": "^1.0.1", 1881 | "webidl-conversions": "^4.0.2" 1882 | } 1883 | }, 1884 | "node_modules/which": { 1885 | "version": "2.0.2", 1886 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1887 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1888 | "dev": true, 1889 | "dependencies": { 1890 | "isexe": "^2.0.0" 1891 | }, 1892 | "bin": { 1893 | "node-which": "bin/node-which" 1894 | }, 1895 | "engines": { 1896 | "node": ">= 8" 1897 | } 1898 | }, 1899 | "node_modules/wildcard": { 1900 | "version": "1.1.2", 1901 | "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-1.1.2.tgz", 1902 | "integrity": "sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==" 1903 | }, 1904 | "node_modules/wrappy": { 1905 | "version": "1.0.2", 1906 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1907 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1908 | "dev": true 1909 | }, 1910 | "node_modules/yaml": { 1911 | "version": "2.3.4", 1912 | "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", 1913 | "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", 1914 | "dev": true, 1915 | "engines": { 1916 | "node": ">= 14" 1917 | } 1918 | }, 1919 | "node_modules/yn": { 1920 | "version": "3.1.1", 1921 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 1922 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", 1923 | "dev": true, 1924 | "engines": { 1925 | "node": ">=6" 1926 | } 1927 | } 1928 | } 1929 | } 1930 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "uppy-encrypt", 3 | "version": "1.0.2", 4 | "description": "Uppy plugin to encrypt and decrypt files in the browser before upload using libsodium-wrappers", 5 | "type": "module", 6 | "main": "./dist/index.cjs", 7 | "module": "./dist/index.js", 8 | "types": "./dist/index.d.ts", 9 | "exports": { 10 | ".": { 11 | "require": "./dist/index.cjs", 12 | "import": "./dist/index.js", 13 | "types": "./dist/index.d.ts" 14 | } 15 | }, 16 | "files": [ 17 | "dist" 18 | ], 19 | "scripts": { 20 | "build": "tsup", 21 | "test": "echo \"Error: no test specified\" && exit 1" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "git+https://github.com/0sumcode/uppy-encrypt.git" 26 | }, 27 | "keywords": [ 28 | "uppy", 29 | "encrypt", 30 | "decrypt", 31 | "libsodium" 32 | ], 33 | "author": "Dan Stevens", 34 | "license": "MIT", 35 | "bugs": { 36 | "url": "https://github.com/0sumcode/uppy-encrypt/issues" 37 | }, 38 | "homepage": "https://github.com/0sumcode/uppy-encrypt#readme", 39 | "devDependencies": { 40 | "ts-node": "^10.9.1", 41 | "tsup": "^8.0.1", 42 | "typescript": "^5.3.2" 43 | }, 44 | "dependencies": { 45 | "@types/libsodium-wrappers-sumo": "^0.7.8", 46 | "@uppy/core": "^3.7.1", 47 | "libsodium-wrappers-sumo": "^0.7.13" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/UppyDecrypt.ts: -------------------------------------------------------------------------------- 1 | import _sodium from 'libsodium-wrappers-sumo'; 2 | import { CHUNK_SIZE, SIGNATURE } from './constants'; 3 | 4 | export interface DecryptedMetaData { 5 | name: string; 6 | type?: string; 7 | } 8 | 9 | // Init Sodium 10 | let sodium: typeof _sodium; 11 | (async () => { 12 | await _sodium.ready; 13 | sodium = _sodium; 14 | })(); 15 | 16 | export default class UppyDecrypt { 17 | private key: Uint8Array; 18 | private state: _sodium.StateAddress; 19 | private stream: ReadableStream; 20 | private streamController: ReadableStreamDefaultController | undefined; 21 | private contentType: string; 22 | 23 | private index = 0; 24 | 25 | constructor(password: string, salt: string, header: string) { 26 | const saltUint = sodium.from_base64(salt, sodium.base64_variants.URLSAFE_NO_PADDING); 27 | const headerUint = sodium.from_base64(header, sodium.base64_variants.URLSAFE_NO_PADDING); 28 | 29 | this.streamController; 30 | this.stream = new ReadableStream({ 31 | start: (controller) => { 32 | this.streamController = controller; 33 | }, 34 | }); 35 | this.contentType = ''; // Defined if/when meta-data is decrypted 36 | 37 | this.key = sodium.crypto_pwhash( 38 | sodium.crypto_secretstream_xchacha20poly1305_KEYBYTES, 39 | password, 40 | saltUint, 41 | sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE, 42 | sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE, 43 | sodium.crypto_pwhash_ALG_ARGON2ID13 44 | ); 45 | 46 | this.state = sodium.crypto_secretstream_xchacha20poly1305_init_pull(headerUint, this.key); 47 | 48 | this.index = SIGNATURE.length + saltUint.length + headerUint.length; 49 | } 50 | 51 | /** 52 | * Validates that the provided password is correct 53 | * @param hash The hash value of the password created during UppyEncrypt 54 | * @param password The user-provided password 55 | * @returns {bool} true if correct password 56 | */ 57 | static verifyPassword(hash: string, password: string) { 58 | return sodium.crypto_pwhash_str_verify(hash, password); 59 | } 60 | 61 | /** 62 | * Decrypts the provided file 63 | * @param file Blob of encryptyed file 64 | * @returns Decrypted file as a blob 65 | */ 66 | async decryptFile(file: Blob) { 67 | if (!this.streamController) { 68 | throw new Error('Encryption stream does not exist'); 69 | } 70 | 71 | while (this.index < file.size) { 72 | const chunk = await file.slice(this.index, this.index + CHUNK_SIZE + sodium.crypto_secretstream_xchacha20poly1305_ABYTES).arrayBuffer(); 73 | const decryptedChunk = sodium.crypto_secretstream_xchacha20poly1305_pull(this.state, new Uint8Array(chunk)); 74 | 75 | this.streamController.enqueue(decryptedChunk.message); 76 | 77 | this.index += CHUNK_SIZE + sodium.crypto_secretstream_xchacha20poly1305_ABYTES; 78 | } 79 | 80 | this.streamController.close(); 81 | 82 | const response = new Response(this.stream, { headers: { 'Content-Type': this.contentType } }); 83 | return response.blob(); 84 | } 85 | 86 | /** 87 | * 88 | * @param header Header created during encryption of the meta data 89 | * @param meta Encrypted meta data string 90 | * @returns object of the decrypted meta data 91 | */ 92 | getDecryptedMetaData(header: string, meta: string) { 93 | // Init fresh state 94 | const state = sodium.crypto_secretstream_xchacha20poly1305_init_pull(sodium.from_base64(header, sodium.base64_variants.URLSAFE_NO_PADDING), this.key); 95 | const decryptedChunk = sodium.crypto_secretstream_xchacha20poly1305_pull(state, sodium.from_base64(meta, sodium.base64_variants.URLSAFE_NO_PADDING)); 96 | 97 | if (!decryptedChunk) throw new Error('Unable to decrypt meta data'); 98 | const decryptedMeta = JSON.parse(new TextDecoder().decode(decryptedChunk.message)) as DecryptedMetaData; 99 | if (decryptedMeta.type) this.contentType = decryptedMeta.type; 100 | return decryptedMeta; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/UppyEncrypt.ts: -------------------------------------------------------------------------------- 1 | import type { Uppy, UppyFile } from '@uppy/core'; 2 | import _sodium from 'libsodium-wrappers-sumo'; 3 | import { CHUNK_SIZE, SIGNATURE } from './constants'; 4 | 5 | // Init Sodium 6 | let sodium: typeof _sodium; 7 | (async () => { 8 | await _sodium.ready; 9 | sodium = _sodium; 10 | })(); 11 | 12 | export default class UppyEncrypt { 13 | private uppy: Uppy; 14 | private password: string; 15 | private salt: Uint8Array; 16 | private key: Uint8Array; 17 | private state: _sodium.StateAddress; 18 | private header: Uint8Array; 19 | private file: UppyFile, Record>; 20 | private stream: ReadableStream; 21 | private streamController: ReadableStreamDefaultController | undefined; 22 | private streamCanceled = false; 23 | 24 | private index = 0; 25 | 26 | constructor(uppy: Uppy, file: UppyFile, Record>, password: string) { 27 | this.uppy = uppy; 28 | this.file = file; 29 | this.password = password; 30 | 31 | // Set Uppy event handlers that effect the encryption process 32 | uppy.on('cancel-all', () => { 33 | this.streamCanceled = true; 34 | }); 35 | 36 | this.streamController; 37 | this.stream = new ReadableStream({ 38 | start: (controller) => { 39 | this.streamController = controller; 40 | }, 41 | }); 42 | 43 | this.salt = sodium.randombytes_buf(sodium.crypto_pwhash_SALTBYTES); 44 | this.key = sodium.crypto_pwhash( 45 | sodium.crypto_secretstream_xchacha20poly1305_KEYBYTES, 46 | password, 47 | this.salt, 48 | sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE, 49 | sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE, 50 | sodium.crypto_pwhash_ALG_ARGON2ID13 51 | ); 52 | 53 | const res = sodium.crypto_secretstream_xchacha20poly1305_init_push(this.key); 54 | this.state = res.state; 55 | this.header = res.header; 56 | } 57 | 58 | /** 59 | * Helper function that generate a random password 60 | */ 61 | static generatePassword() { 62 | return sodium.to_base64(sodium.randombytes_buf(16), sodium.base64_variants.URLSAFE_NO_PADDING); 63 | } 64 | 65 | /** 66 | * Encrypts the file 67 | */ 68 | async encryptFile() { 69 | if (!this.streamController) { 70 | throw new Error('Encryption stream does not exist'); 71 | } 72 | 73 | while (this.index < this.file.size) { 74 | if (this.streamCanceled) { 75 | await this.stream.cancel(); 76 | return false; 77 | } 78 | 79 | // If first chunk 80 | if (this.index === 0) { 81 | this.streamController.enqueue(new Uint8Array(new TextEncoder().encode(SIGNATURE))); 82 | this.streamController.enqueue(this.salt); 83 | this.streamController.enqueue(this.header); 84 | } 85 | 86 | const tag = 87 | this.index + CHUNK_SIZE < this.file.size 88 | ? sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE 89 | : sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL; 90 | 91 | const chunk = await this.file.data.slice(this.index, this.index + CHUNK_SIZE).arrayBuffer(); 92 | const encryptedChunk = sodium.crypto_secretstream_xchacha20poly1305_push(this.state, new Uint8Array(chunk), null, tag); 93 | 94 | this.streamController.enqueue(new Uint8Array(encryptedChunk)); 95 | 96 | this.uppy.emit('preprocess-progress', this.file, { 97 | mode: 'determinate', 98 | message: `Encrypting ${this.file.name}...`, 99 | value: this.index / this.file.size, 100 | }); 101 | 102 | this.index += CHUNK_SIZE; 103 | } 104 | 105 | this.uppy.emit('preprocess-progress', this.file, { 106 | mode: 'determinate', 107 | message: `Encrypting ${this.file.name}...`, 108 | value: 1, 109 | }); 110 | 111 | this.streamController.close(); 112 | 113 | return true; 114 | } 115 | 116 | /** 117 | * Creates and returns a Blob of the encrypted file 118 | */ 119 | async getEncryptedFile() { 120 | const response = new Response(this.stream); 121 | return response.blob(); 122 | } 123 | 124 | /** 125 | * Returns an encrypted representation of the file's metadata (name, content-type) 126 | * header: base64-encoded header data 127 | * meta: Encrypted JSON string of the file's metadata, base64-encoded 128 | */ 129 | getEncryptMetaData() { 130 | // Init fresh state 131 | const res = sodium.crypto_secretstream_xchacha20poly1305_init_push(this.key); 132 | 133 | const metaJson = JSON.stringify({ name: this.file.meta.name, type: this.file.meta.type || null }); 134 | const encryptedChunk = sodium.crypto_secretstream_xchacha20poly1305_push( 135 | res.state, 136 | new Uint8Array(new TextEncoder().encode(metaJson)), 137 | null, 138 | sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL 139 | ); 140 | 141 | return { 142 | header: sodium.to_base64(res.header, sodium.base64_variants.URLSAFE_NO_PADDING), 143 | data: sodium.to_base64(encryptedChunk, sodium.base64_variants.URLSAFE_NO_PADDING), 144 | }; 145 | } 146 | 147 | /** 148 | * Returns a hash of the password base64-encoded 149 | * This data is safe to store in a database, etc 150 | */ 151 | getPasswordHash() { 152 | return sodium.crypto_pwhash_str(this.password, sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE, sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE); 153 | } 154 | 155 | /** 156 | * Returns the header base64-encoded 157 | * This data is safe to store in a database, etc 158 | */ 159 | getHeader() { 160 | return sodium.to_base64(this.header, sodium.base64_variants.URLSAFE_NO_PADDING); 161 | } 162 | 163 | /** 164 | * Returns the salt base64-encoded 165 | * This data is safe to store in a database, etc 166 | */ 167 | getSalt() { 168 | return sodium.to_base64(this.salt, sodium.base64_variants.URLSAFE_NO_PADDING); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | export const CHUNK_SIZE = 64 * 1024 * 1024; 2 | export const SIGNATURE = 'uppyencrypt'; 3 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import UppyEncrypt from './UppyEncrypt'; 2 | import UppyDecrypt, { type DecryptedMetaData } from './UppyDecrypt'; 3 | import _sodium from 'libsodium-wrappers-sumo'; 4 | import { BasePlugin, type DefaultPluginOptions, Uppy } from '@uppy/core'; 5 | 6 | interface UppyEncryptPluginOptions extends DefaultPluginOptions { 7 | password: string | null; 8 | } 9 | 10 | // Sodium is initialized automatically within UppyEncrypt / UppyDecrypt 11 | // Optionally call this to ensure initialization 12 | let sodiumIsReady = false; 13 | export const uppyEncryptReady = async () => { 14 | if (!sodiumIsReady) { 15 | await _sodium.ready; 16 | sodiumIsReady = true; 17 | } 18 | }; 19 | 20 | export class UppyEncryptPlugin extends BasePlugin { 21 | opts: UppyEncryptPluginOptions; 22 | 23 | constructor(uppy: Uppy, opts?: UppyEncryptPluginOptions | undefined) { 24 | super(uppy, opts); 25 | this.id = opts?.id ?? 'UppyEncryptPlugin'; 26 | this.type = 'modifier'; 27 | 28 | const defaultOptions = { 29 | password: null, 30 | }; 31 | this.opts = { ...defaultOptions, ...opts }; 32 | 33 | this.encryptFiles = this.encryptFiles.bind(this); 34 | } 35 | 36 | async encryptFiles(fileIds: string[]) { 37 | // Generate a password here if none is already set 38 | this.opts.password = this.opts.password || UppyEncrypt.generatePassword(); 39 | 40 | // Add password to meta data so it can be referenced externally 41 | this.uppy.setMeta({ password: this.opts.password }); 42 | 43 | for (const fileId of fileIds) { 44 | const file = this.uppy.getFile(fileId); 45 | const enc = new UppyEncrypt(this.uppy, file, this.opts.password); 46 | if (await enc.encryptFile()) { 47 | this.uppy.emit('preprocess-complete', file); 48 | let blob = await enc.getEncryptedFile(); 49 | this.uppy.setFileState(fileId, { 50 | type: 'application/octet-stream', 51 | data: blob, 52 | size: blob.size, 53 | }); 54 | 55 | this.uppy.setFileMeta(fileId, { 56 | name: `${file.name}.enc`, 57 | type: 'application/octet-stream', 58 | encryption: { 59 | salt: enc.getSalt(), 60 | header: enc.getHeader(), 61 | hash: enc.getPasswordHash(), 62 | meta: enc.getEncryptMetaData(), 63 | }, 64 | }); 65 | } 66 | } 67 | } 68 | 69 | install() { 70 | this.uppy.addPreProcessor(this.encryptFiles); 71 | } 72 | 73 | uninstall() { 74 | this.uppy.removePreProcessor(this.encryptFiles); 75 | } 76 | } 77 | 78 | export { UppyEncrypt, UppyDecrypt, DecryptedMetaData }; 79 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "ESNext", 4 | "moduleResolution": "Node", 5 | "target": "ES2015", 6 | "sourceMap": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "esModuleInterop": true, 10 | "outDir": "dist", 11 | "removeComments": true, 12 | "declaration": true 13 | }, 14 | "include": ["types/**/*", "src/**/*"], 15 | "exclude": ["node_modules", "dist"] 16 | } 17 | -------------------------------------------------------------------------------- /tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: ['src/index.ts'], 5 | format: ['cjs', 'esm'], // Build for commonJS and ESmodules 6 | dts: true, // Generate declaration file (.d.ts) 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | }); 11 | --------------------------------------------------------------------------------