wip library to store cold objects in s3, warm objects on disk, and hot objects in memory
nodejs typescript

streaming

nekomimi.pet f1cabe58 b4fd2d1c

verified
+101
example.ts
··· 265 265 await storage.invalidate('item:'); 266 266 } 267 267 268 + async function streamingExample() { 269 + console.log('\n=== Streaming Example ===\n'); 270 + 271 + const { createReadStream, statSync } = await import('node:fs'); 272 + const { pipeline } = await import('node:stream/promises'); 273 + 274 + const storage = new TieredStorage({ 275 + tiers: { 276 + hot: new MemoryStorageTier({ maxSizeBytes: 10 * 1024 * 1024 }), // 10MB 277 + warm: new DiskStorageTier({ directory: './example-cache/streaming/warm' }), 278 + cold: new S3StorageTier({ 279 + bucket: S3_BUCKET, 280 + region: S3_REGION, 281 + endpoint: S3_ENDPOINT, 282 + forcePathStyle: S3_FORCE_PATH_STYLE, 283 + credentials: 284 + AWS_ACCESS_KEY_ID && AWS_SECRET_ACCESS_KEY 285 + ? { 286 + accessKeyId: AWS_ACCESS_KEY_ID, 287 + secretAccessKey: AWS_SECRET_ACCESS_KEY, 288 + } 289 + : undefined, 290 + prefix: 'example/streaming/', 291 + }), 292 + }, 293 + compression: true, // Streams will be compressed automatically 294 + defaultTTL: 60 * 60 * 1000, // 1 hour 295 + }); 296 + 297 + // Stream a file to storage 298 + const filePath = './example-site/index.html'; 299 + const fileStats = statSync(filePath); 300 + 301 + console.log(`Streaming ${filePath} (${fileStats.size} bytes) with compression...`); 302 + 303 + const readStream = createReadStream(filePath); 304 + const result = await storage.setStream('streaming/index.html', readStream, { 305 + size: fileStats.size, 306 + mimeType: 'text/html', 307 + }); 308 + 309 + console.log(`✓ Stored with key: ${result.key}`); 310 + console.log(` Original size: ${result.metadata.size} bytes`); 311 + console.log(` Compressed: ${result.metadata.compressed}`); 312 + console.log(` Checksum (original data): ${result.metadata.checksum.slice(0, 16)}...`); 313 + console.log(` Written to tiers: ${result.tiersWritten.join(', ')}`); 314 + 315 + // Stream the file back (automatically decompressed) 316 + console.log('\nStreaming back the file (with automatic decompression)...'); 317 + 318 + const streamResult = await storage.getStream('streaming/index.html'); 319 + if (streamResult) { 320 + console.log(`✓ Streaming from: ${streamResult.source} tier`); 321 + console.log(` Metadata size: ${streamResult.metadata.size} bytes`); 322 + console.log(` Compressed in storage: ${streamResult.metadata.compressed}`); 323 + 324 + // Collect stream data to verify content 325 + const chunks: Buffer[] = []; 326 + for await (const chunk of streamResult.stream) { 327 + chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)); 328 + } 329 + const content = Buffer.concat(chunks); 330 + 331 + console.log(` Retrieved size: ${content.length} bytes`); 332 + console.log(` Content preview: ${content.toString('utf-8').slice(0, 100)}...`); 333 + 334 + // Verify the content matches the original 335 + const { readFile } = await import('node:fs/promises'); 336 + const original = await readFile(filePath); 337 + if (content.equals(original)) { 338 + console.log(' ✓ Content matches original file!'); 339 + } else { 340 + console.log(' ✗ Content does NOT match original file'); 341 + } 342 + } 343 + 344 + // Example: Stream to a writable destination (like an HTTP response) 345 + console.log('\nStreaming to destination (simulated HTTP response)...'); 346 + const streamResult2 = await storage.getStream('streaming/index.html'); 347 + if (streamResult2) { 348 + // In a real server, you would do: streamResult2.stream.pipe(res); 349 + // Here we just demonstrate the pattern 350 + const { Writable } = await import('node:stream'); 351 + let totalBytes = 0; 352 + const mockResponse = new Writable({ 353 + write(chunk, _encoding, callback) { 354 + totalBytes += chunk.length; 355 + callback(); 356 + }, 357 + }); 358 + 359 + await pipeline(streamResult2.stream, mockResponse); 360 + console.log(`✓ Streamed ${totalBytes} bytes to destination`); 361 + } 362 + 363 + // Cleanup 364 + console.log('\nCleaning up streaming example data...'); 365 + await storage.invalidate('streaming/'); 366 + } 367 + 268 368 async function promotionStrategyExample() { 269 369 console.log('\n=== Promotion Strategy Example ===\n'); 270 370 ··· 415 515 416 516 await basicExample(); 417 517 await staticSiteHostingExample(); 518 + await streamingExample(); 418 519 await bootstrapExample(); 419 520 await promotionStrategyExample(); 420 521 } catch (error: any) {
+967 -465
package-lock.json
··· 9 9 "version": "1.0.0", 10 10 "dependencies": { 11 11 "@aws-sdk/client-s3": "^3.500.0", 12 + "@aws-sdk/lib-storage": "^3.500.0", 12 13 "hono": "^4.10.7", 13 14 "mime-types": "^3.0.2", 14 15 "tiny-lru": "^11.0.0" ··· 20 21 "@typescript-eslint/eslint-plugin": "^8.48.1", 21 22 "@typescript-eslint/parser": "^8.48.1", 22 23 "eslint": "^9.39.1", 24 + "eslint-config-prettier": "^10.1.8", 25 + "eslint-plugin-prettier": "^5.5.4", 26 + "prettier": "^3.7.4", 23 27 "tsx": "^4.0.0", 24 28 "typescript": "^5.3.0", 29 + "typescript-eslint": "^8.50.0", 25 30 "vitest": "^4.0.15" 26 31 }, 27 32 "engines": { ··· 30 35 }, 31 36 "node_modules/@aws-crypto/crc32": { 32 37 "version": "5.2.0", 38 + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", 39 + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", 33 40 "license": "Apache-2.0", 34 41 "dependencies": { 35 42 "@aws-crypto/util": "^5.2.0", ··· 42 49 }, 43 50 "node_modules/@aws-crypto/crc32c": { 44 51 "version": "5.2.0", 52 + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz", 53 + "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==", 45 54 "license": "Apache-2.0", 46 55 "dependencies": { 47 56 "@aws-crypto/util": "^5.2.0", ··· 95 104 }, 96 105 "node_modules/@aws-crypto/sha256-browser": { 97 106 "version": "5.2.0", 107 + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", 108 + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", 98 109 "license": "Apache-2.0", 99 110 "dependencies": { 100 111 "@aws-crypto/sha256-js": "^5.2.0", ··· 106 117 "tslib": "^2.6.2" 107 118 } 108 119 }, 109 - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { 110 - "version": "2.3.0", 120 + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { 121 + "version": "2.2.0", 122 + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", 123 + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", 111 124 "license": "Apache-2.0", 112 125 "dependencies": { 113 - "@smithy/util-buffer-from": "^2.2.0", 114 126 "tslib": "^2.6.2" 115 127 }, 116 128 "engines": { 117 129 "node": ">=14.0.0" 118 130 } 119 131 }, 120 - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8/node_modules/@smithy/util-buffer-from": { 132 + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { 121 133 "version": "2.2.0", 134 + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", 135 + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", 122 136 "license": "Apache-2.0", 123 137 "dependencies": { 124 138 "@smithy/is-array-buffer": "^2.2.0", ··· 128 142 "node": ">=14.0.0" 129 143 } 130 144 }, 131 - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8/node_modules/@smithy/util-buffer-from/node_modules/@smithy/is-array-buffer": { 132 - "version": "2.2.0", 145 + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { 146 + "version": "2.3.0", 147 + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", 148 + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", 133 149 "license": "Apache-2.0", 134 150 "dependencies": { 151 + "@smithy/util-buffer-from": "^2.2.0", 135 152 "tslib": "^2.6.2" 136 153 }, 137 154 "engines": { ··· 140 157 }, 141 158 "node_modules/@aws-crypto/sha256-js": { 142 159 "version": "5.2.0", 160 + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", 161 + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", 143 162 "license": "Apache-2.0", 144 163 "dependencies": { 145 164 "@aws-crypto/util": "^5.2.0", ··· 199 218 } 200 219 }, 201 220 "node_modules/@aws-sdk/client-s3": { 202 - "version": "3.946.0", 221 + "version": "3.956.0", 222 + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.956.0.tgz", 223 + "integrity": "sha512-O+Z7PSY9TjaqJcZSDMvVmXBuV/jmFRJIu7ga+9XgWv4+qfjhAX2N2s4kgsRnIdjIO4xgkN3O/BugTCyjIRrIDQ==", 203 224 "license": "Apache-2.0", 225 + "peer": true, 204 226 "dependencies": { 205 227 "@aws-crypto/sha1-browser": "5.2.0", 206 228 "@aws-crypto/sha256-browser": "5.2.0", 207 229 "@aws-crypto/sha256-js": "5.2.0", 208 - "@aws-sdk/core": "3.946.0", 209 - "@aws-sdk/credential-provider-node": "3.946.0", 210 - "@aws-sdk/middleware-bucket-endpoint": "3.936.0", 211 - "@aws-sdk/middleware-expect-continue": "3.936.0", 212 - "@aws-sdk/middleware-flexible-checksums": "3.946.0", 213 - "@aws-sdk/middleware-host-header": "3.936.0", 214 - "@aws-sdk/middleware-location-constraint": "3.936.0", 215 - "@aws-sdk/middleware-logger": "3.936.0", 216 - "@aws-sdk/middleware-recursion-detection": "3.936.0", 217 - "@aws-sdk/middleware-sdk-s3": "3.946.0", 218 - "@aws-sdk/middleware-ssec": "3.936.0", 219 - "@aws-sdk/middleware-user-agent": "3.946.0", 220 - "@aws-sdk/region-config-resolver": "3.936.0", 221 - "@aws-sdk/signature-v4-multi-region": "3.946.0", 222 - "@aws-sdk/types": "3.936.0", 223 - "@aws-sdk/util-endpoints": "3.936.0", 224 - "@aws-sdk/util-user-agent-browser": "3.936.0", 225 - "@aws-sdk/util-user-agent-node": "3.946.0", 226 - "@smithy/config-resolver": "^4.4.3", 227 - "@smithy/core": "^3.18.7", 228 - "@smithy/eventstream-serde-browser": "^4.2.5", 229 - "@smithy/eventstream-serde-config-resolver": "^4.3.5", 230 - "@smithy/eventstream-serde-node": "^4.2.5", 231 - "@smithy/fetch-http-handler": "^5.3.6", 232 - "@smithy/hash-blob-browser": "^4.2.6", 233 - "@smithy/hash-node": "^4.2.5", 234 - "@smithy/hash-stream-node": "^4.2.5", 235 - "@smithy/invalid-dependency": "^4.2.5", 236 - "@smithy/md5-js": "^4.2.5", 237 - "@smithy/middleware-content-length": "^4.2.5", 238 - "@smithy/middleware-endpoint": "^4.3.14", 239 - "@smithy/middleware-retry": "^4.4.14", 240 - "@smithy/middleware-serde": "^4.2.6", 241 - "@smithy/middleware-stack": "^4.2.5", 242 - "@smithy/node-config-provider": "^4.3.5", 243 - "@smithy/node-http-handler": "^4.4.5", 244 - "@smithy/protocol-http": "^5.3.5", 245 - "@smithy/smithy-client": "^4.9.10", 246 - "@smithy/types": "^4.9.0", 247 - "@smithy/url-parser": "^4.2.5", 230 + "@aws-sdk/core": "3.956.0", 231 + "@aws-sdk/credential-provider-node": "3.956.0", 232 + "@aws-sdk/middleware-bucket-endpoint": "3.956.0", 233 + "@aws-sdk/middleware-expect-continue": "3.956.0", 234 + "@aws-sdk/middleware-flexible-checksums": "3.956.0", 235 + "@aws-sdk/middleware-host-header": "3.956.0", 236 + "@aws-sdk/middleware-location-constraint": "3.956.0", 237 + "@aws-sdk/middleware-logger": "3.956.0", 238 + "@aws-sdk/middleware-recursion-detection": "3.956.0", 239 + "@aws-sdk/middleware-sdk-s3": "3.956.0", 240 + "@aws-sdk/middleware-ssec": "3.956.0", 241 + "@aws-sdk/middleware-user-agent": "3.956.0", 242 + "@aws-sdk/region-config-resolver": "3.956.0", 243 + "@aws-sdk/signature-v4-multi-region": "3.956.0", 244 + "@aws-sdk/types": "3.956.0", 245 + "@aws-sdk/util-endpoints": "3.956.0", 246 + "@aws-sdk/util-user-agent-browser": "3.956.0", 247 + "@aws-sdk/util-user-agent-node": "3.956.0", 248 + "@smithy/config-resolver": "^4.4.5", 249 + "@smithy/core": "^3.20.0", 250 + "@smithy/eventstream-serde-browser": "^4.2.7", 251 + "@smithy/eventstream-serde-config-resolver": "^4.3.7", 252 + "@smithy/eventstream-serde-node": "^4.2.7", 253 + "@smithy/fetch-http-handler": "^5.3.8", 254 + "@smithy/hash-blob-browser": "^4.2.8", 255 + "@smithy/hash-node": "^4.2.7", 256 + "@smithy/hash-stream-node": "^4.2.7", 257 + "@smithy/invalid-dependency": "^4.2.7", 258 + "@smithy/md5-js": "^4.2.7", 259 + "@smithy/middleware-content-length": "^4.2.7", 260 + "@smithy/middleware-endpoint": "^4.4.1", 261 + "@smithy/middleware-retry": "^4.4.17", 262 + "@smithy/middleware-serde": "^4.2.8", 263 + "@smithy/middleware-stack": "^4.2.7", 264 + "@smithy/node-config-provider": "^4.3.7", 265 + "@smithy/node-http-handler": "^4.4.7", 266 + "@smithy/protocol-http": "^5.3.7", 267 + "@smithy/smithy-client": "^4.10.2", 268 + "@smithy/types": "^4.11.0", 269 + "@smithy/url-parser": "^4.2.7", 248 270 "@smithy/util-base64": "^4.3.0", 249 271 "@smithy/util-body-length-browser": "^4.2.0", 250 272 "@smithy/util-body-length-node": "^4.2.1", 251 - "@smithy/util-defaults-mode-browser": "^4.3.13", 252 - "@smithy/util-defaults-mode-node": "^4.2.16", 253 - "@smithy/util-endpoints": "^3.2.5", 254 - "@smithy/util-middleware": "^4.2.5", 255 - "@smithy/util-retry": "^4.2.5", 256 - "@smithy/util-stream": "^4.5.6", 273 + "@smithy/util-defaults-mode-browser": "^4.3.16", 274 + "@smithy/util-defaults-mode-node": "^4.2.19", 275 + "@smithy/util-endpoints": "^3.2.7", 276 + "@smithy/util-middleware": "^4.2.7", 277 + "@smithy/util-retry": "^4.2.7", 278 + "@smithy/util-stream": "^4.5.8", 257 279 "@smithy/util-utf8": "^4.2.0", 258 - "@smithy/util-waiter": "^4.2.5", 280 + "@smithy/util-waiter": "^4.2.7", 259 281 "tslib": "^2.6.2" 260 282 }, 261 283 "engines": { ··· 263 285 } 264 286 }, 265 287 "node_modules/@aws-sdk/client-sso": { 266 - "version": "3.946.0", 288 + "version": "3.956.0", 289 + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.956.0.tgz", 290 + "integrity": "sha512-TCxCa9B1IMILvk/7sig0fRQzff+M2zBQVZGWOJL8SAZq/gfElIMAf/nYjQwMhXjyq8PFDRGm4GN8ZhNKPeNleQ==", 267 291 "license": "Apache-2.0", 268 292 "dependencies": { 269 293 "@aws-crypto/sha256-browser": "5.2.0", 270 294 "@aws-crypto/sha256-js": "5.2.0", 271 - "@aws-sdk/core": "3.946.0", 272 - "@aws-sdk/middleware-host-header": "3.936.0", 273 - "@aws-sdk/middleware-logger": "3.936.0", 274 - "@aws-sdk/middleware-recursion-detection": "3.936.0", 275 - "@aws-sdk/middleware-user-agent": "3.946.0", 276 - "@aws-sdk/region-config-resolver": "3.936.0", 277 - "@aws-sdk/types": "3.936.0", 278 - "@aws-sdk/util-endpoints": "3.936.0", 279 - "@aws-sdk/util-user-agent-browser": "3.936.0", 280 - "@aws-sdk/util-user-agent-node": "3.946.0", 281 - "@smithy/config-resolver": "^4.4.3", 282 - "@smithy/core": "^3.18.7", 283 - "@smithy/fetch-http-handler": "^5.3.6", 284 - "@smithy/hash-node": "^4.2.5", 285 - "@smithy/invalid-dependency": "^4.2.5", 286 - "@smithy/middleware-content-length": "^4.2.5", 287 - "@smithy/middleware-endpoint": "^4.3.14", 288 - "@smithy/middleware-retry": "^4.4.14", 289 - "@smithy/middleware-serde": "^4.2.6", 290 - "@smithy/middleware-stack": "^4.2.5", 291 - "@smithy/node-config-provider": "^4.3.5", 292 - "@smithy/node-http-handler": "^4.4.5", 293 - "@smithy/protocol-http": "^5.3.5", 294 - "@smithy/smithy-client": "^4.9.10", 295 - "@smithy/types": "^4.9.0", 296 - "@smithy/url-parser": "^4.2.5", 295 + "@aws-sdk/core": "3.956.0", 296 + "@aws-sdk/middleware-host-header": "3.956.0", 297 + "@aws-sdk/middleware-logger": "3.956.0", 298 + "@aws-sdk/middleware-recursion-detection": "3.956.0", 299 + "@aws-sdk/middleware-user-agent": "3.956.0", 300 + "@aws-sdk/region-config-resolver": "3.956.0", 301 + "@aws-sdk/types": "3.956.0", 302 + "@aws-sdk/util-endpoints": "3.956.0", 303 + "@aws-sdk/util-user-agent-browser": "3.956.0", 304 + "@aws-sdk/util-user-agent-node": "3.956.0", 305 + "@smithy/config-resolver": "^4.4.5", 306 + "@smithy/core": "^3.20.0", 307 + "@smithy/fetch-http-handler": "^5.3.8", 308 + "@smithy/hash-node": "^4.2.7", 309 + "@smithy/invalid-dependency": "^4.2.7", 310 + "@smithy/middleware-content-length": "^4.2.7", 311 + "@smithy/middleware-endpoint": "^4.4.1", 312 + "@smithy/middleware-retry": "^4.4.17", 313 + "@smithy/middleware-serde": "^4.2.8", 314 + "@smithy/middleware-stack": "^4.2.7", 315 + "@smithy/node-config-provider": "^4.3.7", 316 + "@smithy/node-http-handler": "^4.4.7", 317 + "@smithy/protocol-http": "^5.3.7", 318 + "@smithy/smithy-client": "^4.10.2", 319 + "@smithy/types": "^4.11.0", 320 + "@smithy/url-parser": "^4.2.7", 297 321 "@smithy/util-base64": "^4.3.0", 298 322 "@smithy/util-body-length-browser": "^4.2.0", 299 323 "@smithy/util-body-length-node": "^4.2.1", 300 - "@smithy/util-defaults-mode-browser": "^4.3.13", 301 - "@smithy/util-defaults-mode-node": "^4.2.16", 302 - "@smithy/util-endpoints": "^3.2.5", 303 - "@smithy/util-middleware": "^4.2.5", 304 - "@smithy/util-retry": "^4.2.5", 324 + "@smithy/util-defaults-mode-browser": "^4.3.16", 325 + "@smithy/util-defaults-mode-node": "^4.2.19", 326 + "@smithy/util-endpoints": "^3.2.7", 327 + "@smithy/util-middleware": "^4.2.7", 328 + "@smithy/util-retry": "^4.2.7", 305 329 "@smithy/util-utf8": "^4.2.0", 306 330 "tslib": "^2.6.2" 307 331 }, ··· 310 334 } 311 335 }, 312 336 "node_modules/@aws-sdk/core": { 313 - "version": "3.946.0", 337 + "version": "3.956.0", 338 + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.956.0.tgz", 339 + "integrity": "sha512-BMOCXZNz5z4cR3/SaNHUfeoZQUG/y39bLscdLUgg3RL6mDOhuINIqMc0qc6G3kpwDTLVdXikF4nmx2UrRK9y5A==", 314 340 "license": "Apache-2.0", 315 341 "dependencies": { 316 - "@aws-sdk/types": "3.936.0", 317 - "@aws-sdk/xml-builder": "3.930.0", 318 - "@smithy/core": "^3.18.7", 319 - "@smithy/node-config-provider": "^4.3.5", 320 - "@smithy/property-provider": "^4.2.5", 321 - "@smithy/protocol-http": "^5.3.5", 322 - "@smithy/signature-v4": "^5.3.5", 323 - "@smithy/smithy-client": "^4.9.10", 324 - "@smithy/types": "^4.9.0", 342 + "@aws-sdk/types": "3.956.0", 343 + "@aws-sdk/xml-builder": "3.956.0", 344 + "@smithy/core": "^3.20.0", 345 + "@smithy/node-config-provider": "^4.3.7", 346 + "@smithy/property-provider": "^4.2.7", 347 + "@smithy/protocol-http": "^5.3.7", 348 + "@smithy/signature-v4": "^5.3.7", 349 + "@smithy/smithy-client": "^4.10.2", 350 + "@smithy/types": "^4.11.0", 325 351 "@smithy/util-base64": "^4.3.0", 326 - "@smithy/util-middleware": "^4.2.5", 352 + "@smithy/util-middleware": "^4.2.7", 327 353 "@smithy/util-utf8": "^4.2.0", 328 354 "tslib": "^2.6.2" 329 355 }, ··· 332 358 } 333 359 }, 334 360 "node_modules/@aws-sdk/credential-provider-env": { 335 - "version": "3.946.0", 361 + "version": "3.956.0", 362 + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.956.0.tgz", 363 + "integrity": "sha512-aLJavJMPVTvhmggJ0pcdCKEWJk3sL9QkJkUIEoTzOou7HnxWS66N4sC5e8y27AF2nlnYfIxq3hkEiZlGi/vlfA==", 336 364 "license": "Apache-2.0", 337 365 "dependencies": { 338 - "@aws-sdk/core": "3.946.0", 339 - "@aws-sdk/types": "3.936.0", 340 - "@smithy/property-provider": "^4.2.5", 341 - "@smithy/types": "^4.9.0", 366 + "@aws-sdk/core": "3.956.0", 367 + "@aws-sdk/types": "3.956.0", 368 + "@smithy/property-provider": "^4.2.7", 369 + "@smithy/types": "^4.11.0", 342 370 "tslib": "^2.6.2" 343 371 }, 344 372 "engines": { ··· 346 374 } 347 375 }, 348 376 "node_modules/@aws-sdk/credential-provider-http": { 349 - "version": "3.946.0", 377 + "version": "3.956.0", 378 + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.956.0.tgz", 379 + "integrity": "sha512-VsKzBNhwT6XJdW3HQX6o4KOHj1MAzSwA8/zCsT9mOGecozw1yeCcQPtlWDSlfsfygKVCXz7fiJzU03yl11NKMA==", 350 380 "license": "Apache-2.0", 351 381 "dependencies": { 352 - "@aws-sdk/core": "3.946.0", 353 - "@aws-sdk/types": "3.936.0", 354 - "@smithy/fetch-http-handler": "^5.3.6", 355 - "@smithy/node-http-handler": "^4.4.5", 356 - "@smithy/property-provider": "^4.2.5", 357 - "@smithy/protocol-http": "^5.3.5", 358 - "@smithy/smithy-client": "^4.9.10", 359 - "@smithy/types": "^4.9.0", 360 - "@smithy/util-stream": "^4.5.6", 382 + "@aws-sdk/core": "3.956.0", 383 + "@aws-sdk/types": "3.956.0", 384 + "@smithy/fetch-http-handler": "^5.3.8", 385 + "@smithy/node-http-handler": "^4.4.7", 386 + "@smithy/property-provider": "^4.2.7", 387 + "@smithy/protocol-http": "^5.3.7", 388 + "@smithy/smithy-client": "^4.10.2", 389 + "@smithy/types": "^4.11.0", 390 + "@smithy/util-stream": "^4.5.8", 361 391 "tslib": "^2.6.2" 362 392 }, 363 393 "engines": { ··· 365 395 } 366 396 }, 367 397 "node_modules/@aws-sdk/credential-provider-ini": { 368 - "version": "3.946.0", 398 + "version": "3.956.0", 399 + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.956.0.tgz", 400 + "integrity": "sha512-TlDy+IGr0JIRBwnPdV31J1kWXEcfsR3OzcNVWQrguQdHeTw2lU5eft16kdizo6OruqcZRF/LvHBDwAWx4u51ww==", 369 401 "license": "Apache-2.0", 370 402 "dependencies": { 371 - "@aws-sdk/core": "3.946.0", 372 - "@aws-sdk/credential-provider-env": "3.946.0", 373 - "@aws-sdk/credential-provider-http": "3.946.0", 374 - "@aws-sdk/credential-provider-login": "3.946.0", 375 - "@aws-sdk/credential-provider-process": "3.946.0", 376 - "@aws-sdk/credential-provider-sso": "3.946.0", 377 - "@aws-sdk/credential-provider-web-identity": "3.946.0", 378 - "@aws-sdk/nested-clients": "3.946.0", 379 - "@aws-sdk/types": "3.936.0", 380 - "@smithy/credential-provider-imds": "^4.2.5", 381 - "@smithy/property-provider": "^4.2.5", 382 - "@smithy/shared-ini-file-loader": "^4.4.0", 383 - "@smithy/types": "^4.9.0", 403 + "@aws-sdk/core": "3.956.0", 404 + "@aws-sdk/credential-provider-env": "3.956.0", 405 + "@aws-sdk/credential-provider-http": "3.956.0", 406 + "@aws-sdk/credential-provider-login": "3.956.0", 407 + "@aws-sdk/credential-provider-process": "3.956.0", 408 + "@aws-sdk/credential-provider-sso": "3.956.0", 409 + "@aws-sdk/credential-provider-web-identity": "3.956.0", 410 + "@aws-sdk/nested-clients": "3.956.0", 411 + "@aws-sdk/types": "3.956.0", 412 + "@smithy/credential-provider-imds": "^4.2.7", 413 + "@smithy/property-provider": "^4.2.7", 414 + "@smithy/shared-ini-file-loader": "^4.4.2", 415 + "@smithy/types": "^4.11.0", 384 416 "tslib": "^2.6.2" 385 417 }, 386 418 "engines": { ··· 388 420 } 389 421 }, 390 422 "node_modules/@aws-sdk/credential-provider-login": { 391 - "version": "3.946.0", 423 + "version": "3.956.0", 424 + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.956.0.tgz", 425 + "integrity": "sha512-p2Y62mdIlUpiyi5tvn8cKTja5kq1e3Rm5gm4wpNQ9caTayfkIEXyKrbP07iepTv60Coaylq9Fx6b5En/siAeGA==", 392 426 "license": "Apache-2.0", 393 427 "dependencies": { 394 - "@aws-sdk/core": "3.946.0", 395 - "@aws-sdk/nested-clients": "3.946.0", 396 - "@aws-sdk/types": "3.936.0", 397 - "@smithy/property-provider": "^4.2.5", 398 - "@smithy/protocol-http": "^5.3.5", 399 - "@smithy/shared-ini-file-loader": "^4.4.0", 400 - "@smithy/types": "^4.9.0", 428 + "@aws-sdk/core": "3.956.0", 429 + "@aws-sdk/nested-clients": "3.956.0", 430 + "@aws-sdk/types": "3.956.0", 431 + "@smithy/property-provider": "^4.2.7", 432 + "@smithy/protocol-http": "^5.3.7", 433 + "@smithy/shared-ini-file-loader": "^4.4.2", 434 + "@smithy/types": "^4.11.0", 401 435 "tslib": "^2.6.2" 402 436 }, 403 437 "engines": { ··· 405 439 } 406 440 }, 407 441 "node_modules/@aws-sdk/credential-provider-node": { 408 - "version": "3.946.0", 442 + "version": "3.956.0", 443 + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.956.0.tgz", 444 + "integrity": "sha512-ITjp7uAQh17ljUsCWkPRmLjyFfupGlJVUfTLHnZJ+c7G0P0PDRquaM+fBSh0y33tauHsBa5fGnCCLRo5hy9sGQ==", 409 445 "license": "Apache-2.0", 410 446 "dependencies": { 411 - "@aws-sdk/credential-provider-env": "3.946.0", 412 - "@aws-sdk/credential-provider-http": "3.946.0", 413 - "@aws-sdk/credential-provider-ini": "3.946.0", 414 - "@aws-sdk/credential-provider-process": "3.946.0", 415 - "@aws-sdk/credential-provider-sso": "3.946.0", 416 - "@aws-sdk/credential-provider-web-identity": "3.946.0", 417 - "@aws-sdk/types": "3.936.0", 418 - "@smithy/credential-provider-imds": "^4.2.5", 419 - "@smithy/property-provider": "^4.2.5", 420 - "@smithy/shared-ini-file-loader": "^4.4.0", 421 - "@smithy/types": "^4.9.0", 447 + "@aws-sdk/credential-provider-env": "3.956.0", 448 + "@aws-sdk/credential-provider-http": "3.956.0", 449 + "@aws-sdk/credential-provider-ini": "3.956.0", 450 + "@aws-sdk/credential-provider-process": "3.956.0", 451 + "@aws-sdk/credential-provider-sso": "3.956.0", 452 + "@aws-sdk/credential-provider-web-identity": "3.956.0", 453 + "@aws-sdk/types": "3.956.0", 454 + "@smithy/credential-provider-imds": "^4.2.7", 455 + "@smithy/property-provider": "^4.2.7", 456 + "@smithy/shared-ini-file-loader": "^4.4.2", 457 + "@smithy/types": "^4.11.0", 422 458 "tslib": "^2.6.2" 423 459 }, 424 460 "engines": { ··· 426 462 } 427 463 }, 428 464 "node_modules/@aws-sdk/credential-provider-process": { 429 - "version": "3.946.0", 465 + "version": "3.956.0", 466 + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.956.0.tgz", 467 + "integrity": "sha512-wpAex+/LGVWkHPchsn9FWy1ahFualIeSYq3ADFc262ljJjrltOWGh3+cu3OK3gTMkX6VEsl+lFvy1P7Bk7cgXA==", 430 468 "license": "Apache-2.0", 431 469 "dependencies": { 432 - "@aws-sdk/core": "3.946.0", 433 - "@aws-sdk/types": "3.936.0", 434 - "@smithy/property-provider": "^4.2.5", 435 - "@smithy/shared-ini-file-loader": "^4.4.0", 436 - "@smithy/types": "^4.9.0", 470 + "@aws-sdk/core": "3.956.0", 471 + "@aws-sdk/types": "3.956.0", 472 + "@smithy/property-provider": "^4.2.7", 473 + "@smithy/shared-ini-file-loader": "^4.4.2", 474 + "@smithy/types": "^4.11.0", 437 475 "tslib": "^2.6.2" 438 476 }, 439 477 "engines": { ··· 441 479 } 442 480 }, 443 481 "node_modules/@aws-sdk/credential-provider-sso": { 444 - "version": "3.946.0", 482 + "version": "3.956.0", 483 + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.956.0.tgz", 484 + "integrity": "sha512-IRFSDF32x8TpOEYSGMcGQVJUiYuJaFkek0aCjW0klNIZHBF1YpflVpUarK9DJe4v4ryfVq3c0bqR/JFui8QFmw==", 445 485 "license": "Apache-2.0", 446 486 "dependencies": { 447 - "@aws-sdk/client-sso": "3.946.0", 448 - "@aws-sdk/core": "3.946.0", 449 - "@aws-sdk/token-providers": "3.946.0", 450 - "@aws-sdk/types": "3.936.0", 451 - "@smithy/property-provider": "^4.2.5", 452 - "@smithy/shared-ini-file-loader": "^4.4.0", 453 - "@smithy/types": "^4.9.0", 487 + "@aws-sdk/client-sso": "3.956.0", 488 + "@aws-sdk/core": "3.956.0", 489 + "@aws-sdk/token-providers": "3.956.0", 490 + "@aws-sdk/types": "3.956.0", 491 + "@smithy/property-provider": "^4.2.7", 492 + "@smithy/shared-ini-file-loader": "^4.4.2", 493 + "@smithy/types": "^4.11.0", 454 494 "tslib": "^2.6.2" 455 495 }, 456 496 "engines": { ··· 458 498 } 459 499 }, 460 500 "node_modules/@aws-sdk/credential-provider-web-identity": { 461 - "version": "3.946.0", 501 + "version": "3.956.0", 502 + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.956.0.tgz", 503 + "integrity": "sha512-4YkmjwZC+qoUKlVOY9xNx7BTKRdJ1R1/Zjk2QSW5aWtwkk2e07ZUQvUpbW4vGpAxGm1K4EgRcowuSpOsDTh44Q==", 504 + "license": "Apache-2.0", 505 + "dependencies": { 506 + "@aws-sdk/core": "3.956.0", 507 + "@aws-sdk/nested-clients": "3.956.0", 508 + "@aws-sdk/types": "3.956.0", 509 + "@smithy/property-provider": "^4.2.7", 510 + "@smithy/shared-ini-file-loader": "^4.4.2", 511 + "@smithy/types": "^4.11.0", 512 + "tslib": "^2.6.2" 513 + }, 514 + "engines": { 515 + "node": ">=18.0.0" 516 + } 517 + }, 518 + "node_modules/@aws-sdk/lib-storage": { 519 + "version": "3.956.0", 520 + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.956.0.tgz", 521 + "integrity": "sha512-CbRdMmB0lAf+InlqGUm7ly6qIO8g6661Xpre3OtZcwfTFSJ8TjQWfj0KLZoNvk605XKxhWR43yd5I6MrmE5jng==", 462 522 "license": "Apache-2.0", 463 523 "dependencies": { 464 - "@aws-sdk/core": "3.946.0", 465 - "@aws-sdk/nested-clients": "3.946.0", 466 - "@aws-sdk/types": "3.936.0", 467 - "@smithy/property-provider": "^4.2.5", 468 - "@smithy/shared-ini-file-loader": "^4.4.0", 469 - "@smithy/types": "^4.9.0", 524 + "@smithy/abort-controller": "^4.2.7", 525 + "@smithy/middleware-endpoint": "^4.4.1", 526 + "@smithy/smithy-client": "^4.10.2", 527 + "buffer": "5.6.0", 528 + "events": "3.3.0", 529 + "stream-browserify": "3.0.0", 470 530 "tslib": "^2.6.2" 471 531 }, 472 532 "engines": { 473 533 "node": ">=18.0.0" 534 + }, 535 + "peerDependencies": { 536 + "@aws-sdk/client-s3": "^3.956.0" 474 537 } 475 538 }, 476 539 "node_modules/@aws-sdk/middleware-bucket-endpoint": { 477 - "version": "3.936.0", 540 + "version": "3.956.0", 541 + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.956.0.tgz", 542 + "integrity": "sha512-+iHH9cnkNZgKkTBnPP9rbapHliKDrOuj7MDz6+wL0NV4N/XGB5tbrd+uDP608FXVeMHcWIIZtWkANADUmAI49w==", 478 543 "license": "Apache-2.0", 479 544 "dependencies": { 480 - "@aws-sdk/types": "3.936.0", 481 - "@aws-sdk/util-arn-parser": "3.893.0", 482 - "@smithy/node-config-provider": "^4.3.5", 483 - "@smithy/protocol-http": "^5.3.5", 484 - "@smithy/types": "^4.9.0", 545 + "@aws-sdk/types": "3.956.0", 546 + "@aws-sdk/util-arn-parser": "3.953.0", 547 + "@smithy/node-config-provider": "^4.3.7", 548 + "@smithy/protocol-http": "^5.3.7", 549 + "@smithy/types": "^4.11.0", 485 550 "@smithy/util-config-provider": "^4.2.0", 486 551 "tslib": "^2.6.2" 487 552 }, ··· 490 555 } 491 556 }, 492 557 "node_modules/@aws-sdk/middleware-expect-continue": { 493 - "version": "3.936.0", 558 + "version": "3.956.0", 559 + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.956.0.tgz", 560 + "integrity": "sha512-97rmalK9x09Darcl6AbShZRXYxWiyCeO8ll1C9rx1xyZMs2DeIKAZ/xuAJ/bywB3l25ls6VqXO4/EuDFJHL8eA==", 494 561 "license": "Apache-2.0", 495 562 "dependencies": { 496 - "@aws-sdk/types": "3.936.0", 497 - "@smithy/protocol-http": "^5.3.5", 498 - "@smithy/types": "^4.9.0", 563 + "@aws-sdk/types": "3.956.0", 564 + "@smithy/protocol-http": "^5.3.7", 565 + "@smithy/types": "^4.11.0", 499 566 "tslib": "^2.6.2" 500 567 }, 501 568 "engines": { ··· 503 570 } 504 571 }, 505 572 "node_modules/@aws-sdk/middleware-flexible-checksums": { 506 - "version": "3.946.0", 573 + "version": "3.956.0", 574 + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.956.0.tgz", 575 + "integrity": "sha512-Rd/VeVKuw+lQ1oJmJOyXV0flIkp9ouMGAS9QT28ogdQVxXriaheNo754N4z0+8+R6uTcmeojN7dN4jzt51WV2g==", 507 576 "license": "Apache-2.0", 508 577 "dependencies": { 509 578 "@aws-crypto/crc32": "5.2.0", 510 579 "@aws-crypto/crc32c": "5.2.0", 511 580 "@aws-crypto/util": "5.2.0", 512 - "@aws-sdk/core": "3.946.0", 513 - "@aws-sdk/types": "3.936.0", 581 + "@aws-sdk/core": "3.956.0", 582 + "@aws-sdk/types": "3.956.0", 514 583 "@smithy/is-array-buffer": "^4.2.0", 515 - "@smithy/node-config-provider": "^4.3.5", 516 - "@smithy/protocol-http": "^5.3.5", 517 - "@smithy/types": "^4.9.0", 518 - "@smithy/util-middleware": "^4.2.5", 519 - "@smithy/util-stream": "^4.5.6", 584 + "@smithy/node-config-provider": "^4.3.7", 585 + "@smithy/protocol-http": "^5.3.7", 586 + "@smithy/types": "^4.11.0", 587 + "@smithy/util-middleware": "^4.2.7", 588 + "@smithy/util-stream": "^4.5.8", 520 589 "@smithy/util-utf8": "^4.2.0", 521 590 "tslib": "^2.6.2" 522 591 }, ··· 525 594 } 526 595 }, 527 596 "node_modules/@aws-sdk/middleware-host-header": { 528 - "version": "3.936.0", 597 + "version": "3.956.0", 598 + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.956.0.tgz", 599 + "integrity": "sha512-JujNJDp/dj1DbsI0ntzhrz2uJ4jpumcKtr743eMpEhdboYjuu/UzY8/7n1h5JbgU9TNXgqE9lgQNa5QPG0Tvsg==", 529 600 "license": "Apache-2.0", 530 601 "dependencies": { 531 - "@aws-sdk/types": "3.936.0", 532 - "@smithy/protocol-http": "^5.3.5", 533 - "@smithy/types": "^4.9.0", 602 + "@aws-sdk/types": "3.956.0", 603 + "@smithy/protocol-http": "^5.3.7", 604 + "@smithy/types": "^4.11.0", 534 605 "tslib": "^2.6.2" 535 606 }, 536 607 "engines": { ··· 538 609 } 539 610 }, 540 611 "node_modules/@aws-sdk/middleware-location-constraint": { 541 - "version": "3.936.0", 612 + "version": "3.956.0", 613 + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.956.0.tgz", 614 + "integrity": "sha512-eANhYRFcVO/lI9tliitSW0DK5H1d9J7BK/9RrRz86bd5zPWteVqqzQRbMUdErVi1nwSbSIAa6YGv/ItYPswe0w==", 542 615 "license": "Apache-2.0", 543 616 "dependencies": { 544 - "@aws-sdk/types": "3.936.0", 545 - "@smithy/types": "^4.9.0", 617 + "@aws-sdk/types": "3.956.0", 618 + "@smithy/types": "^4.11.0", 546 619 "tslib": "^2.6.2" 547 620 }, 548 621 "engines": { ··· 550 623 } 551 624 }, 552 625 "node_modules/@aws-sdk/middleware-logger": { 553 - "version": "3.936.0", 626 + "version": "3.956.0", 627 + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.956.0.tgz", 628 + "integrity": "sha512-Qff39yEOPYgRsm4SrkHOvS0nSoxXILYnC8Akp0uMRi2lOcZVyXL3WCWqIOtI830qVI4GPa796sleKguxx50RHg==", 554 629 "license": "Apache-2.0", 555 630 "dependencies": { 556 - "@aws-sdk/types": "3.936.0", 557 - "@smithy/types": "^4.9.0", 631 + "@aws-sdk/types": "3.956.0", 632 + "@smithy/types": "^4.11.0", 558 633 "tslib": "^2.6.2" 559 634 }, 560 635 "engines": { ··· 562 637 } 563 638 }, 564 639 "node_modules/@aws-sdk/middleware-recursion-detection": { 565 - "version": "3.936.0", 640 + "version": "3.956.0", 641 + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.956.0.tgz", 642 + "integrity": "sha512-/f4JxL2kSCYhy63wovqts6SJkpalSLvuFe78ozt3ClrGoHGyr69o7tPRYx5U7azLgvrIGjsWUyTayeAk3YHIVQ==", 566 643 "license": "Apache-2.0", 567 644 "dependencies": { 568 - "@aws-sdk/types": "3.936.0", 569 - "@aws/lambda-invoke-store": "^0.2.0", 570 - "@smithy/protocol-http": "^5.3.5", 571 - "@smithy/types": "^4.9.0", 645 + "@aws-sdk/types": "3.956.0", 646 + "@aws/lambda-invoke-store": "^0.2.2", 647 + "@smithy/protocol-http": "^5.3.7", 648 + "@smithy/types": "^4.11.0", 572 649 "tslib": "^2.6.2" 573 650 }, 574 651 "engines": { ··· 576 653 } 577 654 }, 578 655 "node_modules/@aws-sdk/middleware-sdk-s3": { 579 - "version": "3.946.0", 656 + "version": "3.956.0", 657 + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.956.0.tgz", 658 + "integrity": "sha512-U/+jYb4iowqqpLjB6cSYan0goAMOlh2xg2CPIdSy550o8mYnJtuajBUQ20A9AA9PYKLlEAoCNEysNZkn4o/63g==", 580 659 "license": "Apache-2.0", 581 660 "dependencies": { 582 - "@aws-sdk/core": "3.946.0", 583 - "@aws-sdk/types": "3.936.0", 584 - "@aws-sdk/util-arn-parser": "3.893.0", 585 - "@smithy/core": "^3.18.7", 586 - "@smithy/node-config-provider": "^4.3.5", 587 - "@smithy/protocol-http": "^5.3.5", 588 - "@smithy/signature-v4": "^5.3.5", 589 - "@smithy/smithy-client": "^4.9.10", 590 - "@smithy/types": "^4.9.0", 661 + "@aws-sdk/core": "3.956.0", 662 + "@aws-sdk/types": "3.956.0", 663 + "@aws-sdk/util-arn-parser": "3.953.0", 664 + "@smithy/core": "^3.20.0", 665 + "@smithy/node-config-provider": "^4.3.7", 666 + "@smithy/protocol-http": "^5.3.7", 667 + "@smithy/signature-v4": "^5.3.7", 668 + "@smithy/smithy-client": "^4.10.2", 669 + "@smithy/types": "^4.11.0", 591 670 "@smithy/util-config-provider": "^4.2.0", 592 - "@smithy/util-middleware": "^4.2.5", 593 - "@smithy/util-stream": "^4.5.6", 671 + "@smithy/util-middleware": "^4.2.7", 672 + "@smithy/util-stream": "^4.5.8", 594 673 "@smithy/util-utf8": "^4.2.0", 595 674 "tslib": "^2.6.2" 596 675 }, ··· 599 678 } 600 679 }, 601 680 "node_modules/@aws-sdk/middleware-ssec": { 602 - "version": "3.936.0", 681 + "version": "3.956.0", 682 + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.956.0.tgz", 683 + "integrity": "sha512-1Et0vPoIzfhkUAdNRzu0pC25ZawFqXo5T8xpvbwkfDgfIkeVj+sm9t01iXO3pCOK52OSuLRAy7fiAo/AoHjOYg==", 603 684 "license": "Apache-2.0", 604 685 "dependencies": { 605 - "@aws-sdk/types": "3.936.0", 606 - "@smithy/types": "^4.9.0", 686 + "@aws-sdk/types": "3.956.0", 687 + "@smithy/types": "^4.11.0", 607 688 "tslib": "^2.6.2" 608 689 }, 609 690 "engines": { ··· 611 692 } 612 693 }, 613 694 "node_modules/@aws-sdk/middleware-user-agent": { 614 - "version": "3.946.0", 695 + "version": "3.956.0", 696 + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.956.0.tgz", 697 + "integrity": "sha512-azH8OJ0AIe3NafaTNvJorG/ALaLNTYwVKtyaSeQKOvaL8TNuBVuDnM5iHCiWryIaRgZotomqycwyfNKLw2D3JQ==", 615 698 "license": "Apache-2.0", 616 699 "dependencies": { 617 - "@aws-sdk/core": "3.946.0", 618 - "@aws-sdk/types": "3.936.0", 619 - "@aws-sdk/util-endpoints": "3.936.0", 620 - "@smithy/core": "^3.18.7", 621 - "@smithy/protocol-http": "^5.3.5", 622 - "@smithy/types": "^4.9.0", 700 + "@aws-sdk/core": "3.956.0", 701 + "@aws-sdk/types": "3.956.0", 702 + "@aws-sdk/util-endpoints": "3.956.0", 703 + "@smithy/core": "^3.20.0", 704 + "@smithy/protocol-http": "^5.3.7", 705 + "@smithy/types": "^4.11.0", 623 706 "tslib": "^2.6.2" 624 707 }, 625 708 "engines": { ··· 627 710 } 628 711 }, 629 712 "node_modules/@aws-sdk/nested-clients": { 630 - "version": "3.946.0", 713 + "version": "3.956.0", 714 + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.956.0.tgz", 715 + "integrity": "sha512-GHDQMkxoWpi3eTrhWGmghw0gsZJ5rM1ERHfBFhlhduCdtV3TyhKVmDgFG84KhU8v18dcVpSp3Pu3KwH7j1tgIg==", 631 716 "license": "Apache-2.0", 632 717 "dependencies": { 633 718 "@aws-crypto/sha256-browser": "5.2.0", 634 719 "@aws-crypto/sha256-js": "5.2.0", 635 - "@aws-sdk/core": "3.946.0", 636 - "@aws-sdk/middleware-host-header": "3.936.0", 637 - "@aws-sdk/middleware-logger": "3.936.0", 638 - "@aws-sdk/middleware-recursion-detection": "3.936.0", 639 - "@aws-sdk/middleware-user-agent": "3.946.0", 640 - "@aws-sdk/region-config-resolver": "3.936.0", 641 - "@aws-sdk/types": "3.936.0", 642 - "@aws-sdk/util-endpoints": "3.936.0", 643 - "@aws-sdk/util-user-agent-browser": "3.936.0", 644 - "@aws-sdk/util-user-agent-node": "3.946.0", 645 - "@smithy/config-resolver": "^4.4.3", 646 - "@smithy/core": "^3.18.7", 647 - "@smithy/fetch-http-handler": "^5.3.6", 648 - "@smithy/hash-node": "^4.2.5", 649 - "@smithy/invalid-dependency": "^4.2.5", 650 - "@smithy/middleware-content-length": "^4.2.5", 651 - "@smithy/middleware-endpoint": "^4.3.14", 652 - "@smithy/middleware-retry": "^4.4.14", 653 - "@smithy/middleware-serde": "^4.2.6", 654 - "@smithy/middleware-stack": "^4.2.5", 655 - "@smithy/node-config-provider": "^4.3.5", 656 - "@smithy/node-http-handler": "^4.4.5", 657 - "@smithy/protocol-http": "^5.3.5", 658 - "@smithy/smithy-client": "^4.9.10", 659 - "@smithy/types": "^4.9.0", 660 - "@smithy/url-parser": "^4.2.5", 720 + "@aws-sdk/core": "3.956.0", 721 + "@aws-sdk/middleware-host-header": "3.956.0", 722 + "@aws-sdk/middleware-logger": "3.956.0", 723 + "@aws-sdk/middleware-recursion-detection": "3.956.0", 724 + "@aws-sdk/middleware-user-agent": "3.956.0", 725 + "@aws-sdk/region-config-resolver": "3.956.0", 726 + "@aws-sdk/types": "3.956.0", 727 + "@aws-sdk/util-endpoints": "3.956.0", 728 + "@aws-sdk/util-user-agent-browser": "3.956.0", 729 + "@aws-sdk/util-user-agent-node": "3.956.0", 730 + "@smithy/config-resolver": "^4.4.5", 731 + "@smithy/core": "^3.20.0", 732 + "@smithy/fetch-http-handler": "^5.3.8", 733 + "@smithy/hash-node": "^4.2.7", 734 + "@smithy/invalid-dependency": "^4.2.7", 735 + "@smithy/middleware-content-length": "^4.2.7", 736 + "@smithy/middleware-endpoint": "^4.4.1", 737 + "@smithy/middleware-retry": "^4.4.17", 738 + "@smithy/middleware-serde": "^4.2.8", 739 + "@smithy/middleware-stack": "^4.2.7", 740 + "@smithy/node-config-provider": "^4.3.7", 741 + "@smithy/node-http-handler": "^4.4.7", 742 + "@smithy/protocol-http": "^5.3.7", 743 + "@smithy/smithy-client": "^4.10.2", 744 + "@smithy/types": "^4.11.0", 745 + "@smithy/url-parser": "^4.2.7", 661 746 "@smithy/util-base64": "^4.3.0", 662 747 "@smithy/util-body-length-browser": "^4.2.0", 663 748 "@smithy/util-body-length-node": "^4.2.1", 664 - "@smithy/util-defaults-mode-browser": "^4.3.13", 665 - "@smithy/util-defaults-mode-node": "^4.2.16", 666 - "@smithy/util-endpoints": "^3.2.5", 667 - "@smithy/util-middleware": "^4.2.5", 668 - "@smithy/util-retry": "^4.2.5", 749 + "@smithy/util-defaults-mode-browser": "^4.3.16", 750 + "@smithy/util-defaults-mode-node": "^4.2.19", 751 + "@smithy/util-endpoints": "^3.2.7", 752 + "@smithy/util-middleware": "^4.2.7", 753 + "@smithy/util-retry": "^4.2.7", 669 754 "@smithy/util-utf8": "^4.2.0", 670 755 "tslib": "^2.6.2" 671 756 }, ··· 674 759 } 675 760 }, 676 761 "node_modules/@aws-sdk/region-config-resolver": { 677 - "version": "3.936.0", 762 + "version": "3.956.0", 763 + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.956.0.tgz", 764 + "integrity": "sha512-byU5XYekW7+rZ3e067y038wlrpnPkdI4fMxcHCHrv+TAfzl8CCk5xLyzerQtXZR8cVPVOXuaYWe1zKW0uCnXUA==", 678 765 "license": "Apache-2.0", 679 766 "dependencies": { 680 - "@aws-sdk/types": "3.936.0", 681 - "@smithy/config-resolver": "^4.4.3", 682 - "@smithy/node-config-provider": "^4.3.5", 683 - "@smithy/types": "^4.9.0", 767 + "@aws-sdk/types": "3.956.0", 768 + "@smithy/config-resolver": "^4.4.5", 769 + "@smithy/node-config-provider": "^4.3.7", 770 + "@smithy/types": "^4.11.0", 684 771 "tslib": "^2.6.2" 685 772 }, 686 773 "engines": { ··· 688 775 } 689 776 }, 690 777 "node_modules/@aws-sdk/signature-v4-multi-region": { 691 - "version": "3.946.0", 778 + "version": "3.956.0", 779 + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.956.0.tgz", 780 + "integrity": "sha512-gejlXPmor08VydGC8bx0Bv4/tPT92eK0WLe2pUPR0AaMXL+5ycDpThAi1vLWjWr0aUjCA7lXx0pMENWlJlYK3A==", 692 781 "license": "Apache-2.0", 693 782 "dependencies": { 694 - "@aws-sdk/middleware-sdk-s3": "3.946.0", 695 - "@aws-sdk/types": "3.936.0", 696 - "@smithy/protocol-http": "^5.3.5", 697 - "@smithy/signature-v4": "^5.3.5", 698 - "@smithy/types": "^4.9.0", 783 + "@aws-sdk/middleware-sdk-s3": "3.956.0", 784 + "@aws-sdk/types": "3.956.0", 785 + "@smithy/protocol-http": "^5.3.7", 786 + "@smithy/signature-v4": "^5.3.7", 787 + "@smithy/types": "^4.11.0", 699 788 "tslib": "^2.6.2" 700 789 }, 701 790 "engines": { ··· 703 792 } 704 793 }, 705 794 "node_modules/@aws-sdk/token-providers": { 706 - "version": "3.946.0", 795 + "version": "3.956.0", 796 + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.956.0.tgz", 797 + "integrity": "sha512-I01Q9yDeG9oXge14u/bubtSdBpok/rTsPp2AQwy5xj/5PatRTHPbUTP6tef3AH/lFCAqkI0nncIcgx6zikDdUQ==", 707 798 "license": "Apache-2.0", 708 799 "dependencies": { 709 - "@aws-sdk/core": "3.946.0", 710 - "@aws-sdk/nested-clients": "3.946.0", 711 - "@aws-sdk/types": "3.936.0", 712 - "@smithy/property-provider": "^4.2.5", 713 - "@smithy/shared-ini-file-loader": "^4.4.0", 714 - "@smithy/types": "^4.9.0", 800 + "@aws-sdk/core": "3.956.0", 801 + "@aws-sdk/nested-clients": "3.956.0", 802 + "@aws-sdk/types": "3.956.0", 803 + "@smithy/property-provider": "^4.2.7", 804 + "@smithy/shared-ini-file-loader": "^4.4.2", 805 + "@smithy/types": "^4.11.0", 715 806 "tslib": "^2.6.2" 716 807 }, 717 808 "engines": { ··· 719 810 } 720 811 }, 721 812 "node_modules/@aws-sdk/types": { 722 - "version": "3.936.0", 813 + "version": "3.956.0", 814 + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.956.0.tgz", 815 + "integrity": "sha512-DMRU/p9wAlAJxEjegnLwduCA8YP2pcT/sIJ+17KSF38c5cC6CbBhykwbZLECTo+zYzoFrOqeLbqE6paH8Gx3ug==", 723 816 "license": "Apache-2.0", 724 817 "dependencies": { 725 - "@smithy/types": "^4.9.0", 818 + "@smithy/types": "^4.11.0", 726 819 "tslib": "^2.6.2" 727 820 }, 728 821 "engines": { ··· 730 823 } 731 824 }, 732 825 "node_modules/@aws-sdk/util-arn-parser": { 733 - "version": "3.893.0", 826 + "version": "3.953.0", 827 + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.953.0.tgz", 828 + "integrity": "sha512-9hqdKkn4OvYzzaLryq2xnwcrPc8ziY34i9szUdgBfSqEC6pBxbY9/lLXmrgzfwMSL2Z7/v2go4Od0p5eukKLMQ==", 734 829 "license": "Apache-2.0", 735 830 "dependencies": { 736 831 "tslib": "^2.6.2" ··· 740 835 } 741 836 }, 742 837 "node_modules/@aws-sdk/util-endpoints": { 743 - "version": "3.936.0", 838 + "version": "3.956.0", 839 + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.956.0.tgz", 840 + "integrity": "sha512-xZ5CBoubS4rs9JkFniKNShDtfqxaMUnwaebYMoybZm070q9+omFkQkJYXl7kopTViEgZgQl1sAsAkrawBM8qEQ==", 744 841 "license": "Apache-2.0", 745 842 "dependencies": { 746 - "@aws-sdk/types": "3.936.0", 747 - "@smithy/types": "^4.9.0", 748 - "@smithy/url-parser": "^4.2.5", 749 - "@smithy/util-endpoints": "^3.2.5", 843 + "@aws-sdk/types": "3.956.0", 844 + "@smithy/types": "^4.11.0", 845 + "@smithy/url-parser": "^4.2.7", 846 + "@smithy/util-endpoints": "^3.2.7", 750 847 "tslib": "^2.6.2" 751 848 }, 752 849 "engines": { ··· 764 861 } 765 862 }, 766 863 "node_modules/@aws-sdk/util-user-agent-browser": { 767 - "version": "3.936.0", 864 + "version": "3.956.0", 865 + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.956.0.tgz", 866 + "integrity": "sha512-s8KwYR3HqiGNni7a1DN2P3RUog64QoBQ6VCSzJkHBWb6++8KSOpqeeDkfmEz+22y1LOne+bRrpDGKa0aqOc3rQ==", 768 867 "license": "Apache-2.0", 769 868 "dependencies": { 770 - "@aws-sdk/types": "3.936.0", 771 - "@smithy/types": "^4.9.0", 869 + "@aws-sdk/types": "3.956.0", 870 + "@smithy/types": "^4.11.0", 772 871 "bowser": "^2.11.0", 773 872 "tslib": "^2.6.2" 774 873 } 775 874 }, 776 875 "node_modules/@aws-sdk/util-user-agent-node": { 777 - "version": "3.946.0", 876 + "version": "3.956.0", 877 + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.956.0.tgz", 878 + "integrity": "sha512-H0r6ol3Rr63/3xvrUsLqHps+cA7VkM7uCU5NtuTHnMbv3uYYTKf9M2XFHAdVewmmRgssTzvqemrARc8Ji3SNvg==", 778 879 "license": "Apache-2.0", 779 880 "dependencies": { 780 - "@aws-sdk/middleware-user-agent": "3.946.0", 781 - "@aws-sdk/types": "3.936.0", 782 - "@smithy/node-config-provider": "^4.3.5", 783 - "@smithy/types": "^4.9.0", 881 + "@aws-sdk/middleware-user-agent": "3.956.0", 882 + "@aws-sdk/types": "3.956.0", 883 + "@smithy/node-config-provider": "^4.3.7", 884 + "@smithy/types": "^4.11.0", 784 885 "tslib": "^2.6.2" 785 886 }, 786 887 "engines": { ··· 796 897 } 797 898 }, 798 899 "node_modules/@aws-sdk/xml-builder": { 799 - "version": "3.930.0", 900 + "version": "3.956.0", 901 + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.956.0.tgz", 902 + "integrity": "sha512-x/IvXUeQYNUEQojpRIQpFt4X7XGxqzjUlXFRdwaTCtTz3q1droXVJvYOhnX3KiMgzeHGlBJfY4Nmq3oZNEUGFw==", 800 903 "license": "Apache-2.0", 801 904 "dependencies": { 802 - "@smithy/types": "^4.9.0", 905 + "@smithy/types": "^4.11.0", 803 906 "fast-xml-parser": "5.2.5", 804 907 "tslib": "^2.6.2" 805 908 }, ··· 809 912 }, 810 913 "node_modules/@aws/lambda-invoke-store": { 811 914 "version": "0.2.2", 915 + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.2.tgz", 916 + "integrity": "sha512-C0NBLsIqzDIae8HFw9YIrIBsbc0xTiOtt7fAukGPnqQ/+zZNaq+4jhuccltK0QuWHBnNm/a6kLIRA6GFiM10eg==", 812 917 "license": "Apache-2.0", 813 918 "engines": { 814 919 "node": ">=18.0.0" ··· 1446 1551 "dev": true, 1447 1552 "license": "MIT" 1448 1553 }, 1554 + "node_modules/@pkgr/core": { 1555 + "version": "0.2.9", 1556 + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", 1557 + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", 1558 + "dev": true, 1559 + "license": "MIT", 1560 + "engines": { 1561 + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" 1562 + }, 1563 + "funding": { 1564 + "url": "https://opencollective.com/pkgr" 1565 + } 1566 + }, 1449 1567 "node_modules/@rollup/rollup-android-arm-eabi": { 1450 1568 "version": "4.53.3", 1451 1569 "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", ··· 1753 1871 ] 1754 1872 }, 1755 1873 "node_modules/@smithy/abort-controller": { 1756 - "version": "4.2.5", 1874 + "version": "4.2.7", 1875 + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.7.tgz", 1876 + "integrity": "sha512-rzMY6CaKx2qxrbYbqjXWS0plqEy7LOdKHS0bg4ixJ6aoGDPNUcLWk/FRNuCILh7GKLG9TFUXYYeQQldMBBwuyw==", 1757 1877 "license": "Apache-2.0", 1758 1878 "dependencies": { 1759 - "@smithy/types": "^4.9.0", 1879 + "@smithy/types": "^4.11.0", 1760 1880 "tslib": "^2.6.2" 1761 1881 }, 1762 1882 "engines": { ··· 1765 1885 }, 1766 1886 "node_modules/@smithy/chunked-blob-reader": { 1767 1887 "version": "5.2.0", 1888 + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.2.0.tgz", 1889 + "integrity": "sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==", 1768 1890 "license": "Apache-2.0", 1769 1891 "dependencies": { 1770 1892 "tslib": "^2.6.2" ··· 1775 1897 }, 1776 1898 "node_modules/@smithy/chunked-blob-reader-native": { 1777 1899 "version": "4.2.1", 1900 + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.1.tgz", 1901 + "integrity": "sha512-lX9Ay+6LisTfpLid2zZtIhSEjHMZoAR5hHCR4H7tBz/Zkfr5ea8RcQ7Tk4mi0P76p4cN+Btz16Ffno7YHpKXnQ==", 1778 1902 "license": "Apache-2.0", 1779 1903 "dependencies": { 1780 1904 "@smithy/util-base64": "^4.3.0", ··· 1785 1909 } 1786 1910 }, 1787 1911 "node_modules/@smithy/config-resolver": { 1788 - "version": "4.4.3", 1912 + "version": "4.4.5", 1913 + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.5.tgz", 1914 + "integrity": "sha512-HAGoUAFYsUkoSckuKbCPayECeMim8pOu+yLy1zOxt1sifzEbrsRpYa+mKcMdiHKMeiqOibyPG0sFJnmaV/OGEg==", 1789 1915 "license": "Apache-2.0", 1790 1916 "dependencies": { 1791 - "@smithy/node-config-provider": "^4.3.5", 1792 - "@smithy/types": "^4.9.0", 1917 + "@smithy/node-config-provider": "^4.3.7", 1918 + "@smithy/types": "^4.11.0", 1793 1919 "@smithy/util-config-provider": "^4.2.0", 1794 - "@smithy/util-endpoints": "^3.2.5", 1795 - "@smithy/util-middleware": "^4.2.5", 1920 + "@smithy/util-endpoints": "^3.2.7", 1921 + "@smithy/util-middleware": "^4.2.7", 1796 1922 "tslib": "^2.6.2" 1797 1923 }, 1798 1924 "engines": { ··· 1800 1926 } 1801 1927 }, 1802 1928 "node_modules/@smithy/core": { 1803 - "version": "3.18.7", 1929 + "version": "3.20.0", 1930 + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.20.0.tgz", 1931 + "integrity": "sha512-WsSHCPq/neD5G/MkK4csLI5Y5Pkd9c1NMfpYEKeghSGaD4Ja1qLIohRQf2D5c1Uy5aXp76DeKHkzWZ9KAlHroQ==", 1804 1932 "license": "Apache-2.0", 1805 1933 "dependencies": { 1806 - "@smithy/middleware-serde": "^4.2.6", 1807 - "@smithy/protocol-http": "^5.3.5", 1808 - "@smithy/types": "^4.9.0", 1934 + "@smithy/middleware-serde": "^4.2.8", 1935 + "@smithy/protocol-http": "^5.3.7", 1936 + "@smithy/types": "^4.11.0", 1809 1937 "@smithy/util-base64": "^4.3.0", 1810 1938 "@smithy/util-body-length-browser": "^4.2.0", 1811 - "@smithy/util-middleware": "^4.2.5", 1812 - "@smithy/util-stream": "^4.5.6", 1939 + "@smithy/util-middleware": "^4.2.7", 1940 + "@smithy/util-stream": "^4.5.8", 1813 1941 "@smithy/util-utf8": "^4.2.0", 1814 1942 "@smithy/uuid": "^1.1.0", 1815 1943 "tslib": "^2.6.2" ··· 1819 1947 } 1820 1948 }, 1821 1949 "node_modules/@smithy/credential-provider-imds": { 1822 - "version": "4.2.5", 1950 + "version": "4.2.7", 1951 + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.7.tgz", 1952 + "integrity": "sha512-CmduWdCiILCRNbQWFR0OcZlUPVtyE49Sr8yYL0rZQ4D/wKxiNzBNS/YHemvnbkIWj623fplgkexUd/c9CAKdoA==", 1823 1953 "license": "Apache-2.0", 1824 1954 "dependencies": { 1825 - "@smithy/node-config-provider": "^4.3.5", 1826 - "@smithy/property-provider": "^4.2.5", 1827 - "@smithy/types": "^4.9.0", 1828 - "@smithy/url-parser": "^4.2.5", 1955 + "@smithy/node-config-provider": "^4.3.7", 1956 + "@smithy/property-provider": "^4.2.7", 1957 + "@smithy/types": "^4.11.0", 1958 + "@smithy/url-parser": "^4.2.7", 1829 1959 "tslib": "^2.6.2" 1830 1960 }, 1831 1961 "engines": { ··· 1833 1963 } 1834 1964 }, 1835 1965 "node_modules/@smithy/eventstream-codec": { 1836 - "version": "4.2.5", 1966 + "version": "4.2.7", 1967 + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.7.tgz", 1968 + "integrity": "sha512-DrpkEoM3j9cBBWhufqBwnbbn+3nf1N9FP6xuVJ+e220jbactKuQgaZwjwP5CP1t+O94brm2JgVMD2atMGX3xIQ==", 1837 1969 "license": "Apache-2.0", 1838 1970 "dependencies": { 1839 1971 "@aws-crypto/crc32": "5.2.0", 1840 - "@smithy/types": "^4.9.0", 1972 + "@smithy/types": "^4.11.0", 1841 1973 "@smithy/util-hex-encoding": "^4.2.0", 1842 1974 "tslib": "^2.6.2" 1843 1975 }, ··· 1846 1978 } 1847 1979 }, 1848 1980 "node_modules/@smithy/eventstream-serde-browser": { 1849 - "version": "4.2.5", 1981 + "version": "4.2.7", 1982 + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.7.tgz", 1983 + "integrity": "sha512-ujzPk8seYoDBmABDE5YqlhQZAXLOrtxtJLrbhHMKjBoG5b4dK4i6/mEU+6/7yXIAkqOO8sJ6YxZl+h0QQ1IJ7g==", 1850 1984 "license": "Apache-2.0", 1851 1985 "dependencies": { 1852 - "@smithy/eventstream-serde-universal": "^4.2.5", 1853 - "@smithy/types": "^4.9.0", 1986 + "@smithy/eventstream-serde-universal": "^4.2.7", 1987 + "@smithy/types": "^4.11.0", 1854 1988 "tslib": "^2.6.2" 1855 1989 }, 1856 1990 "engines": { ··· 1858 1992 } 1859 1993 }, 1860 1994 "node_modules/@smithy/eventstream-serde-config-resolver": { 1861 - "version": "4.3.5", 1995 + "version": "4.3.7", 1996 + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.7.tgz", 1997 + "integrity": "sha512-x7BtAiIPSaNaWuzm24Q/mtSkv+BrISO/fmheiJ39PKRNH3RmH2Hph/bUKSOBOBC9unqfIYDhKTHwpyZycLGPVQ==", 1862 1998 "license": "Apache-2.0", 1863 1999 "dependencies": { 1864 - "@smithy/types": "^4.9.0", 2000 + "@smithy/types": "^4.11.0", 1865 2001 "tslib": "^2.6.2" 1866 2002 }, 1867 2003 "engines": { ··· 1869 2005 } 1870 2006 }, 1871 2007 "node_modules/@smithy/eventstream-serde-node": { 1872 - "version": "4.2.5", 2008 + "version": "4.2.7", 2009 + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.7.tgz", 2010 + "integrity": "sha512-roySCtHC5+pQq5lK4be1fZ/WR6s/AxnPaLfCODIPArtN2du8s5Ot4mKVK3pPtijL/L654ws592JHJ1PbZFF6+A==", 1873 2011 "license": "Apache-2.0", 1874 2012 "dependencies": { 1875 - "@smithy/eventstream-serde-universal": "^4.2.5", 1876 - "@smithy/types": "^4.9.0", 2013 + "@smithy/eventstream-serde-universal": "^4.2.7", 2014 + "@smithy/types": "^4.11.0", 1877 2015 "tslib": "^2.6.2" 1878 2016 }, 1879 2017 "engines": { ··· 1881 2019 } 1882 2020 }, 1883 2021 "node_modules/@smithy/eventstream-serde-universal": { 1884 - "version": "4.2.5", 2022 + "version": "4.2.7", 2023 + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.7.tgz", 2024 + "integrity": "sha512-QVD+g3+icFkThoy4r8wVFZMsIP08taHVKjE6Jpmz8h5CgX/kk6pTODq5cht0OMtcapUx+xrPzUTQdA+TmO0m1g==", 1885 2025 "license": "Apache-2.0", 1886 2026 "dependencies": { 1887 - "@smithy/eventstream-codec": "^4.2.5", 1888 - "@smithy/types": "^4.9.0", 2027 + "@smithy/eventstream-codec": "^4.2.7", 2028 + "@smithy/types": "^4.11.0", 1889 2029 "tslib": "^2.6.2" 1890 2030 }, 1891 2031 "engines": { ··· 1893 2033 } 1894 2034 }, 1895 2035 "node_modules/@smithy/fetch-http-handler": { 1896 - "version": "5.3.6", 2036 + "version": "5.3.8", 2037 + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.8.tgz", 2038 + "integrity": "sha512-h/Fi+o7mti4n8wx1SR6UHWLaakwHRx29sizvp8OOm7iqwKGFneT06GCSFhml6Bha5BT6ot5pj3CYZnCHhGC2Rg==", 1897 2039 "license": "Apache-2.0", 1898 2040 "dependencies": { 1899 - "@smithy/protocol-http": "^5.3.5", 1900 - "@smithy/querystring-builder": "^4.2.5", 1901 - "@smithy/types": "^4.9.0", 2041 + "@smithy/protocol-http": "^5.3.7", 2042 + "@smithy/querystring-builder": "^4.2.7", 2043 + "@smithy/types": "^4.11.0", 1902 2044 "@smithy/util-base64": "^4.3.0", 1903 2045 "tslib": "^2.6.2" 1904 2046 }, ··· 1907 2049 } 1908 2050 }, 1909 2051 "node_modules/@smithy/hash-blob-browser": { 1910 - "version": "4.2.6", 2052 + "version": "4.2.8", 2053 + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.8.tgz", 2054 + "integrity": "sha512-07InZontqsM1ggTCPSRgI7d8DirqRrnpL7nIACT4PW0AWrgDiHhjGZzbAE5UtRSiU0NISGUYe7/rri9ZeWyDpw==", 1911 2055 "license": "Apache-2.0", 1912 2056 "dependencies": { 1913 2057 "@smithy/chunked-blob-reader": "^5.2.0", 1914 2058 "@smithy/chunked-blob-reader-native": "^4.2.1", 1915 - "@smithy/types": "^4.9.0", 2059 + "@smithy/types": "^4.11.0", 1916 2060 "tslib": "^2.6.2" 1917 2061 }, 1918 2062 "engines": { ··· 1920 2064 } 1921 2065 }, 1922 2066 "node_modules/@smithy/hash-node": { 1923 - "version": "4.2.5", 2067 + "version": "4.2.7", 2068 + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.7.tgz", 2069 + "integrity": "sha512-PU/JWLTBCV1c8FtB8tEFnY4eV1tSfBc7bDBADHfn1K+uRbPgSJ9jnJp0hyjiFN2PMdPzxsf1Fdu0eo9fJ760Xw==", 1924 2070 "license": "Apache-2.0", 1925 2071 "dependencies": { 1926 - "@smithy/types": "^4.9.0", 2072 + "@smithy/types": "^4.11.0", 1927 2073 "@smithy/util-buffer-from": "^4.2.0", 1928 2074 "@smithy/util-utf8": "^4.2.0", 1929 2075 "tslib": "^2.6.2" ··· 1933 2079 } 1934 2080 }, 1935 2081 "node_modules/@smithy/hash-stream-node": { 1936 - "version": "4.2.5", 2082 + "version": "4.2.7", 2083 + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.2.7.tgz", 2084 + "integrity": "sha512-ZQVoAwNYnFMIbd4DUc517HuwNelJUY6YOzwqrbcAgCnVn+79/OK7UjwA93SPpdTOpKDVkLIzavWm/Ck7SmnDPQ==", 1937 2085 "license": "Apache-2.0", 1938 2086 "dependencies": { 1939 - "@smithy/types": "^4.9.0", 2087 + "@smithy/types": "^4.11.0", 1940 2088 "@smithy/util-utf8": "^4.2.0", 1941 2089 "tslib": "^2.6.2" 1942 2090 }, ··· 1945 2093 } 1946 2094 }, 1947 2095 "node_modules/@smithy/invalid-dependency": { 1948 - "version": "4.2.5", 2096 + "version": "4.2.7", 2097 + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.7.tgz", 2098 + "integrity": "sha512-ncvgCr9a15nPlkhIUx3CU4d7E7WEuVJOV7fS7nnK2hLtPK9tYRBkMHQbhXU1VvvKeBm/O0x26OEoBq+ngFpOEQ==", 1949 2099 "license": "Apache-2.0", 1950 2100 "dependencies": { 1951 - "@smithy/types": "^4.9.0", 2101 + "@smithy/types": "^4.11.0", 1952 2102 "tslib": "^2.6.2" 1953 2103 }, 1954 2104 "engines": { ··· 1957 2107 }, 1958 2108 "node_modules/@smithy/is-array-buffer": { 1959 2109 "version": "4.2.0", 2110 + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.0.tgz", 2111 + "integrity": "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==", 1960 2112 "license": "Apache-2.0", 1961 2113 "dependencies": { 1962 2114 "tslib": "^2.6.2" ··· 1966 2118 } 1967 2119 }, 1968 2120 "node_modules/@smithy/md5-js": { 1969 - "version": "4.2.5", 2121 + "version": "4.2.7", 2122 + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.7.tgz", 2123 + "integrity": "sha512-Wv6JcUxtOLTnxvNjDnAiATUsk8gvA6EeS8zzHig07dotpByYsLot+m0AaQEniUBjx97AC41MQR4hW0baraD1Xw==", 1970 2124 "license": "Apache-2.0", 1971 2125 "dependencies": { 1972 - "@smithy/types": "^4.9.0", 2126 + "@smithy/types": "^4.11.0", 1973 2127 "@smithy/util-utf8": "^4.2.0", 1974 2128 "tslib": "^2.6.2" 1975 2129 }, ··· 1978 2132 } 1979 2133 }, 1980 2134 "node_modules/@smithy/middleware-content-length": { 1981 - "version": "4.2.5", 2135 + "version": "4.2.7", 2136 + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.7.tgz", 2137 + "integrity": "sha512-GszfBfCcvt7kIbJ41LuNa5f0wvQCHhnGx/aDaZJCCT05Ld6x6U2s0xsc/0mBFONBZjQJp2U/0uSJ178OXOwbhg==", 1982 2138 "license": "Apache-2.0", 1983 2139 "dependencies": { 1984 - "@smithy/protocol-http": "^5.3.5", 1985 - "@smithy/types": "^4.9.0", 2140 + "@smithy/protocol-http": "^5.3.7", 2141 + "@smithy/types": "^4.11.0", 1986 2142 "tslib": "^2.6.2" 1987 2143 }, 1988 2144 "engines": { ··· 1990 2146 } 1991 2147 }, 1992 2148 "node_modules/@smithy/middleware-endpoint": { 1993 - "version": "4.3.14", 2149 + "version": "4.4.1", 2150 + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.1.tgz", 2151 + "integrity": "sha512-gpLspUAoe6f1M6H0u4cVuFzxZBrsGZmjx2O9SigurTx4PbntYa4AJ+o0G0oGm1L2oSX6oBhcGHwrfJHup2JnJg==", 1994 2152 "license": "Apache-2.0", 1995 2153 "dependencies": { 1996 - "@smithy/core": "^3.18.7", 1997 - "@smithy/middleware-serde": "^4.2.6", 1998 - "@smithy/node-config-provider": "^4.3.5", 1999 - "@smithy/shared-ini-file-loader": "^4.4.0", 2000 - "@smithy/types": "^4.9.0", 2001 - "@smithy/url-parser": "^4.2.5", 2002 - "@smithy/util-middleware": "^4.2.5", 2154 + "@smithy/core": "^3.20.0", 2155 + "@smithy/middleware-serde": "^4.2.8", 2156 + "@smithy/node-config-provider": "^4.3.7", 2157 + "@smithy/shared-ini-file-loader": "^4.4.2", 2158 + "@smithy/types": "^4.11.0", 2159 + "@smithy/url-parser": "^4.2.7", 2160 + "@smithy/util-middleware": "^4.2.7", 2003 2161 "tslib": "^2.6.2" 2004 2162 }, 2005 2163 "engines": { ··· 2007 2165 } 2008 2166 }, 2009 2167 "node_modules/@smithy/middleware-retry": { 2010 - "version": "4.4.14", 2168 + "version": "4.4.17", 2169 + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.17.tgz", 2170 + "integrity": "sha512-MqbXK6Y9uq17h+4r0ogu/sBT6V/rdV+5NvYL7ZV444BKfQygYe8wAhDrVXagVebN6w2RE0Fm245l69mOsPGZzg==", 2011 2171 "license": "Apache-2.0", 2012 2172 "dependencies": { 2013 - "@smithy/node-config-provider": "^4.3.5", 2014 - "@smithy/protocol-http": "^5.3.5", 2015 - "@smithy/service-error-classification": "^4.2.5", 2016 - "@smithy/smithy-client": "^4.9.10", 2017 - "@smithy/types": "^4.9.0", 2018 - "@smithy/util-middleware": "^4.2.5", 2019 - "@smithy/util-retry": "^4.2.5", 2173 + "@smithy/node-config-provider": "^4.3.7", 2174 + "@smithy/protocol-http": "^5.3.7", 2175 + "@smithy/service-error-classification": "^4.2.7", 2176 + "@smithy/smithy-client": "^4.10.2", 2177 + "@smithy/types": "^4.11.0", 2178 + "@smithy/util-middleware": "^4.2.7", 2179 + "@smithy/util-retry": "^4.2.7", 2020 2180 "@smithy/uuid": "^1.1.0", 2021 2181 "tslib": "^2.6.2" 2022 2182 }, ··· 2025 2185 } 2026 2186 }, 2027 2187 "node_modules/@smithy/middleware-serde": { 2028 - "version": "4.2.6", 2188 + "version": "4.2.8", 2189 + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.8.tgz", 2190 + "integrity": "sha512-8rDGYen5m5+NV9eHv9ry0sqm2gI6W7mc1VSFMtn6Igo25S507/HaOX9LTHAS2/J32VXD0xSzrY0H5FJtOMS4/w==", 2029 2191 "license": "Apache-2.0", 2030 2192 "dependencies": { 2031 - "@smithy/protocol-http": "^5.3.5", 2032 - "@smithy/types": "^4.9.0", 2193 + "@smithy/protocol-http": "^5.3.7", 2194 + "@smithy/types": "^4.11.0", 2033 2195 "tslib": "^2.6.2" 2034 2196 }, 2035 2197 "engines": { ··· 2037 2199 } 2038 2200 }, 2039 2201 "node_modules/@smithy/middleware-stack": { 2040 - "version": "4.2.5", 2202 + "version": "4.2.7", 2203 + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.7.tgz", 2204 + "integrity": "sha512-bsOT0rJ+HHlZd9crHoS37mt8qRRN/h9jRve1SXUhVbkRzu0QaNYZp1i1jha4n098tsvROjcwfLlfvcFuJSXEsw==", 2041 2205 "license": "Apache-2.0", 2042 2206 "dependencies": { 2043 - "@smithy/types": "^4.9.0", 2207 + "@smithy/types": "^4.11.0", 2044 2208 "tslib": "^2.6.2" 2045 2209 }, 2046 2210 "engines": { ··· 2048 2212 } 2049 2213 }, 2050 2214 "node_modules/@smithy/node-config-provider": { 2051 - "version": "4.3.5", 2215 + "version": "4.3.7", 2216 + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.7.tgz", 2217 + "integrity": "sha512-7r58wq8sdOcrwWe+klL9y3bc4GW1gnlfnFOuL7CXa7UzfhzhxKuzNdtqgzmTV+53lEp9NXh5hY/S4UgjLOzPfw==", 2052 2218 "license": "Apache-2.0", 2053 2219 "dependencies": { 2054 - "@smithy/property-provider": "^4.2.5", 2055 - "@smithy/shared-ini-file-loader": "^4.4.0", 2056 - "@smithy/types": "^4.9.0", 2220 + "@smithy/property-provider": "^4.2.7", 2221 + "@smithy/shared-ini-file-loader": "^4.4.2", 2222 + "@smithy/types": "^4.11.0", 2057 2223 "tslib": "^2.6.2" 2058 2224 }, 2059 2225 "engines": { ··· 2061 2227 } 2062 2228 }, 2063 2229 "node_modules/@smithy/node-http-handler": { 2064 - "version": "4.4.5", 2230 + "version": "4.4.7", 2231 + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.7.tgz", 2232 + "integrity": "sha512-NELpdmBOO6EpZtWgQiHjoShs1kmweaiNuETUpuup+cmm/xJYjT4eUjfhrXRP4jCOaAsS3c3yPsP3B+K+/fyPCQ==", 2065 2233 "license": "Apache-2.0", 2066 2234 "dependencies": { 2067 - "@smithy/abort-controller": "^4.2.5", 2068 - "@smithy/protocol-http": "^5.3.5", 2069 - "@smithy/querystring-builder": "^4.2.5", 2070 - "@smithy/types": "^4.9.0", 2235 + "@smithy/abort-controller": "^4.2.7", 2236 + "@smithy/protocol-http": "^5.3.7", 2237 + "@smithy/querystring-builder": "^4.2.7", 2238 + "@smithy/types": "^4.11.0", 2071 2239 "tslib": "^2.6.2" 2072 2240 }, 2073 2241 "engines": { ··· 2075 2243 } 2076 2244 }, 2077 2245 "node_modules/@smithy/property-provider": { 2078 - "version": "4.2.5", 2246 + "version": "4.2.7", 2247 + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.7.tgz", 2248 + "integrity": "sha512-jmNYKe9MGGPoSl/D7JDDs1C8b3dC8f/w78LbaVfoTtWy4xAd5dfjaFG9c9PWPihY4ggMQNQSMtzU77CNgAJwmA==", 2079 2249 "license": "Apache-2.0", 2080 2250 "dependencies": { 2081 - "@smithy/types": "^4.9.0", 2251 + "@smithy/types": "^4.11.0", 2082 2252 "tslib": "^2.6.2" 2083 2253 }, 2084 2254 "engines": { ··· 2086 2256 } 2087 2257 }, 2088 2258 "node_modules/@smithy/protocol-http": { 2089 - "version": "5.3.5", 2259 + "version": "5.3.7", 2260 + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.7.tgz", 2261 + "integrity": "sha512-1r07pb994I20dD/c2seaZhoCuNYm0rWrvBxhCQ70brNh11M5Ml2ew6qJVo0lclB3jMIXirD4s2XRXRe7QEi0xA==", 2090 2262 "license": "Apache-2.0", 2091 2263 "dependencies": { 2092 - "@smithy/types": "^4.9.0", 2264 + "@smithy/types": "^4.11.0", 2093 2265 "tslib": "^2.6.2" 2094 2266 }, 2095 2267 "engines": { ··· 2097 2269 } 2098 2270 }, 2099 2271 "node_modules/@smithy/querystring-builder": { 2100 - "version": "4.2.5", 2272 + "version": "4.2.7", 2273 + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.7.tgz", 2274 + "integrity": "sha512-eKONSywHZxK4tBxe2lXEysh8wbBdvDWiA+RIuaxZSgCMmA0zMgoDpGLJhnyj+c0leOQprVnXOmcB4m+W9Rw7sg==", 2101 2275 "license": "Apache-2.0", 2102 2276 "dependencies": { 2103 - "@smithy/types": "^4.9.0", 2277 + "@smithy/types": "^4.11.0", 2104 2278 "@smithy/util-uri-escape": "^4.2.0", 2105 2279 "tslib": "^2.6.2" 2106 2280 }, ··· 2109 2283 } 2110 2284 }, 2111 2285 "node_modules/@smithy/querystring-parser": { 2112 - "version": "4.2.5", 2286 + "version": "4.2.7", 2287 + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.7.tgz", 2288 + "integrity": "sha512-3X5ZvzUHmlSTHAXFlswrS6EGt8fMSIxX/c3Rm1Pni3+wYWB6cjGocmRIoqcQF9nU5OgGmL0u7l9m44tSUpfj9w==", 2113 2289 "license": "Apache-2.0", 2114 2290 "dependencies": { 2115 - "@smithy/types": "^4.9.0", 2291 + "@smithy/types": "^4.11.0", 2116 2292 "tslib": "^2.6.2" 2117 2293 }, 2118 2294 "engines": { ··· 2120 2296 } 2121 2297 }, 2122 2298 "node_modules/@smithy/service-error-classification": { 2123 - "version": "4.2.5", 2299 + "version": "4.2.7", 2300 + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.7.tgz", 2301 + "integrity": "sha512-YB7oCbukqEb2Dlh3340/8g8vNGbs/QsNNRms+gv3N2AtZz9/1vSBx6/6tpwQpZMEJFs7Uq8h4mmOn48ZZ72MkA==", 2124 2302 "license": "Apache-2.0", 2125 2303 "dependencies": { 2126 - "@smithy/types": "^4.9.0" 2304 + "@smithy/types": "^4.11.0" 2127 2305 }, 2128 2306 "engines": { 2129 2307 "node": ">=18.0.0" 2130 2308 } 2131 2309 }, 2132 2310 "node_modules/@smithy/shared-ini-file-loader": { 2133 - "version": "4.4.0", 2311 + "version": "4.4.2", 2312 + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.2.tgz", 2313 + "integrity": "sha512-M7iUUff/KwfNunmrgtqBfvZSzh3bmFgv/j/t1Y1dQ+8dNo34br1cqVEqy6v0mYEgi0DkGO7Xig0AnuOaEGVlcg==", 2134 2314 "license": "Apache-2.0", 2135 2315 "dependencies": { 2136 - "@smithy/types": "^4.9.0", 2316 + "@smithy/types": "^4.11.0", 2137 2317 "tslib": "^2.6.2" 2138 2318 }, 2139 2319 "engines": { ··· 2141 2321 } 2142 2322 }, 2143 2323 "node_modules/@smithy/signature-v4": { 2144 - "version": "5.3.5", 2324 + "version": "5.3.7", 2325 + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.7.tgz", 2326 + "integrity": "sha512-9oNUlqBlFZFOSdxgImA6X5GFuzE7V2H7VG/7E70cdLhidFbdtvxxt81EHgykGK5vq5D3FafH//X+Oy31j3CKOg==", 2145 2327 "license": "Apache-2.0", 2146 2328 "dependencies": { 2147 2329 "@smithy/is-array-buffer": "^4.2.0", 2148 - "@smithy/protocol-http": "^5.3.5", 2149 - "@smithy/types": "^4.9.0", 2330 + "@smithy/protocol-http": "^5.3.7", 2331 + "@smithy/types": "^4.11.0", 2150 2332 "@smithy/util-hex-encoding": "^4.2.0", 2151 - "@smithy/util-middleware": "^4.2.5", 2333 + "@smithy/util-middleware": "^4.2.7", 2152 2334 "@smithy/util-uri-escape": "^4.2.0", 2153 2335 "@smithy/util-utf8": "^4.2.0", 2154 2336 "tslib": "^2.6.2" ··· 2158 2340 } 2159 2341 }, 2160 2342 "node_modules/@smithy/smithy-client": { 2161 - "version": "4.9.10", 2343 + "version": "4.10.2", 2344 + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.10.2.tgz", 2345 + "integrity": "sha512-D5z79xQWpgrGpAHb054Fn2CCTQZpog7JELbVQ6XAvXs5MNKWf28U9gzSBlJkOyMl9LA1TZEjRtwvGXfP0Sl90g==", 2162 2346 "license": "Apache-2.0", 2163 2347 "dependencies": { 2164 - "@smithy/core": "^3.18.7", 2165 - "@smithy/middleware-endpoint": "^4.3.14", 2166 - "@smithy/middleware-stack": "^4.2.5", 2167 - "@smithy/protocol-http": "^5.3.5", 2168 - "@smithy/types": "^4.9.0", 2169 - "@smithy/util-stream": "^4.5.6", 2348 + "@smithy/core": "^3.20.0", 2349 + "@smithy/middleware-endpoint": "^4.4.1", 2350 + "@smithy/middleware-stack": "^4.2.7", 2351 + "@smithy/protocol-http": "^5.3.7", 2352 + "@smithy/types": "^4.11.0", 2353 + "@smithy/util-stream": "^4.5.8", 2170 2354 "tslib": "^2.6.2" 2171 2355 }, 2172 2356 "engines": { ··· 2174 2358 } 2175 2359 }, 2176 2360 "node_modules/@smithy/types": { 2177 - "version": "4.9.0", 2361 + "version": "4.11.0", 2362 + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.11.0.tgz", 2363 + "integrity": "sha512-mlrmL0DRDVe3mNrjTcVcZEgkFmufITfUAPBEA+AHYiIeYyJebso/He1qLbP3PssRe22KUzLRpQSdBPbXdgZ2VA==", 2178 2364 "license": "Apache-2.0", 2179 2365 "dependencies": { 2180 2366 "tslib": "^2.6.2" ··· 2184 2370 } 2185 2371 }, 2186 2372 "node_modules/@smithy/url-parser": { 2187 - "version": "4.2.5", 2373 + "version": "4.2.7", 2374 + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.7.tgz", 2375 + "integrity": "sha512-/RLtVsRV4uY3qPWhBDsjwahAtt3x2IsMGnP5W1b2VZIe+qgCqkLxI1UOHDZp1Q1QSOrdOR32MF3Ph2JfWT1VHg==", 2188 2376 "license": "Apache-2.0", 2189 2377 "dependencies": { 2190 - "@smithy/querystring-parser": "^4.2.5", 2191 - "@smithy/types": "^4.9.0", 2378 + "@smithy/querystring-parser": "^4.2.7", 2379 + "@smithy/types": "^4.11.0", 2192 2380 "tslib": "^2.6.2" 2193 2381 }, 2194 2382 "engines": { ··· 2197 2385 }, 2198 2386 "node_modules/@smithy/util-base64": { 2199 2387 "version": "4.3.0", 2388 + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.0.tgz", 2389 + "integrity": "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==", 2200 2390 "license": "Apache-2.0", 2201 2391 "dependencies": { 2202 2392 "@smithy/util-buffer-from": "^4.2.0", ··· 2209 2399 }, 2210 2400 "node_modules/@smithy/util-body-length-browser": { 2211 2401 "version": "4.2.0", 2402 + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.0.tgz", 2403 + "integrity": "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==", 2212 2404 "license": "Apache-2.0", 2213 2405 "dependencies": { 2214 2406 "tslib": "^2.6.2" ··· 2219 2411 }, 2220 2412 "node_modules/@smithy/util-body-length-node": { 2221 2413 "version": "4.2.1", 2414 + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.1.tgz", 2415 + "integrity": "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==", 2222 2416 "license": "Apache-2.0", 2223 2417 "dependencies": { 2224 2418 "tslib": "^2.6.2" ··· 2229 2423 }, 2230 2424 "node_modules/@smithy/util-buffer-from": { 2231 2425 "version": "4.2.0", 2426 + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.0.tgz", 2427 + "integrity": "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==", 2232 2428 "license": "Apache-2.0", 2233 2429 "dependencies": { 2234 2430 "@smithy/is-array-buffer": "^4.2.0", ··· 2240 2436 }, 2241 2437 "node_modules/@smithy/util-config-provider": { 2242 2438 "version": "4.2.0", 2439 + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.0.tgz", 2440 + "integrity": "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==", 2243 2441 "license": "Apache-2.0", 2244 2442 "dependencies": { 2245 2443 "tslib": "^2.6.2" ··· 2249 2447 } 2250 2448 }, 2251 2449 "node_modules/@smithy/util-defaults-mode-browser": { 2252 - "version": "4.3.13", 2450 + "version": "4.3.16", 2451 + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.16.tgz", 2452 + "integrity": "sha512-/eiSP3mzY3TsvUOYMeL4EqUX6fgUOj2eUOU4rMMgVbq67TiRLyxT7Xsjxq0bW3OwuzK009qOwF0L2OgJqperAQ==", 2253 2453 "license": "Apache-2.0", 2254 2454 "dependencies": { 2255 - "@smithy/property-provider": "^4.2.5", 2256 - "@smithy/smithy-client": "^4.9.10", 2257 - "@smithy/types": "^4.9.0", 2455 + "@smithy/property-provider": "^4.2.7", 2456 + "@smithy/smithy-client": "^4.10.2", 2457 + "@smithy/types": "^4.11.0", 2258 2458 "tslib": "^2.6.2" 2259 2459 }, 2260 2460 "engines": { ··· 2262 2462 } 2263 2463 }, 2264 2464 "node_modules/@smithy/util-defaults-mode-node": { 2265 - "version": "4.2.16", 2465 + "version": "4.2.19", 2466 + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.19.tgz", 2467 + "integrity": "sha512-3a4+4mhf6VycEJyHIQLypRbiwG6aJvbQAeRAVXydMmfweEPnLLabRbdyo/Pjw8Rew9vjsh5WCdhmDaHkQnhhhA==", 2266 2468 "license": "Apache-2.0", 2267 2469 "dependencies": { 2268 - "@smithy/config-resolver": "^4.4.3", 2269 - "@smithy/credential-provider-imds": "^4.2.5", 2270 - "@smithy/node-config-provider": "^4.3.5", 2271 - "@smithy/property-provider": "^4.2.5", 2272 - "@smithy/smithy-client": "^4.9.10", 2273 - "@smithy/types": "^4.9.0", 2470 + "@smithy/config-resolver": "^4.4.5", 2471 + "@smithy/credential-provider-imds": "^4.2.7", 2472 + "@smithy/node-config-provider": "^4.3.7", 2473 + "@smithy/property-provider": "^4.2.7", 2474 + "@smithy/smithy-client": "^4.10.2", 2475 + "@smithy/types": "^4.11.0", 2274 2476 "tslib": "^2.6.2" 2275 2477 }, 2276 2478 "engines": { ··· 2278 2480 } 2279 2481 }, 2280 2482 "node_modules/@smithy/util-endpoints": { 2281 - "version": "3.2.5", 2483 + "version": "3.2.7", 2484 + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.7.tgz", 2485 + "integrity": "sha512-s4ILhyAvVqhMDYREeTS68R43B1V5aenV5q/V1QpRQJkCXib5BPRo4s7uNdzGtIKxaPHCfU/8YkvPAEvTpxgspg==", 2282 2486 "license": "Apache-2.0", 2283 2487 "dependencies": { 2284 - "@smithy/node-config-provider": "^4.3.5", 2285 - "@smithy/types": "^4.9.0", 2488 + "@smithy/node-config-provider": "^4.3.7", 2489 + "@smithy/types": "^4.11.0", 2286 2490 "tslib": "^2.6.2" 2287 2491 }, 2288 2492 "engines": { ··· 2291 2495 }, 2292 2496 "node_modules/@smithy/util-hex-encoding": { 2293 2497 "version": "4.2.0", 2498 + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.0.tgz", 2499 + "integrity": "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==", 2294 2500 "license": "Apache-2.0", 2295 2501 "dependencies": { 2296 2502 "tslib": "^2.6.2" ··· 2300 2506 } 2301 2507 }, 2302 2508 "node_modules/@smithy/util-middleware": { 2303 - "version": "4.2.5", 2509 + "version": "4.2.7", 2510 + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.7.tgz", 2511 + "integrity": "sha512-i1IkpbOae6NvIKsEeLLM9/2q4X+M90KV3oCFgWQI4q0Qz+yUZvsr+gZPdAEAtFhWQhAHpTsJO8DRJPuwVyln+w==", 2304 2512 "license": "Apache-2.0", 2305 2513 "dependencies": { 2306 - "@smithy/types": "^4.9.0", 2514 + "@smithy/types": "^4.11.0", 2307 2515 "tslib": "^2.6.2" 2308 2516 }, 2309 2517 "engines": { ··· 2311 2519 } 2312 2520 }, 2313 2521 "node_modules/@smithy/util-retry": { 2314 - "version": "4.2.5", 2522 + "version": "4.2.7", 2523 + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.7.tgz", 2524 + "integrity": "sha512-SvDdsQyF5CIASa4EYVT02LukPHVzAgUA4kMAuZ97QJc2BpAqZfA4PINB8/KOoCXEw9tsuv/jQjMeaHFvxdLNGg==", 2315 2525 "license": "Apache-2.0", 2316 2526 "dependencies": { 2317 - "@smithy/service-error-classification": "^4.2.5", 2318 - "@smithy/types": "^4.9.0", 2527 + "@smithy/service-error-classification": "^4.2.7", 2528 + "@smithy/types": "^4.11.0", 2319 2529 "tslib": "^2.6.2" 2320 2530 }, 2321 2531 "engines": { ··· 2323 2533 } 2324 2534 }, 2325 2535 "node_modules/@smithy/util-stream": { 2326 - "version": "4.5.6", 2536 + "version": "4.5.8", 2537 + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.8.tgz", 2538 + "integrity": "sha512-ZnnBhTapjM0YPGUSmOs0Mcg/Gg87k503qG4zU2v/+Js2Gu+daKOJMeqcQns8ajepY8tgzzfYxl6kQyZKml6O2w==", 2327 2539 "license": "Apache-2.0", 2328 2540 "dependencies": { 2329 - "@smithy/fetch-http-handler": "^5.3.6", 2330 - "@smithy/node-http-handler": "^4.4.5", 2331 - "@smithy/types": "^4.9.0", 2541 + "@smithy/fetch-http-handler": "^5.3.8", 2542 + "@smithy/node-http-handler": "^4.4.7", 2543 + "@smithy/types": "^4.11.0", 2332 2544 "@smithy/util-base64": "^4.3.0", 2333 2545 "@smithy/util-buffer-from": "^4.2.0", 2334 2546 "@smithy/util-hex-encoding": "^4.2.0", ··· 2341 2553 }, 2342 2554 "node_modules/@smithy/util-uri-escape": { 2343 2555 "version": "4.2.0", 2556 + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.0.tgz", 2557 + "integrity": "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==", 2344 2558 "license": "Apache-2.0", 2345 2559 "dependencies": { 2346 2560 "tslib": "^2.6.2" ··· 2351 2565 }, 2352 2566 "node_modules/@smithy/util-utf8": { 2353 2567 "version": "4.2.0", 2568 + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.0.tgz", 2569 + "integrity": "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==", 2354 2570 "license": "Apache-2.0", 2355 2571 "dependencies": { 2356 2572 "@smithy/util-buffer-from": "^4.2.0", ··· 2361 2577 } 2362 2578 }, 2363 2579 "node_modules/@smithy/util-waiter": { 2364 - "version": "4.2.5", 2580 + "version": "4.2.7", 2581 + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.7.tgz", 2582 + "integrity": "sha512-vHJFXi9b7kUEpHWUCY3Twl+9NPOZvQ0SAi+Ewtn48mbiJk4JY9MZmKQjGB4SCvVb9WPiSphZJYY6RIbs+grrzw==", 2365 2583 "license": "Apache-2.0", 2366 2584 "dependencies": { 2367 - "@smithy/abort-controller": "^4.2.5", 2368 - "@smithy/types": "^4.9.0", 2585 + "@smithy/abort-controller": "^4.2.7", 2586 + "@smithy/types": "^4.11.0", 2369 2587 "tslib": "^2.6.2" 2370 2588 }, 2371 2589 "engines": { ··· 2374 2592 }, 2375 2593 "node_modules/@smithy/uuid": { 2376 2594 "version": "1.1.0", 2595 + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.0.tgz", 2596 + "integrity": "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==", 2377 2597 "license": "Apache-2.0", 2378 2598 "dependencies": { 2379 2599 "tslib": "^2.6.2" ··· 2434 2654 "version": "24.10.1", 2435 2655 "dev": true, 2436 2656 "license": "MIT", 2437 - "peer": true, 2438 2657 "dependencies": { 2439 2658 "undici-types": "~7.16.0" 2440 2659 } 2441 2660 }, 2442 2661 "node_modules/@typescript-eslint/eslint-plugin": { 2443 - "version": "8.49.0", 2662 + "version": "8.50.0", 2663 + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.50.0.tgz", 2664 + "integrity": "sha512-O7QnmOXYKVtPrfYzMolrCTfkezCJS9+ljLdKW/+DCvRsc3UAz+sbH6Xcsv7p30+0OwUbeWfUDAQE0vpabZ3QLg==", 2444 2665 "dev": true, 2445 2666 "license": "MIT", 2446 2667 "dependencies": { 2447 2668 "@eslint-community/regexpp": "^4.10.0", 2448 - "@typescript-eslint/scope-manager": "8.49.0", 2449 - "@typescript-eslint/type-utils": "8.49.0", 2450 - "@typescript-eslint/utils": "8.49.0", 2451 - "@typescript-eslint/visitor-keys": "8.49.0", 2669 + "@typescript-eslint/scope-manager": "8.50.0", 2670 + "@typescript-eslint/type-utils": "8.50.0", 2671 + "@typescript-eslint/utils": "8.50.0", 2672 + "@typescript-eslint/visitor-keys": "8.50.0", 2452 2673 "ignore": "^7.0.0", 2453 2674 "natural-compare": "^1.4.0", 2454 2675 "ts-api-utils": "^2.1.0" ··· 2461 2682 "url": "https://opencollective.com/typescript-eslint" 2462 2683 }, 2463 2684 "peerDependencies": { 2464 - "@typescript-eslint/parser": "^8.49.0", 2685 + "@typescript-eslint/parser": "^8.50.0", 2465 2686 "eslint": "^8.57.0 || ^9.0.0", 2466 2687 "typescript": ">=4.8.4 <6.0.0" 2467 2688 } 2468 2689 }, 2469 2690 "node_modules/@typescript-eslint/parser": { 2470 - "version": "8.49.0", 2691 + "version": "8.50.0", 2692 + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.50.0.tgz", 2693 + "integrity": "sha512-6/cmF2piao+f6wSxUsJLZjck7OQsYyRtcOZS02k7XINSNlz93v6emM8WutDQSXnroG2xwYlEVHJI+cPA7CPM3Q==", 2471 2694 "dev": true, 2472 2695 "license": "MIT", 2473 2696 "peer": true, 2474 2697 "dependencies": { 2475 - "@typescript-eslint/scope-manager": "8.49.0", 2476 - "@typescript-eslint/types": "8.49.0", 2477 - "@typescript-eslint/typescript-estree": "8.49.0", 2478 - "@typescript-eslint/visitor-keys": "8.49.0", 2698 + "@typescript-eslint/scope-manager": "8.50.0", 2699 + "@typescript-eslint/types": "8.50.0", 2700 + "@typescript-eslint/typescript-estree": "8.50.0", 2701 + "@typescript-eslint/visitor-keys": "8.50.0", 2479 2702 "debug": "^4.3.4" 2480 2703 }, 2481 2704 "engines": { ··· 2491 2714 } 2492 2715 }, 2493 2716 "node_modules/@typescript-eslint/project-service": { 2494 - "version": "8.49.0", 2717 + "version": "8.50.0", 2718 + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.50.0.tgz", 2719 + "integrity": "sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==", 2495 2720 "dev": true, 2496 2721 "license": "MIT", 2497 2722 "dependencies": { 2498 - "@typescript-eslint/tsconfig-utils": "^8.49.0", 2499 - "@typescript-eslint/types": "^8.49.0", 2723 + "@typescript-eslint/tsconfig-utils": "^8.50.0", 2724 + "@typescript-eslint/types": "^8.50.0", 2500 2725 "debug": "^4.3.4" 2501 2726 }, 2502 2727 "engines": { ··· 2511 2736 } 2512 2737 }, 2513 2738 "node_modules/@typescript-eslint/scope-manager": { 2514 - "version": "8.49.0", 2739 + "version": "8.50.0", 2740 + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.50.0.tgz", 2741 + "integrity": "sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A==", 2515 2742 "dev": true, 2516 2743 "license": "MIT", 2517 2744 "dependencies": { 2518 - "@typescript-eslint/types": "8.49.0", 2519 - "@typescript-eslint/visitor-keys": "8.49.0" 2745 + "@typescript-eslint/types": "8.50.0", 2746 + "@typescript-eslint/visitor-keys": "8.50.0" 2520 2747 }, 2521 2748 "engines": { 2522 2749 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" ··· 2527 2754 } 2528 2755 }, 2529 2756 "node_modules/@typescript-eslint/tsconfig-utils": { 2530 - "version": "8.49.0", 2757 + "version": "8.50.0", 2758 + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.0.tgz", 2759 + "integrity": "sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==", 2531 2760 "dev": true, 2532 2761 "license": "MIT", 2533 2762 "engines": { ··· 2542 2771 } 2543 2772 }, 2544 2773 "node_modules/@typescript-eslint/type-utils": { 2545 - "version": "8.49.0", 2774 + "version": "8.50.0", 2775 + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.50.0.tgz", 2776 + "integrity": "sha512-7OciHT2lKCewR0mFoBrvZJ4AXTMe/sYOe87289WAViOocEmDjjv8MvIOT2XESuKj9jp8u3SZYUSh89QA4S1kQw==", 2546 2777 "dev": true, 2547 2778 "license": "MIT", 2548 2779 "dependencies": { 2549 - "@typescript-eslint/types": "8.49.0", 2550 - "@typescript-eslint/typescript-estree": "8.49.0", 2551 - "@typescript-eslint/utils": "8.49.0", 2780 + "@typescript-eslint/types": "8.50.0", 2781 + "@typescript-eslint/typescript-estree": "8.50.0", 2782 + "@typescript-eslint/utils": "8.50.0", 2552 2783 "debug": "^4.3.4", 2553 2784 "ts-api-utils": "^2.1.0" 2554 2785 }, ··· 2565 2796 } 2566 2797 }, 2567 2798 "node_modules/@typescript-eslint/types": { 2568 - "version": "8.49.0", 2799 + "version": "8.50.0", 2800 + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.50.0.tgz", 2801 + "integrity": "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==", 2569 2802 "dev": true, 2570 2803 "license": "MIT", 2571 2804 "engines": { ··· 2577 2810 } 2578 2811 }, 2579 2812 "node_modules/@typescript-eslint/typescript-estree": { 2580 - "version": "8.49.0", 2813 + "version": "8.50.0", 2814 + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.0.tgz", 2815 + "integrity": "sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==", 2581 2816 "dev": true, 2582 2817 "license": "MIT", 2583 2818 "dependencies": { 2584 - "@typescript-eslint/project-service": "8.49.0", 2585 - "@typescript-eslint/tsconfig-utils": "8.49.0", 2586 - "@typescript-eslint/types": "8.49.0", 2587 - "@typescript-eslint/visitor-keys": "8.49.0", 2819 + "@typescript-eslint/project-service": "8.50.0", 2820 + "@typescript-eslint/tsconfig-utils": "8.50.0", 2821 + "@typescript-eslint/types": "8.50.0", 2822 + "@typescript-eslint/visitor-keys": "8.50.0", 2588 2823 "debug": "^4.3.4", 2589 2824 "minimatch": "^9.0.4", 2590 2825 "semver": "^7.6.0", ··· 2602 2837 "typescript": ">=4.8.4 <6.0.0" 2603 2838 } 2604 2839 }, 2840 + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { 2841 + "version": "2.0.2", 2842 + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", 2843 + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", 2844 + "dev": true, 2845 + "license": "MIT", 2846 + "dependencies": { 2847 + "balanced-match": "^1.0.0" 2848 + } 2849 + }, 2605 2850 "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { 2606 2851 "version": "9.0.5", 2852 + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 2853 + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 2607 2854 "dev": true, 2608 2855 "license": "ISC", 2609 2856 "dependencies": { ··· 2616 2863 "url": "https://github.com/sponsors/isaacs" 2617 2864 } 2618 2865 }, 2619 - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch/node_modules/brace-expansion": { 2620 - "version": "2.0.2", 2621 - "dev": true, 2622 - "license": "MIT", 2623 - "dependencies": { 2624 - "balanced-match": "^1.0.0" 2625 - } 2626 - }, 2627 2866 "node_modules/@typescript-eslint/utils": { 2628 - "version": "8.49.0", 2867 + "version": "8.50.0", 2868 + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.50.0.tgz", 2869 + "integrity": "sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==", 2629 2870 "dev": true, 2630 2871 "license": "MIT", 2631 2872 "dependencies": { 2632 2873 "@eslint-community/eslint-utils": "^4.7.0", 2633 - "@typescript-eslint/scope-manager": "8.49.0", 2634 - "@typescript-eslint/types": "8.49.0", 2635 - "@typescript-eslint/typescript-estree": "8.49.0" 2874 + "@typescript-eslint/scope-manager": "8.50.0", 2875 + "@typescript-eslint/types": "8.50.0", 2876 + "@typescript-eslint/typescript-estree": "8.50.0" 2636 2877 }, 2637 2878 "engines": { 2638 2879 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" ··· 2647 2888 } 2648 2889 }, 2649 2890 "node_modules/@typescript-eslint/visitor-keys": { 2650 - "version": "8.49.0", 2891 + "version": "8.50.0", 2892 + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.50.0.tgz", 2893 + "integrity": "sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==", 2651 2894 "dev": true, 2652 2895 "license": "MIT", 2653 2896 "dependencies": { 2654 - "@typescript-eslint/types": "8.49.0", 2897 + "@typescript-eslint/types": "8.50.0", 2655 2898 "eslint-visitor-keys": "^4.2.1" 2656 2899 }, 2657 2900 "engines": { ··· 2664 2907 }, 2665 2908 "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { 2666 2909 "version": "4.2.1", 2910 + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", 2911 + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", 2667 2912 "dev": true, 2668 2913 "license": "Apache-2.0", 2669 2914 "engines": { ··· 2845 3090 "dev": true, 2846 3091 "license": "MIT" 2847 3092 }, 3093 + "node_modules/base64-js": { 3094 + "version": "1.5.1", 3095 + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 3096 + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 3097 + "funding": [ 3098 + { 3099 + "type": "github", 3100 + "url": "https://github.com/sponsors/feross" 3101 + }, 3102 + { 3103 + "type": "patreon", 3104 + "url": "https://www.patreon.com/feross" 3105 + }, 3106 + { 3107 + "type": "consulting", 3108 + "url": "https://feross.org/support" 3109 + } 3110 + ], 3111 + "license": "MIT" 3112 + }, 2848 3113 "node_modules/bowser": { 2849 3114 "version": "2.13.1", 3115 + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.13.1.tgz", 3116 + "integrity": "sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==", 2850 3117 "license": "MIT" 2851 3118 }, 2852 3119 "node_modules/brace-expansion": { ··· 2858 3125 "dependencies": { 2859 3126 "balanced-match": "^1.0.0", 2860 3127 "concat-map": "0.0.1" 3128 + } 3129 + }, 3130 + "node_modules/buffer": { 3131 + "version": "5.6.0", 3132 + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", 3133 + "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", 3134 + "license": "MIT", 3135 + "dependencies": { 3136 + "base64-js": "^1.0.2", 3137 + "ieee754": "^1.1.4" 2861 3138 } 2862 3139 }, 2863 3140 "node_modules/bun-types": { ··· 3073 3350 }, 3074 3351 "peerDependenciesMeta": { 3075 3352 "jiti": { 3353 + "optional": true 3354 + } 3355 + } 3356 + }, 3357 + "node_modules/eslint-config-prettier": { 3358 + "version": "10.1.8", 3359 + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", 3360 + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", 3361 + "dev": true, 3362 + "license": "MIT", 3363 + "peer": true, 3364 + "bin": { 3365 + "eslint-config-prettier": "bin/cli.js" 3366 + }, 3367 + "funding": { 3368 + "url": "https://opencollective.com/eslint-config-prettier" 3369 + }, 3370 + "peerDependencies": { 3371 + "eslint": ">=7.0.0" 3372 + } 3373 + }, 3374 + "node_modules/eslint-plugin-prettier": { 3375 + "version": "5.5.4", 3376 + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.4.tgz", 3377 + "integrity": "sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==", 3378 + "dev": true, 3379 + "license": "MIT", 3380 + "dependencies": { 3381 + "prettier-linter-helpers": "^1.0.0", 3382 + "synckit": "^0.11.7" 3383 + }, 3384 + "engines": { 3385 + "node": "^14.18.0 || >=16.0.0" 3386 + }, 3387 + "funding": { 3388 + "url": "https://opencollective.com/eslint-plugin-prettier" 3389 + }, 3390 + "peerDependencies": { 3391 + "@types/eslint": ">=8.0.0", 3392 + "eslint": ">=8.0.0", 3393 + "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", 3394 + "prettier": ">=3.0.0" 3395 + }, 3396 + "peerDependenciesMeta": { 3397 + "@types/eslint": { 3398 + "optional": true 3399 + }, 3400 + "eslint-config-prettier": { 3076 3401 "optional": true 3077 3402 } 3078 3403 } ··· 3207 3532 "node": ">=0.10.0" 3208 3533 } 3209 3534 }, 3535 + "node_modules/events": { 3536 + "version": "3.3.0", 3537 + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", 3538 + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", 3539 + "license": "MIT", 3540 + "engines": { 3541 + "node": ">=0.8.x" 3542 + } 3543 + }, 3210 3544 "node_modules/expect-type": { 3211 3545 "version": "1.3.0", 3212 3546 "dev": true, ··· 3222 3556 "dev": true, 3223 3557 "license": "MIT" 3224 3558 }, 3559 + "node_modules/fast-diff": { 3560 + "version": "1.3.0", 3561 + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", 3562 + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", 3563 + "dev": true, 3564 + "license": "Apache-2.0" 3565 + }, 3225 3566 "node_modules/fast-json-stable-stringify": { 3226 3567 "version": "2.1.0", 3227 3568 "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", ··· 3236 3577 }, 3237 3578 "node_modules/fast-xml-parser": { 3238 3579 "version": "5.2.5", 3580 + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.5.tgz", 3581 + "integrity": "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==", 3239 3582 "funding": [ 3240 3583 { 3241 3584 "type": "github", ··· 3377 3720 "node": ">=16.9.0" 3378 3721 } 3379 3722 }, 3723 + "node_modules/ieee754": { 3724 + "version": "1.2.1", 3725 + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 3726 + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 3727 + "funding": [ 3728 + { 3729 + "type": "github", 3730 + "url": "https://github.com/sponsors/feross" 3731 + }, 3732 + { 3733 + "type": "patreon", 3734 + "url": "https://www.patreon.com/feross" 3735 + }, 3736 + { 3737 + "type": "consulting", 3738 + "url": "https://feross.org/support" 3739 + } 3740 + ], 3741 + "license": "BSD-3-Clause" 3742 + }, 3380 3743 "node_modules/ignore": { 3381 3744 "version": "7.0.5", 3382 3745 "dev": true, ··· 3409 3772 "engines": { 3410 3773 "node": ">=0.8.19" 3411 3774 } 3775 + }, 3776 + "node_modules/inherits": { 3777 + "version": "2.0.4", 3778 + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 3779 + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 3780 + "license": "ISC" 3412 3781 }, 3413 3782 "node_modules/is-extglob": { 3414 3783 "version": "2.1.1", ··· 3715 4084 "node": ">= 0.8.0" 3716 4085 } 3717 4086 }, 4087 + "node_modules/prettier": { 4088 + "version": "3.7.4", 4089 + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz", 4090 + "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", 4091 + "dev": true, 4092 + "license": "MIT", 4093 + "peer": true, 4094 + "bin": { 4095 + "prettier": "bin/prettier.cjs" 4096 + }, 4097 + "engines": { 4098 + "node": ">=14" 4099 + }, 4100 + "funding": { 4101 + "url": "https://github.com/prettier/prettier?sponsor=1" 4102 + } 4103 + }, 4104 + "node_modules/prettier-linter-helpers": { 4105 + "version": "1.0.0", 4106 + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", 4107 + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", 4108 + "dev": true, 4109 + "license": "MIT", 4110 + "dependencies": { 4111 + "fast-diff": "^1.1.2" 4112 + }, 4113 + "engines": { 4114 + "node": ">=6.0.0" 4115 + } 4116 + }, 3718 4117 "node_modules/punycode": { 3719 4118 "version": "2.3.1", 3720 4119 "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", ··· 3723 4122 "license": "MIT", 3724 4123 "engines": { 3725 4124 "node": ">=6" 4125 + } 4126 + }, 4127 + "node_modules/readable-stream": { 4128 + "version": "3.6.2", 4129 + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 4130 + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 4131 + "license": "MIT", 4132 + "dependencies": { 4133 + "inherits": "^2.0.3", 4134 + "string_decoder": "^1.1.1", 4135 + "util-deprecate": "^1.0.1" 4136 + }, 4137 + "engines": { 4138 + "node": ">= 6" 3726 4139 } 3727 4140 }, 3728 4141 "node_modules/resolve-from": { ··· 3783 4196 "fsevents": "~2.3.2" 3784 4197 } 3785 4198 }, 4199 + "node_modules/safe-buffer": { 4200 + "version": "5.2.1", 4201 + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 4202 + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 4203 + "funding": [ 4204 + { 4205 + "type": "github", 4206 + "url": "https://github.com/sponsors/feross" 4207 + }, 4208 + { 4209 + "type": "patreon", 4210 + "url": "https://www.patreon.com/feross" 4211 + }, 4212 + { 4213 + "type": "consulting", 4214 + "url": "https://feross.org/support" 4215 + } 4216 + ], 4217 + "license": "MIT" 4218 + }, 3786 4219 "node_modules/semver": { 3787 4220 "version": "7.7.3", 4221 + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", 4222 + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", 3788 4223 "dev": true, 3789 4224 "license": "ISC", 3790 4225 "bin": { ··· 3836 4271 "dev": true, 3837 4272 "license": "MIT" 3838 4273 }, 4274 + "node_modules/stream-browserify": { 4275 + "version": "3.0.0", 4276 + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", 4277 + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", 4278 + "license": "MIT", 4279 + "dependencies": { 4280 + "inherits": "~2.0.4", 4281 + "readable-stream": "^3.5.0" 4282 + } 4283 + }, 4284 + "node_modules/string_decoder": { 4285 + "version": "1.3.0", 4286 + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 4287 + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 4288 + "license": "MIT", 4289 + "dependencies": { 4290 + "safe-buffer": "~5.2.0" 4291 + } 4292 + }, 3839 4293 "node_modules/strip-json-comments": { 3840 4294 "version": "3.1.1", 3841 4295 "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", ··· 3850 4304 } 3851 4305 }, 3852 4306 "node_modules/strnum": { 3853 - "version": "2.1.1", 4307 + "version": "2.1.2", 4308 + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", 4309 + "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", 3854 4310 "funding": [ 3855 4311 { 3856 4312 "type": "github", ··· 3870 4326 "node": ">=8" 3871 4327 } 3872 4328 }, 4329 + "node_modules/synckit": { 4330 + "version": "0.11.11", 4331 + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", 4332 + "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", 4333 + "dev": true, 4334 + "license": "MIT", 4335 + "dependencies": { 4336 + "@pkgr/core": "^0.2.9" 4337 + }, 4338 + "engines": { 4339 + "node": "^14.18.0 || >=16.0.0" 4340 + }, 4341 + "funding": { 4342 + "url": "https://opencollective.com/synckit" 4343 + } 4344 + }, 3873 4345 "node_modules/tiny-lru": { 3874 4346 "version": "11.4.5", 3875 4347 "license": "BSD-3-Clause", ··· 3971 4443 "node": ">=14.17" 3972 4444 } 3973 4445 }, 4446 + "node_modules/typescript-eslint": { 4447 + "version": "8.50.0", 4448 + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.50.0.tgz", 4449 + "integrity": "sha512-Q1/6yNUmCpH94fbgMUMg2/BSAr/6U7GBk61kZTv1/asghQOWOjTlp9K8mixS5NcJmm2creY+UFfGeW/+OcA64A==", 4450 + "dev": true, 4451 + "license": "MIT", 4452 + "dependencies": { 4453 + "@typescript-eslint/eslint-plugin": "8.50.0", 4454 + "@typescript-eslint/parser": "8.50.0", 4455 + "@typescript-eslint/typescript-estree": "8.50.0", 4456 + "@typescript-eslint/utils": "8.50.0" 4457 + }, 4458 + "engines": { 4459 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 4460 + }, 4461 + "funding": { 4462 + "type": "opencollective", 4463 + "url": "https://opencollective.com/typescript-eslint" 4464 + }, 4465 + "peerDependencies": { 4466 + "eslint": "^8.57.0 || ^9.0.0", 4467 + "typescript": ">=4.8.4 <6.0.0" 4468 + } 4469 + }, 3974 4470 "node_modules/undici-types": { 3975 4471 "version": "7.16.0", 3976 4472 "dev": true, ··· 3985 4481 "dependencies": { 3986 4482 "punycode": "^2.1.0" 3987 4483 } 4484 + }, 4485 + "node_modules/util-deprecate": { 4486 + "version": "1.0.2", 4487 + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 4488 + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 4489 + "license": "MIT" 3988 4490 }, 3989 4491 "node_modules/vite": { 3990 4492 "version": "7.2.7",
+1
package.json
··· 21 21 }, 22 22 "dependencies": { 23 23 "@aws-sdk/client-s3": "^3.500.0", 24 + "@aws-sdk/lib-storage": "^3.500.0", 24 25 "hono": "^4.10.7", 25 26 "mime-types": "^3.0.2", 26 27 "tiny-lru": "^11.0.0"
+279 -1
src/TieredStorage.ts
··· 7 7 StorageTier, 8 8 AllTierStats, 9 9 StorageSnapshot, 10 + StreamResult, 11 + StreamSetOptions, 10 12 } from './types/index'; 11 - import { compress, decompress } from './utils/compression.js'; 13 + import { 14 + compress, 15 + decompress, 16 + createCompressStream, 17 + createDecompressStream, 18 + } from './utils/compression.js'; 12 19 import { defaultSerialize, defaultDeserialize } from './utils/serialization.js'; 13 20 import { calculateChecksum } from './utils/checksum.js'; 14 21 import { matchGlob } from './utils/glob.js'; 22 + import { PassThrough, type Readable } from 'node:stream'; 23 + import { createHash } from 'node:crypto'; 15 24 16 25 /** 17 26 * Main orchestrator for tiered storage system. ··· 192 201 return null; 193 202 } 194 203 return { data, metadata }; 204 + } 205 + 206 + /** 207 + * Retrieve data as a readable stream with metadata. 208 + * 209 + * @param key - The key to retrieve 210 + * @returns A readable stream, metadata, and source tier, or null if not found 211 + * 212 + * @remarks 213 + * Use this for large files to avoid loading entire content into memory. 214 + * The stream must be consumed or destroyed by the caller. 215 + * 216 + * Checks tiers in order: hot → warm → cold. 217 + * On cache miss, does NOT promote data to upper tiers (streaming would 218 + * require buffering, defeating the purpose). 219 + * 220 + * Decompression is automatically handled if the data was stored with 221 + * compression enabled (metadata.compressed = true). 222 + * 223 + * @example 224 + * ```typescript 225 + * const result = await storage.getStream('large-file.mp4'); 226 + * if (result) { 227 + * result.stream.pipe(response); // Stream directly to HTTP response 228 + * } 229 + * ``` 230 + */ 231 + async getStream(key: string): Promise<StreamResult | null> { 232 + // 1. Check hot tier first 233 + if (this.config.tiers.hot?.getStream) { 234 + const result = await this.config.tiers.hot.getStream(key); 235 + if (result) { 236 + if (this.isExpired(result.metadata)) { 237 + (result.stream as Readable).destroy?.(); 238 + await this.delete(key); 239 + return null; 240 + } 241 + void this.updateAccessStats(key, 'hot'); 242 + return this.wrapStreamWithDecompression(result, 'hot'); 243 + } 244 + } 245 + 246 + // 2. Check warm tier 247 + if (this.config.tiers.warm?.getStream) { 248 + const result = await this.config.tiers.warm.getStream(key); 249 + if (result) { 250 + if (this.isExpired(result.metadata)) { 251 + (result.stream as Readable).destroy?.(); 252 + await this.delete(key); 253 + return null; 254 + } 255 + // NOTE: No promotion for streaming (would require buffering) 256 + void this.updateAccessStats(key, 'warm'); 257 + return this.wrapStreamWithDecompression(result, 'warm'); 258 + } 259 + } 260 + 261 + // 3. Check cold tier (source of truth) 262 + if (this.config.tiers.cold.getStream) { 263 + const result = await this.config.tiers.cold.getStream(key); 264 + if (result) { 265 + if (this.isExpired(result.metadata)) { 266 + (result.stream as Readable).destroy?.(); 267 + await this.delete(key); 268 + return null; 269 + } 270 + // NOTE: No promotion for streaming (would require buffering) 271 + void this.updateAccessStats(key, 'cold'); 272 + return this.wrapStreamWithDecompression(result, 'cold'); 273 + } 274 + } 275 + 276 + return null; 277 + } 278 + 279 + /** 280 + * Wrap a stream result with decompression if needed. 281 + */ 282 + private wrapStreamWithDecompression( 283 + result: { stream: NodeJS.ReadableStream; metadata: StorageMetadata }, 284 + source: 'hot' | 'warm' | 'cold', 285 + ): StreamResult { 286 + if (result.metadata.compressed) { 287 + // Pipe through decompression stream 288 + const decompressStream = createDecompressStream(); 289 + (result.stream as Readable).pipe(decompressStream); 290 + return { stream: decompressStream, metadata: result.metadata, source }; 291 + } 292 + return { ...result, source }; 293 + } 294 + 295 + /** 296 + * Store data from a readable stream. 297 + * 298 + * @param key - The key to store under 299 + * @param stream - Readable stream of data to store 300 + * @param options - Configuration including size (required), checksum, and tier options 301 + * @returns Information about what was stored and where 302 + * 303 + * @remarks 304 + * Use this for large files to avoid loading entire content into memory. 305 + * 306 + * **Important differences from set():** 307 + * - `options.size` is required (stream size cannot be determined upfront) 308 + * - Serialization is NOT applied (stream is stored as-is) 309 + * - If no checksum is provided, one will be computed during streaming 310 + * - Checksum is computed on the original (pre-compression) data 311 + * 312 + * **Compression:** 313 + * - If `config.compression` is true, the stream is compressed before storage 314 + * - Checksum is always computed on the original uncompressed data 315 + * 316 + * **Tier handling:** 317 + * - Only writes to tiers that support streaming (have setStream method) 318 + * - Hot tier is skipped by default for streaming (typically memory-based) 319 + * - Tees the stream to write to multiple tiers simultaneously 320 + * 321 + * @example 322 + * ```typescript 323 + * const fileStream = fs.createReadStream('large-file.mp4'); 324 + * const stat = fs.statSync('large-file.mp4'); 325 + * 326 + * await storage.setStream('videos/large.mp4', fileStream, { 327 + * size: stat.size, 328 + * mimeType: 'video/mp4', 329 + * }); 330 + * ``` 331 + */ 332 + async setStream( 333 + key: string, 334 + stream: NodeJS.ReadableStream, 335 + options: StreamSetOptions, 336 + ): Promise<SetResult> { 337 + const shouldCompress = this.config.compression ?? false; 338 + 339 + // Create metadata 340 + const now = new Date(); 341 + const ttl = options.ttl ?? this.config.defaultTTL; 342 + 343 + const metadata: StorageMetadata = { 344 + key, 345 + size: options.size, // Original uncompressed size 346 + createdAt: now, 347 + lastAccessed: now, 348 + accessCount: 0, 349 + compressed: shouldCompress, 350 + checksum: options.checksum ?? '', // Will be computed if not provided 351 + ...(options.mimeType && { mimeType: options.mimeType }), 352 + }; 353 + 354 + if (ttl) { 355 + metadata.ttl = new Date(now.getTime() + ttl); 356 + } 357 + 358 + if (options.metadata) { 359 + metadata.customMetadata = options.metadata; 360 + } 361 + 362 + // Determine which tiers to write to 363 + // Default: skip hot tier for streaming (typically memory-based, defeats purpose) 364 + const allowedTiers = this.getTiersForKey(key, options.skipTiers ?? ['hot']); 365 + 366 + // Collect tiers that support streaming 367 + const streamingTiers: Array<{ name: 'hot' | 'warm' | 'cold'; tier: StorageTier }> = []; 368 + 369 + if (this.config.tiers.hot?.setStream && allowedTiers.includes('hot')) { 370 + streamingTiers.push({ name: 'hot', tier: this.config.tiers.hot }); 371 + } 372 + 373 + if (this.config.tiers.warm?.setStream && allowedTiers.includes('warm')) { 374 + streamingTiers.push({ name: 'warm', tier: this.config.tiers.warm }); 375 + } 376 + 377 + if (this.config.tiers.cold.setStream) { 378 + streamingTiers.push({ name: 'cold', tier: this.config.tiers.cold }); 379 + } 380 + 381 + const tiersWritten: ('hot' | 'warm' | 'cold')[] = []; 382 + 383 + if (streamingTiers.length === 0) { 384 + throw new Error('No tiers support streaming. Use set() for buffered writes.'); 385 + } 386 + 387 + // We always need to compute checksum on uncompressed data if not provided 388 + const needsChecksum = !options.checksum; 389 + 390 + // Create pass-through streams for each tier 391 + const passThroughs = streamingTiers.map(() => new PassThrough()); 392 + const hashStream = needsChecksum ? createHash('sha256') : null; 393 + 394 + // Set up the stream pipeline: 395 + // source -> (hash) -> (compress) -> tee to all tier streams 396 + const sourceStream = stream as Readable; 397 + 398 + // If compression is enabled, we need to: 399 + // 1. Compute hash on original data 400 + // 2. Then compress 401 + // 3. Then tee to all tiers 402 + if (shouldCompress) { 403 + const compressStream = createCompressStream(); 404 + 405 + // Hash the original uncompressed data 406 + sourceStream.on('data', (chunk: Buffer) => { 407 + if (hashStream) { 408 + hashStream.update(chunk); 409 + } 410 + }); 411 + 412 + // Pipe source through compression 413 + sourceStream.pipe(compressStream); 414 + 415 + // Tee compressed output to all tier streams 416 + compressStream.on('data', (chunk: Buffer) => { 417 + for (const pt of passThroughs) { 418 + pt.write(chunk); 419 + } 420 + }); 421 + 422 + compressStream.on('end', () => { 423 + for (const pt of passThroughs) { 424 + pt.end(); 425 + } 426 + }); 427 + 428 + compressStream.on('error', (err) => { 429 + for (const pt of passThroughs) { 430 + pt.destroy(err); 431 + } 432 + }); 433 + } else { 434 + // No compression - hash and tee directly 435 + sourceStream.on('data', (chunk: Buffer) => { 436 + for (const pt of passThroughs) { 437 + pt.write(chunk); 438 + } 439 + if (hashStream) { 440 + hashStream.update(chunk); 441 + } 442 + }); 443 + 444 + sourceStream.on('end', () => { 445 + for (const pt of passThroughs) { 446 + pt.end(); 447 + } 448 + }); 449 + 450 + sourceStream.on('error', (err) => { 451 + for (const pt of passThroughs) { 452 + pt.destroy(err); 453 + } 454 + }); 455 + } 456 + 457 + // Wait for all tier writes 458 + const writePromises = streamingTiers.map(async ({ name, tier }, index) => { 459 + await tier.setStream!(key, passThroughs[index]!, metadata); 460 + tiersWritten.push(name); 461 + }); 462 + 463 + await Promise.all(writePromises); 464 + 465 + // Update checksum in metadata if computed 466 + if (hashStream) { 467 + metadata.checksum = hashStream.digest('hex'); 468 + // Update metadata in all tiers with the computed checksum 469 + await Promise.all(streamingTiers.map(({ tier }) => tier.setMetadata(key, metadata))); 470 + } 471 + 472 + return { key, metadata, tiersWritten }; 195 473 } 196 474 197 475 /**
+10 -1
src/index.ts
··· 25 25 StorageMetadata, 26 26 TierStats, 27 27 TierGetResult, 28 + TierStreamResult, 28 29 AllTierStats, 29 30 TieredStorageConfig, 30 31 PlacementRule, 31 32 SetOptions, 33 + StreamSetOptions, 32 34 StorageResult, 35 + StreamResult, 33 36 SetResult, 34 37 StorageSnapshot, 35 38 } from './types/index.js'; 36 39 37 40 // Utilities 38 - export { compress, decompress, isGzipped } from './utils/compression.js'; 41 + export { 42 + compress, 43 + decompress, 44 + isGzipped, 45 + createCompressStream, 46 + createDecompressStream, 47 + } from './utils/compression.js'; 39 48 export { defaultSerialize, defaultDeserialize } from './utils/serialization.js'; 40 49 export { calculateChecksum, verifyChecksum } from './utils/checksum.js'; 41 50 export { encodeKey, decodeKey } from './utils/path-encoding.js';
+99 -2
src/tiers/DiskStorageTier.ts
··· 1 1 import { readFile, writeFile, unlink, readdir, stat, mkdir, rm, rename } from 'node:fs/promises'; 2 - import { existsSync } from 'node:fs'; 2 + import { existsSync, createReadStream, createWriteStream } from 'node:fs'; 3 3 import { join, dirname } from 'node:path'; 4 - import type { StorageTier, StorageMetadata, TierStats, TierGetResult } from '../types/index.js'; 4 + import { pipeline } from 'node:stream/promises'; 5 + import type { 6 + StorageTier, 7 + StorageMetadata, 8 + TierStats, 9 + TierGetResult, 10 + TierStreamResult, 11 + } from '../types/index.js'; 5 12 import { encodeKey } from '../utils/path-encoding.js'; 6 13 7 14 /** ··· 188 195 } 189 196 throw error; 190 197 } 198 + } 199 + 200 + /** 201 + * Retrieve data as a readable stream with metadata. 202 + * 203 + * @param key - The key to retrieve 204 + * @returns A readable stream and metadata, or null if not found 205 + * 206 + * @remarks 207 + * Use this for large files to avoid loading entire content into memory. 208 + * The stream must be consumed or destroyed by the caller. 209 + */ 210 + async getStream(key: string): Promise<TierStreamResult | null> { 211 + const filePath = this.getFilePath(key); 212 + const metaPath = this.getMetaPath(key); 213 + 214 + try { 215 + // Read metadata first to verify file exists 216 + const metaContent = await readFile(metaPath, 'utf-8'); 217 + const metadata = JSON.parse(metaContent) as StorageMetadata; 218 + 219 + // Convert date strings back to Date objects 220 + metadata.createdAt = new Date(metadata.createdAt); 221 + metadata.lastAccessed = new Date(metadata.lastAccessed); 222 + if (metadata.ttl) { 223 + metadata.ttl = new Date(metadata.ttl); 224 + } 225 + 226 + // Create stream - will throw if file doesn't exist 227 + const stream = createReadStream(filePath); 228 + 229 + return { stream, metadata }; 230 + } catch (error) { 231 + if ((error as NodeJS.ErrnoException).code === 'ENOENT') { 232 + return null; 233 + } 234 + throw error; 235 + } 236 + } 237 + 238 + /** 239 + * Store data from a readable stream. 240 + * 241 + * @param key - The key to store under 242 + * @param stream - Readable stream of data to store 243 + * @param metadata - Metadata to store alongside the data 244 + * 245 + * @remarks 246 + * Use this for large files to avoid loading entire content into memory. 247 + * The stream will be fully consumed by this operation. 248 + */ 249 + async setStream( 250 + key: string, 251 + stream: NodeJS.ReadableStream, 252 + metadata: StorageMetadata, 253 + ): Promise<void> { 254 + const filePath = this.getFilePath(key); 255 + const metaPath = this.getMetaPath(key); 256 + 257 + const dir = dirname(filePath); 258 + if (!existsSync(dir)) { 259 + await mkdir(dir, { recursive: true }); 260 + } 261 + 262 + const existingEntry = this.metadataIndex.get(key); 263 + if (existingEntry) { 264 + this.currentSize -= existingEntry.size; 265 + } 266 + 267 + if (this.config.maxSizeBytes) { 268 + await this.evictIfNeeded(metadata.size); 269 + } 270 + 271 + // Write metadata first (atomic via temp file) 272 + const tempMetaPath = `${metaPath}.tmp`; 273 + await writeFile(tempMetaPath, JSON.stringify(metadata, null, 2)); 274 + 275 + // Stream data to file 276 + const writeStream = createWriteStream(filePath); 277 + await pipeline(stream, writeStream); 278 + 279 + // Commit metadata 280 + await rename(tempMetaPath, metaPath); 281 + 282 + this.metadataIndex.set(key, { 283 + size: metadata.size, 284 + createdAt: metadata.createdAt, 285 + lastAccessed: metadata.lastAccessed, 286 + }); 287 + this.currentSize += metadata.size; 191 288 } 192 289 193 290 async set(key: string, data: Uint8Array, metadata: StorageMetadata): Promise<void> {
+75 -1
src/tiers/MemoryStorageTier.ts
··· 1 1 import { lru, type LRU } from 'tiny-lru'; 2 - import type { StorageTier, StorageMetadata, TierStats, TierGetResult } from '../types/index.js'; 2 + import { Readable } from 'node:stream'; 3 + import type { 4 + StorageTier, 5 + StorageMetadata, 6 + TierStats, 7 + TierGetResult, 8 + TierStreamResult, 9 + } from '../types/index.js'; 3 10 4 11 interface CacheEntry { 5 12 data: Uint8Array; ··· 100 107 101 108 this.stats.hits++; 102 109 return { data: entry.data, metadata: entry.metadata }; 110 + } 111 + 112 + /** 113 + * Retrieve data as a readable stream with metadata. 114 + * 115 + * @param key - The key to retrieve 116 + * @returns A readable stream and metadata, or null if not found 117 + * 118 + * @remarks 119 + * Creates a readable stream from the in-memory data. 120 + * Note that for memory tier, data is already in memory, so this 121 + * provides API consistency rather than memory savings. 122 + */ 123 + async getStream(key: string): Promise<TierStreamResult | null> { 124 + const entry = this.cache.get(key); 125 + 126 + if (!entry) { 127 + this.stats.misses++; 128 + return null; 129 + } 130 + 131 + this.stats.hits++; 132 + 133 + // Create a readable stream from the buffer 134 + const stream = Readable.from([entry.data]); 135 + 136 + return { stream, metadata: entry.metadata }; 137 + } 138 + 139 + /** 140 + * Store data from a readable stream. 141 + * 142 + * @param key - The key to store under 143 + * @param stream - Readable stream of data to store 144 + * @param metadata - Metadata to store alongside the data 145 + * 146 + * @remarks 147 + * Buffers the stream into memory. For memory tier, this is unavoidable 148 + * since the tier stores data in memory. Use disk or S3 tiers for 149 + * truly streaming large file handling. 150 + */ 151 + async setStream( 152 + key: string, 153 + stream: NodeJS.ReadableStream, 154 + metadata: StorageMetadata, 155 + ): Promise<void> { 156 + const chunks: Uint8Array[] = []; 157 + 158 + for await (const chunk of stream) { 159 + if (Buffer.isBuffer(chunk)) { 160 + chunks.push(new Uint8Array(chunk)); 161 + } else if (ArrayBuffer.isView(chunk)) { 162 + chunks.push(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength)); 163 + } else if (typeof chunk === 'string') { 164 + chunks.push(new TextEncoder().encode(chunk)); 165 + } 166 + } 167 + 168 + const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0); 169 + const data = new Uint8Array(totalLength); 170 + let offset = 0; 171 + for (const chunk of chunks) { 172 + data.set(chunk, offset); 173 + offset += chunk.length; 174 + } 175 + 176 + await this.set(key, data, metadata); 103 177 } 104 178 105 179 async set(key: string, data: Uint8Array, metadata: StorageMetadata): Promise<void> {
+134 -1
src/tiers/S3StorageTier.ts
··· 9 9 CopyObjectCommand, 10 10 type S3ClientConfig, 11 11 } from '@aws-sdk/client-s3'; 12 + import { Upload } from '@aws-sdk/lib-storage'; 12 13 import type { Readable } from 'node:stream'; 13 - import type { StorageTier, StorageMetadata, TierStats, TierGetResult } from '../types/index.js'; 14 + import type { 15 + StorageTier, 16 + StorageMetadata, 17 + TierStats, 18 + TierGetResult, 19 + TierStreamResult, 20 + } from '../types/index.js'; 14 21 15 22 /** 16 23 * Configuration for S3StorageTier. ··· 260 267 return null; 261 268 } 262 269 throw error; 270 + } 271 + } 272 + 273 + /** 274 + * Retrieve data as a readable stream with metadata. 275 + * 276 + * @param key - The key to retrieve 277 + * @returns A readable stream and metadata, or null if not found 278 + * 279 + * @remarks 280 + * Use this for large files to avoid loading entire content into memory. 281 + * The stream must be consumed or destroyed by the caller. 282 + */ 283 + async getStream(key: string): Promise<TierStreamResult | null> { 284 + const s3Key = this.getS3Key(key); 285 + 286 + try { 287 + if (this.metadataBucket) { 288 + // Fetch data stream and metadata in parallel 289 + const [dataResponse, metadataResponse] = await Promise.all([ 290 + this.client.send( 291 + new GetObjectCommand({ 292 + Bucket: this.config.bucket, 293 + Key: s3Key, 294 + }), 295 + ), 296 + this.client.send( 297 + new GetObjectCommand({ 298 + Bucket: this.metadataBucket, 299 + Key: s3Key + '.meta', 300 + }), 301 + ), 302 + ]); 303 + 304 + if (!dataResponse.Body || !metadataResponse.Body) { 305 + return null; 306 + } 307 + 308 + // Only buffer the small metadata, stream the data 309 + const metaBuffer = await this.streamToUint8Array(metadataResponse.Body as Readable); 310 + const json = new TextDecoder().decode(metaBuffer); 311 + const metadata = JSON.parse(json) as StorageMetadata; 312 + metadata.createdAt = new Date(metadata.createdAt); 313 + metadata.lastAccessed = new Date(metadata.lastAccessed); 314 + if (metadata.ttl) { 315 + metadata.ttl = new Date(metadata.ttl); 316 + } 317 + 318 + return { stream: dataResponse.Body as Readable, metadata }; 319 + } else { 320 + // Get data stream with embedded metadata from response headers 321 + const response = await this.client.send( 322 + new GetObjectCommand({ 323 + Bucket: this.config.bucket, 324 + Key: s3Key, 325 + }), 326 + ); 327 + 328 + if (!response.Body || !response.Metadata) { 329 + return null; 330 + } 331 + 332 + const metadata = this.s3ToMetadata(response.Metadata); 333 + 334 + return { stream: response.Body as Readable, metadata }; 335 + } 336 + } catch (error) { 337 + if (this.isNoSuchKeyError(error)) { 338 + return null; 339 + } 340 + throw error; 341 + } 342 + } 343 + 344 + /** 345 + * Store data from a readable stream. 346 + * 347 + * @param key - The key to store under 348 + * @param stream - Readable stream of data to store 349 + * @param metadata - Metadata to store alongside the data 350 + * 351 + * @remarks 352 + * Uses multipart upload for efficient streaming of large files. 353 + * The stream will be fully consumed by this operation. 354 + */ 355 + async setStream( 356 + key: string, 357 + stream: NodeJS.ReadableStream, 358 + metadata: StorageMetadata, 359 + ): Promise<void> { 360 + const s3Key = this.getS3Key(key); 361 + 362 + if (this.metadataBucket) { 363 + // Use multipart upload for streaming data 364 + const upload = new Upload({ 365 + client: this.client, 366 + params: { 367 + Bucket: this.config.bucket, 368 + Key: s3Key, 369 + Body: stream as Readable, 370 + }, 371 + }); 372 + 373 + const metadataJson = JSON.stringify(metadata); 374 + const metadataBuffer = new TextEncoder().encode(metadataJson); 375 + const metadataCommand = new PutObjectCommand({ 376 + Bucket: this.metadataBucket, 377 + Key: s3Key + '.meta', 378 + Body: metadataBuffer, 379 + ContentType: 'application/json', 380 + }); 381 + 382 + await Promise.all([upload.done(), this.client.send(metadataCommand)]); 383 + } else { 384 + // Use multipart upload with embedded metadata 385 + const upload = new Upload({ 386 + client: this.client, 387 + params: { 388 + Bucket: this.config.bucket, 389 + Key: s3Key, 390 + Body: stream as Readable, 391 + Metadata: this.metadataToS3(metadata), 392 + }, 393 + }); 394 + 395 + await upload.done(); 263 396 } 264 397 } 265 398
+85
src/types/index.ts
··· 124 124 metadata: StorageMetadata; 125 125 } 126 126 127 + /** 128 + * Result from a streaming get operation on a tier. 129 + */ 130 + export interface TierStreamResult { 131 + /** Readable stream of the data */ 132 + stream: NodeJS.ReadableStream; 133 + /** Metadata associated with the data */ 134 + metadata: StorageMetadata; 135 + } 136 + 137 + /** 138 + * Result from a streaming get operation on TieredStorage. 139 + * 140 + * @remarks 141 + * Includes the source tier for observability. 142 + */ 143 + export interface StreamResult { 144 + /** Readable stream of the data */ 145 + stream: NodeJS.ReadableStream; 146 + /** Metadata associated with the data */ 147 + metadata: StorageMetadata; 148 + /** Which tier the data was served from */ 149 + source: 'hot' | 'warm' | 'cold'; 150 + } 151 + 152 + /** 153 + * Options for streaming set operations. 154 + */ 155 + export interface StreamSetOptions extends SetOptions { 156 + /** 157 + * Size of the data being streamed in bytes. 158 + * 159 + * @remarks 160 + * Required for streaming writes because the size cannot be determined 161 + * until the stream is fully consumed. This is used for: 162 + * - Metadata creation before streaming starts 163 + * - Capacity checks and eviction in tiers with size limits 164 + */ 165 + size: number; 166 + 167 + /** 168 + * Pre-computed checksum of the data. 169 + * 170 + * @remarks 171 + * If not provided, checksum will be computed during streaming. 172 + * Providing it upfront is useful when the checksum is already known 173 + * (e.g., from a previous upload or external source). 174 + */ 175 + checksum?: string; 176 + 177 + /** 178 + * MIME type of the content. 179 + */ 180 + mimeType?: string; 181 + } 182 + 127 183 export interface StorageTier { 128 184 /** 129 185 * Retrieve data for a key. ··· 144 200 * especially for disk and network-based tiers. 145 201 */ 146 202 getWithMetadata?(key: string): Promise<TierGetResult | null>; 203 + 204 + /** 205 + * Retrieve data as a readable stream with metadata. 206 + * 207 + * @param key - The key to retrieve 208 + * @returns A readable stream and metadata, or null if not found 209 + * 210 + * @remarks 211 + * Use this for large files to avoid loading entire content into memory. 212 + * The stream must be consumed or destroyed by the caller. 213 + */ 214 + getStream?(key: string): Promise<TierStreamResult | null>; 215 + 216 + /** 217 + * Store data from a readable stream. 218 + * 219 + * @param key - The key to store under 220 + * @param stream - Readable stream of data to store 221 + * @param metadata - Metadata to store alongside the data 222 + * 223 + * @remarks 224 + * Use this for large files to avoid loading entire content into memory. 225 + * The stream will be fully consumed by this operation. 226 + */ 227 + setStream?( 228 + key: string, 229 + stream: NodeJS.ReadableStream, 230 + metadata: StorageMetadata, 231 + ): Promise<void>; 147 232 148 233 /** 149 234 * Store data with associated metadata.
+40 -1
src/utils/compression.ts
··· 1 - import { gzip, gunzip } from 'node:zlib'; 1 + import { gzip, gunzip, createGzip, createGunzip } from 'node:zlib'; 2 2 import { promisify } from 'node:util'; 3 + import type { Transform } from 'node:stream'; 3 4 4 5 const gzipAsync = promisify(gzip); 5 6 const gunzipAsync = promisify(gunzip); ··· 76 77 export function isGzipped(data: Uint8Array): boolean { 77 78 return data.length >= 2 && data[0] === 0x1f && data[1] === 0x8b; 78 79 } 80 + 81 + /** 82 + * Create a gzip compression transform stream. 83 + * 84 + * @returns A transform stream that compresses data passing through it 85 + * 86 + * @remarks 87 + * Use this for streaming compression of large files. 88 + * Pipe data through this stream to compress it on-the-fly. 89 + * 90 + * @example 91 + * ```typescript 92 + * const compressStream = createCompressStream(); 93 + * sourceStream.pipe(compressStream).pipe(destinationStream); 94 + * ``` 95 + */ 96 + export function createCompressStream(): Transform { 97 + return createGzip(); 98 + } 99 + 100 + /** 101 + * Create a gzip decompression transform stream. 102 + * 103 + * @returns A transform stream that decompresses data passing through it 104 + * 105 + * @remarks 106 + * Use this for streaming decompression of large files. 107 + * Pipe compressed data through this stream to decompress it on-the-fly. 108 + * 109 + * @example 110 + * ```typescript 111 + * const decompressStream = createDecompressStream(); 112 + * compressedStream.pipe(decompressStream).pipe(destinationStream); 113 + * ``` 114 + */ 115 + export function createDecompressStream(): Transform { 116 + return createGunzip(); 117 + }
+598
test/streaming.test.ts
··· 1 + import { describe, it, expect, afterEach } from 'vitest'; 2 + import { TieredStorage } from '../src/TieredStorage.js'; 3 + import { MemoryStorageTier } from '../src/tiers/MemoryStorageTier.js'; 4 + import { DiskStorageTier } from '../src/tiers/DiskStorageTier.js'; 5 + import { rm } from 'node:fs/promises'; 6 + import { Readable } from 'node:stream'; 7 + import { createHash } from 'node:crypto'; 8 + 9 + describe('Streaming Operations', () => { 10 + const testDir = './test-streaming-cache'; 11 + 12 + afterEach(async () => { 13 + await rm(testDir, { recursive: true, force: true }); 14 + }); 15 + 16 + /** 17 + * Helper to create a readable stream from a string or buffer 18 + */ 19 + function createStream(data: string | Buffer): Readable { 20 + return Readable.from([Buffer.from(data)]); 21 + } 22 + 23 + /** 24 + * Helper to consume a stream and return its contents as a buffer 25 + */ 26 + async function streamToBuffer(stream: NodeJS.ReadableStream): Promise<Buffer> { 27 + const chunks: Buffer[] = []; 28 + for await (const chunk of stream) { 29 + chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)); 30 + } 31 + return Buffer.concat(chunks); 32 + } 33 + 34 + /** 35 + * Helper to compute SHA256 checksum of a buffer 36 + */ 37 + function computeChecksum(data: Buffer): string { 38 + return createHash('sha256').update(data).digest('hex'); 39 + } 40 + 41 + describe('DiskStorageTier Streaming', () => { 42 + it('should write and read data using streams', async () => { 43 + const tier = new DiskStorageTier({ directory: testDir }); 44 + 45 + const testData = 'Hello, streaming world! '.repeat(100); 46 + const testBuffer = Buffer.from(testData); 47 + const checksum = computeChecksum(testBuffer); 48 + 49 + const metadata = { 50 + key: 'streaming-test.txt', 51 + size: testBuffer.byteLength, 52 + createdAt: new Date(), 53 + lastAccessed: new Date(), 54 + accessCount: 0, 55 + compressed: false, 56 + checksum, 57 + }; 58 + 59 + // Write using stream 60 + await tier.setStream('streaming-test.txt', createStream(testData), metadata); 61 + 62 + // Verify file exists 63 + expect(await tier.exists('streaming-test.txt')).toBe(true); 64 + 65 + // Read using stream 66 + const result = await tier.getStream('streaming-test.txt'); 67 + expect(result).not.toBeNull(); 68 + 69 + const retrievedData = await streamToBuffer(result!.stream); 70 + expect(retrievedData.toString()).toBe(testData); 71 + expect(result!.metadata.key).toBe('streaming-test.txt'); 72 + }); 73 + 74 + it('should handle large data without memory issues', async () => { 75 + const tier = new DiskStorageTier({ directory: testDir }); 76 + 77 + // Create a 1MB chunk and repeat pattern 78 + const chunkSize = 1024 * 1024; // 1MB 79 + const chunk = Buffer.alloc(chunkSize, 'x'); 80 + 81 + const metadata = { 82 + key: 'large-file.bin', 83 + size: chunkSize, 84 + createdAt: new Date(), 85 + lastAccessed: new Date(), 86 + accessCount: 0, 87 + compressed: false, 88 + checksum: computeChecksum(chunk), 89 + }; 90 + 91 + // Write using stream 92 + await tier.setStream('large-file.bin', Readable.from([chunk]), metadata); 93 + 94 + // Read using stream 95 + const result = await tier.getStream('large-file.bin'); 96 + expect(result).not.toBeNull(); 97 + 98 + const retrievedData = await streamToBuffer(result!.stream); 99 + expect(retrievedData.length).toBe(chunkSize); 100 + expect(retrievedData.equals(chunk)).toBe(true); 101 + }); 102 + 103 + it('should return null for non-existent key', async () => { 104 + const tier = new DiskStorageTier({ directory: testDir }); 105 + 106 + const result = await tier.getStream('non-existent-key'); 107 + expect(result).toBeNull(); 108 + }); 109 + 110 + it('should handle nested directories with streaming', async () => { 111 + const tier = new DiskStorageTier({ directory: testDir }); 112 + 113 + const testData = 'nested streaming data'; 114 + const testBuffer = Buffer.from(testData); 115 + 116 + const metadata = { 117 + key: 'deep/nested/path/file.txt', 118 + size: testBuffer.byteLength, 119 + createdAt: new Date(), 120 + lastAccessed: new Date(), 121 + accessCount: 0, 122 + compressed: false, 123 + checksum: computeChecksum(testBuffer), 124 + }; 125 + 126 + await tier.setStream('deep/nested/path/file.txt', createStream(testData), metadata); 127 + 128 + const result = await tier.getStream('deep/nested/path/file.txt'); 129 + expect(result).not.toBeNull(); 130 + 131 + const retrievedData = await streamToBuffer(result!.stream); 132 + expect(retrievedData.toString()).toBe(testData); 133 + }); 134 + }); 135 + 136 + describe('MemoryStorageTier Streaming', () => { 137 + it('should write and read data using streams', async () => { 138 + const tier = new MemoryStorageTier({ maxSizeBytes: 10 * 1024 * 1024 }); 139 + 140 + const testData = 'Memory tier streaming test'; 141 + const testBuffer = Buffer.from(testData); 142 + 143 + const metadata = { 144 + key: 'memory-test.txt', 145 + size: testBuffer.byteLength, 146 + createdAt: new Date(), 147 + lastAccessed: new Date(), 148 + accessCount: 0, 149 + compressed: false, 150 + checksum: computeChecksum(testBuffer), 151 + }; 152 + 153 + // Write using stream 154 + await tier.setStream('memory-test.txt', createStream(testData), metadata); 155 + 156 + // Read using stream 157 + const result = await tier.getStream('memory-test.txt'); 158 + expect(result).not.toBeNull(); 159 + 160 + const retrievedData = await streamToBuffer(result!.stream); 161 + expect(retrievedData.toString()).toBe(testData); 162 + }); 163 + 164 + it('should return null for non-existent key', async () => { 165 + const tier = new MemoryStorageTier({ maxSizeBytes: 10 * 1024 * 1024 }); 166 + 167 + const result = await tier.getStream('non-existent-key'); 168 + expect(result).toBeNull(); 169 + }); 170 + }); 171 + 172 + describe('TieredStorage Streaming', () => { 173 + it('should store and retrieve data using streams', async () => { 174 + const storage = new TieredStorage({ 175 + tiers: { 176 + hot: new MemoryStorageTier({ maxSizeBytes: 10 * 1024 * 1024 }), 177 + warm: new DiskStorageTier({ directory: `${testDir}/warm` }), 178 + cold: new DiskStorageTier({ directory: `${testDir}/cold` }), 179 + }, 180 + }); 181 + 182 + const testData = 'TieredStorage streaming test data'; 183 + const testBuffer = Buffer.from(testData); 184 + 185 + // Write using stream 186 + const setResult = await storage.setStream('stream-key', createStream(testData), { 187 + size: testBuffer.byteLength, 188 + }); 189 + 190 + expect(setResult.key).toBe('stream-key'); 191 + expect(setResult.metadata.size).toBe(testBuffer.byteLength); 192 + // Hot tier is skipped by default for streaming 193 + expect(setResult.tiersWritten).not.toContain('hot'); 194 + expect(setResult.tiersWritten).toContain('warm'); 195 + expect(setResult.tiersWritten).toContain('cold'); 196 + 197 + // Read using stream 198 + const result = await storage.getStream('stream-key'); 199 + expect(result).not.toBeNull(); 200 + 201 + const retrievedData = await streamToBuffer(result!.stream); 202 + expect(retrievedData.toString()).toBe(testData); 203 + }); 204 + 205 + it('should compute checksum during streaming write', async () => { 206 + const storage = new TieredStorage({ 207 + tiers: { 208 + warm: new DiskStorageTier({ directory: `${testDir}/warm` }), 209 + cold: new DiskStorageTier({ directory: `${testDir}/cold` }), 210 + }, 211 + }); 212 + 213 + const testData = 'Data for checksum test'; 214 + const testBuffer = Buffer.from(testData); 215 + const expectedChecksum = computeChecksum(testBuffer); 216 + 217 + const setResult = await storage.setStream('checksum-test', createStream(testData), { 218 + size: testBuffer.byteLength, 219 + }); 220 + 221 + // Checksum should be computed and stored 222 + expect(setResult.metadata.checksum).toBe(expectedChecksum); 223 + }); 224 + 225 + it('should use provided checksum without computing', async () => { 226 + const storage = new TieredStorage({ 227 + tiers: { 228 + cold: new DiskStorageTier({ directory: `${testDir}/cold` }), 229 + }, 230 + }); 231 + 232 + const testData = 'Data with pre-computed checksum'; 233 + const testBuffer = Buffer.from(testData); 234 + const providedChecksum = 'my-custom-checksum'; 235 + 236 + const setResult = await storage.setStream('custom-checksum', createStream(testData), { 237 + size: testBuffer.byteLength, 238 + checksum: providedChecksum, 239 + }); 240 + 241 + expect(setResult.metadata.checksum).toBe(providedChecksum); 242 + }); 243 + 244 + it('should return null for non-existent key', async () => { 245 + const storage = new TieredStorage({ 246 + tiers: { 247 + cold: new DiskStorageTier({ directory: `${testDir}/cold` }), 248 + }, 249 + }); 250 + 251 + const result = await storage.getStream('non-existent'); 252 + expect(result).toBeNull(); 253 + }); 254 + 255 + it('should read from appropriate tier (warm before cold)', async () => { 256 + const warm = new DiskStorageTier({ directory: `${testDir}/warm` }); 257 + const cold = new DiskStorageTier({ directory: `${testDir}/cold` }); 258 + 259 + const storage = new TieredStorage({ 260 + tiers: { warm, cold }, 261 + }); 262 + 263 + const testData = 'Tier priority test data'; 264 + const testBuffer = Buffer.from(testData); 265 + 266 + await storage.setStream('tier-test', createStream(testData), { 267 + size: testBuffer.byteLength, 268 + }); 269 + 270 + // Both tiers should have the data 271 + expect(await warm.exists('tier-test')).toBe(true); 272 + expect(await cold.exists('tier-test')).toBe(true); 273 + 274 + // Read should come from warm (first available) 275 + const result = await storage.getStream('tier-test'); 276 + expect(result).not.toBeNull(); 277 + expect(result!.source).toBe('warm'); 278 + }); 279 + 280 + it('should fall back to cold tier when warm has no data', async () => { 281 + const warm = new DiskStorageTier({ directory: `${testDir}/warm` }); 282 + const cold = new DiskStorageTier({ directory: `${testDir}/cold` }); 283 + 284 + const storage = new TieredStorage({ 285 + tiers: { warm, cold }, 286 + }); 287 + 288 + // Write directly to cold only 289 + const testData = 'Cold tier only data'; 290 + const testBuffer = Buffer.from(testData); 291 + const metadata = { 292 + key: 'cold-only', 293 + size: testBuffer.byteLength, 294 + createdAt: new Date(), 295 + lastAccessed: new Date(), 296 + accessCount: 0, 297 + compressed: false, 298 + checksum: computeChecksum(testBuffer), 299 + }; 300 + 301 + await cold.setStream('cold-only', createStream(testData), metadata); 302 + 303 + // Read should come from cold 304 + const result = await storage.getStream('cold-only'); 305 + expect(result).not.toBeNull(); 306 + expect(result!.source).toBe('cold'); 307 + }); 308 + 309 + it('should handle TTL with metadata', async () => { 310 + const storage = new TieredStorage({ 311 + tiers: { 312 + cold: new DiskStorageTier({ directory: `${testDir}/cold` }), 313 + }, 314 + defaultTTL: 60000, // 1 minute 315 + }); 316 + 317 + const testData = 'TTL test data'; 318 + const testBuffer = Buffer.from(testData); 319 + 320 + const setResult = await storage.setStream('ttl-test', createStream(testData), { 321 + size: testBuffer.byteLength, 322 + ttl: 30000, // 30 seconds 323 + }); 324 + 325 + expect(setResult.metadata.ttl).toBeDefined(); 326 + expect(setResult.metadata.ttl!.getTime()).toBeGreaterThan(Date.now()); 327 + }); 328 + 329 + it('should include mimeType in metadata', async () => { 330 + const storage = new TieredStorage({ 331 + tiers: { 332 + cold: new DiskStorageTier({ directory: `${testDir}/cold` }), 333 + }, 334 + }); 335 + 336 + const testData = '{"message": "json data"}'; 337 + const testBuffer = Buffer.from(testData); 338 + 339 + const setResult = await storage.setStream('json-file.json', createStream(testData), { 340 + size: testBuffer.byteLength, 341 + mimeType: 'application/json', 342 + }); 343 + 344 + expect(setResult.metadata.mimeType).toBe('application/json'); 345 + }); 346 + 347 + it('should write to multiple tiers simultaneously', async () => { 348 + const warm = new DiskStorageTier({ directory: `${testDir}/warm` }); 349 + const cold = new DiskStorageTier({ directory: `${testDir}/cold` }); 350 + 351 + const storage = new TieredStorage({ 352 + tiers: { warm, cold }, 353 + }); 354 + 355 + const testData = 'Multi-tier streaming data'; 356 + const testBuffer = Buffer.from(testData); 357 + 358 + await storage.setStream('multi-tier', createStream(testData), { 359 + size: testBuffer.byteLength, 360 + }); 361 + 362 + // Verify data in both tiers 363 + const warmResult = await warm.getStream('multi-tier'); 364 + const coldResult = await cold.getStream('multi-tier'); 365 + 366 + expect(warmResult).not.toBeNull(); 367 + expect(coldResult).not.toBeNull(); 368 + 369 + const warmData = await streamToBuffer(warmResult!.stream); 370 + const coldData = await streamToBuffer(coldResult!.stream); 371 + 372 + expect(warmData.toString()).toBe(testData); 373 + expect(coldData.toString()).toBe(testData); 374 + }); 375 + 376 + it('should skip hot tier by default for streaming writes', async () => { 377 + const hot = new MemoryStorageTier({ maxSizeBytes: 10 * 1024 * 1024 }); 378 + const warm = new DiskStorageTier({ directory: `${testDir}/warm` }); 379 + const cold = new DiskStorageTier({ directory: `${testDir}/cold` }); 380 + 381 + const storage = new TieredStorage({ 382 + tiers: { hot, warm, cold }, 383 + }); 384 + 385 + const testData = 'Skip hot tier test'; 386 + const testBuffer = Buffer.from(testData); 387 + 388 + const setResult = await storage.setStream('skip-hot', createStream(testData), { 389 + size: testBuffer.byteLength, 390 + }); 391 + 392 + // Hot should be skipped by default 393 + expect(setResult.tiersWritten).not.toContain('hot'); 394 + expect(await hot.exists('skip-hot')).toBe(false); 395 + 396 + // Warm and cold should have data 397 + expect(setResult.tiersWritten).toContain('warm'); 398 + expect(setResult.tiersWritten).toContain('cold'); 399 + }); 400 + 401 + it('should allow including hot tier explicitly', async () => { 402 + const hot = new MemoryStorageTier({ maxSizeBytes: 10 * 1024 * 1024 }); 403 + const cold = new DiskStorageTier({ directory: `${testDir}/cold` }); 404 + 405 + const storage = new TieredStorage({ 406 + tiers: { hot, cold }, 407 + }); 408 + 409 + const testData = 'Include hot tier test'; 410 + const testBuffer = Buffer.from(testData); 411 + 412 + const setResult = await storage.setStream('include-hot', createStream(testData), { 413 + size: testBuffer.byteLength, 414 + skipTiers: [], // Don't skip any tiers 415 + }); 416 + 417 + // Hot should be included 418 + expect(setResult.tiersWritten).toContain('hot'); 419 + expect(await hot.exists('include-hot')).toBe(true); 420 + }); 421 + }); 422 + 423 + describe('Streaming with Compression', () => { 424 + it('should compress stream data when compression is enabled', async () => { 425 + const storage = new TieredStorage({ 426 + tiers: { 427 + warm: new DiskStorageTier({ directory: `${testDir}/warm` }), 428 + cold: new DiskStorageTier({ directory: `${testDir}/cold` }), 429 + }, 430 + compression: true, 431 + }); 432 + 433 + const testData = 'Compressible data '.repeat(100); // Repeating data compresses well 434 + const testBuffer = Buffer.from(testData); 435 + 436 + const setResult = await storage.setStream('compress-test', createStream(testData), { 437 + size: testBuffer.byteLength, 438 + }); 439 + 440 + // Metadata should indicate compression 441 + expect(setResult.metadata.compressed).toBe(true); 442 + // Checksum should be of original uncompressed data 443 + expect(setResult.metadata.checksum).toBe(computeChecksum(testBuffer)); 444 + }); 445 + 446 + it('should decompress stream data automatically on read', async () => { 447 + const storage = new TieredStorage({ 448 + tiers: { 449 + warm: new DiskStorageTier({ directory: `${testDir}/warm` }), 450 + cold: new DiskStorageTier({ directory: `${testDir}/cold` }), 451 + }, 452 + compression: true, 453 + }); 454 + 455 + const testData = 'Hello, compressed world! '.repeat(50); 456 + const testBuffer = Buffer.from(testData); 457 + 458 + await storage.setStream('decompress-test', createStream(testData), { 459 + size: testBuffer.byteLength, 460 + }); 461 + 462 + // Read back via stream 463 + const result = await storage.getStream('decompress-test'); 464 + expect(result).not.toBeNull(); 465 + expect(result!.metadata.compressed).toBe(true); 466 + 467 + // Stream should be decompressed automatically 468 + const retrievedData = await streamToBuffer(result!.stream); 469 + expect(retrievedData.toString()).toBe(testData); 470 + }); 471 + 472 + it('should not compress when compression is disabled', async () => { 473 + const storage = new TieredStorage({ 474 + tiers: { 475 + cold: new DiskStorageTier({ directory: `${testDir}/cold` }), 476 + }, 477 + compression: false, 478 + }); 479 + 480 + const testData = 'Uncompressed data '.repeat(50); 481 + const testBuffer = Buffer.from(testData); 482 + 483 + const setResult = await storage.setStream('no-compress-test', createStream(testData), { 484 + size: testBuffer.byteLength, 485 + }); 486 + 487 + expect(setResult.metadata.compressed).toBe(false); 488 + 489 + // Read back - should be exact same data 490 + const result = await storage.getStream('no-compress-test'); 491 + expect(result).not.toBeNull(); 492 + 493 + const retrievedData = await streamToBuffer(result!.stream); 494 + expect(retrievedData.toString()).toBe(testData); 495 + }); 496 + 497 + it('should preserve checksum of original data when compressed', async () => { 498 + const storage = new TieredStorage({ 499 + tiers: { 500 + cold: new DiskStorageTier({ directory: `${testDir}/cold` }), 501 + }, 502 + compression: true, 503 + }); 504 + 505 + const testData = 'Data for checksum verification '.repeat(100); 506 + const testBuffer = Buffer.from(testData); 507 + const expectedChecksum = computeChecksum(testBuffer); 508 + 509 + const setResult = await storage.setStream('checksum-compress', createStream(testData), { 510 + size: testBuffer.byteLength, 511 + }); 512 + 513 + // Checksum should match the ORIGINAL uncompressed data 514 + expect(setResult.metadata.checksum).toBe(expectedChecksum); 515 + 516 + // Read back and verify content matches 517 + const result = await storage.getStream('checksum-compress'); 518 + const retrievedData = await streamToBuffer(result!.stream); 519 + expect(computeChecksum(retrievedData)).toBe(expectedChecksum); 520 + }); 521 + }); 522 + 523 + describe('Edge Cases', () => { 524 + it('should handle empty streams', async () => { 525 + const tier = new DiskStorageTier({ directory: testDir }); 526 + 527 + const metadata = { 528 + key: 'empty-file.txt', 529 + size: 0, 530 + createdAt: new Date(), 531 + lastAccessed: new Date(), 532 + accessCount: 0, 533 + compressed: false, 534 + checksum: computeChecksum(Buffer.from('')), 535 + }; 536 + 537 + await tier.setStream('empty-file.txt', createStream(''), metadata); 538 + 539 + const result = await tier.getStream('empty-file.txt'); 540 + expect(result).not.toBeNull(); 541 + 542 + const data = await streamToBuffer(result!.stream); 543 + expect(data.length).toBe(0); 544 + }); 545 + 546 + it('should preserve binary data integrity', async () => { 547 + const tier = new DiskStorageTier({ directory: testDir }); 548 + 549 + // Create binary data with all possible byte values 550 + const binaryData = Buffer.alloc(256); 551 + for (let i = 0; i < 256; i++) { 552 + binaryData[i] = i; 553 + } 554 + 555 + const metadata = { 556 + key: 'binary-file.bin', 557 + size: binaryData.byteLength, 558 + createdAt: new Date(), 559 + lastAccessed: new Date(), 560 + accessCount: 0, 561 + compressed: false, 562 + checksum: computeChecksum(binaryData), 563 + }; 564 + 565 + await tier.setStream('binary-file.bin', Readable.from([binaryData]), metadata); 566 + 567 + const result = await tier.getStream('binary-file.bin'); 568 + expect(result).not.toBeNull(); 569 + 570 + const retrievedData = await streamToBuffer(result!.stream); 571 + expect(retrievedData.equals(binaryData)).toBe(true); 572 + }); 573 + 574 + it('should handle special characters in keys', async () => { 575 + const tier = new DiskStorageTier({ directory: testDir }); 576 + 577 + const testData = 'special key test'; 578 + const testBuffer = Buffer.from(testData); 579 + 580 + const specialKey = 'user:123/file[1].txt'; 581 + const metadata = { 582 + key: specialKey, 583 + size: testBuffer.byteLength, 584 + createdAt: new Date(), 585 + lastAccessed: new Date(), 586 + accessCount: 0, 587 + compressed: false, 588 + checksum: computeChecksum(testBuffer), 589 + }; 590 + 591 + await tier.setStream(specialKey, createStream(testData), metadata); 592 + 593 + const result = await tier.getStream(specialKey); 594 + expect(result).not.toBeNull(); 595 + expect(result!.metadata.key).toBe(specialKey); 596 + }); 597 + }); 598 + });