From 76a44cf2ab9888f8640922933390259080230f40 Mon Sep 17 00:00:00 2001 From: Samuel Adeoye Date: Sat, 14 Feb 2026 04:48:03 -0330 Subject: [PATCH 01/11] Add DefaultAzureCredential support for azure store --- package-lock.json | 137 ++++++++++-------------------- packages/azure-store/package.json | 1 + packages/azure-store/src/index.ts | 19 +++-- 3 files changed, 54 insertions(+), 103 deletions(-) diff --git a/package-lock.json b/package-lock.json index d161f3f1..daf9f7a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "tus-node-server", + "name": "tus-node-server-1", "version": "0.0.0", "lockfileVersion": 3, "requires": true, @@ -869,17 +869,17 @@ } }, "node_modules/@azure/core-auth": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.7.2.tgz", - "integrity": "sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.1.tgz", + "integrity": "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.0.0", - "@azure/core-util": "^1.1.0", + "@azure/abort-controller": "^2.1.2", + "@azure/core-util": "^1.13.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@azure/core-auth/node_modules/@azure/abort-controller": { @@ -1046,16 +1046,17 @@ } }, "node_modules/@azure/core-util": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.2.tgz", - "integrity": "sha512-l1Qrqhi4x1aekkV+OlcqsJa4AnAkj5p0JV8omgwjaV9OAbP41lvrMvs+CptfetKkeEaGRGSzby7sjPZEX7+kkQ==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.1.tgz", + "integrity": "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.0.0", + "@azure/abort-controller": "^2.1.2", + "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@azure/core-util/node_modules/@azure/abort-controller": { @@ -2715,16 +2716,6 @@ "resolved": "packages/utils", "link": true }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, "node_modules/@types/caseless": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", @@ -2732,15 +2723,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/connect": { - "version": "3.4.38", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/cookiejar": { "version": "2.1.2", "dev": true, @@ -2754,18 +2736,6 @@ "@types/ms": "*" } }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.41", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, "node_modules/@types/glob": { "version": "8.1.0", "dev": true, @@ -2775,12 +2745,6 @@ "@types/node": "*" } }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/@types/lodash": { "version": "4.17.0", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", @@ -2796,12 +2760,6 @@ "@types/lodash": "*" } }, - "node_modules/@types/mime": { - "version": "1.3.5", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/@types/minimatch": { "version": "5.1.2", "dev": true, @@ -2835,18 +2793,6 @@ "undici-types": "~6.20.0" } }, - "node_modules/@types/qs": { - "version": "6.9.11", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/@types/request": { "version": "2.48.12", "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", @@ -2886,33 +2832,6 @@ "@types/node": "*" } }, - "node_modules/@types/send": { - "version": "0.17.4", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.5", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static/node_modules/@types/mime": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/@types/set-cookie-parser": { "version": "2.4.10", "resolved": "https://registry.npmjs.org/@types/set-cookie-parser/-/set-cookie-parser-2.4.10.tgz", @@ -2969,6 +2888,33 @@ "dev": true, "license": "MIT" }, + "node_modules/@typespec/ts-http-runtime": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.3.tgz", + "integrity": "sha512-91fp6CAAJSRtH5ja95T1FHSKa8aPW9/Zw6cta81jlZTUw/+Vq8jM/AfF/14h2b71wwR84JUTW/3Y8QPhDAawFA==", + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@typespec/ts-http-runtime/node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/abort-controller": { "version": "3.0.0", "dev": true, @@ -3548,6 +3494,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "iconv-lite": "^0.6.2" } @@ -3557,6 +3504,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -6193,6 +6141,7 @@ "version": "2.0.0", "license": "MIT", "dependencies": { + "@azure/core-auth": "^1.9.0", "@azure/storage-blob": "^12.24.0", "@tus/utils": "^0.6.0", "debug": "^4.3.4" diff --git a/packages/azure-store/package.json b/packages/azure-store/package.json index b2adfb64..5c7a3061 100644 --- a/packages/azure-store/package.json +++ b/packages/azure-store/package.json @@ -22,6 +22,7 @@ }, "dependencies": { "@tus/utils": "^0.6.0", + "@azure/core-auth": "^1.9.0", "@azure/storage-blob": "^12.24.0", "debug": "^4.3.4" }, diff --git a/packages/azure-store/src/index.ts b/packages/azure-store/src/index.ts index c80ecd5f..29f61840 100644 --- a/packages/azure-store/src/index.ts +++ b/packages/azure-store/src/index.ts @@ -16,12 +16,14 @@ import { type ContainerClient, StorageSharedKeyCredential, } from '@azure/storage-blob' +import type {TokenCredential} from '@azure/core-auth' type Options = { cache?: KvStore account: string - accountKey: string containerName: string + accountKey?: string + credential?: TokenCredential } const log = debug('tus-node-server:stores:azurestore') @@ -44,22 +46,21 @@ export class AzureStore extends DataStore { if (!options.account) { throw new Error('Azure store must have a account') } - if (!options.accountKey) { - throw new Error('Azure store must have a account key') - } if (!options.containerName) { throw new Error('Azure store must have a container name') } + if (!options.accountKey && !options.credential) { + throw new Error('Azure store requires either accountKey or credential') + } const storageAccountBaseUrl = `https://${options.account}.blob.core.windows.net` - const sharedKeyCredential = new StorageSharedKeyCredential( - options.account, - options.accountKey - ) + const credential = options.credential + ? options.credential + : new StorageSharedKeyCredential(options.account, options.accountKey!) this.blobServiceClient = new BlobServiceClient( storageAccountBaseUrl, - sharedKeyCredential + credential ) this.containerClient = this.blobServiceClient.getContainerClient( options.containerName From ee5035f267cb7a9ee07d4e17063f95a6592be667 Mon Sep 17 00:00:00 2001 From: Samuel Adeoye Date: Sat, 14 Feb 2026 04:55:09 -0330 Subject: [PATCH 02/11] Add transpiled code for experimentation for DefaultAzureCredential --- .gitignore | 2 +- packages/azure-store/dist/index.d.ts | 52 ++++ packages/azure-store/dist/index.d.ts.map | 1 + packages/azure-store/dist/index.js | 183 ++++++++++++++ packages/azure-store/dist/index.js.map | 1 + packages/azure-store/dist/test/index.d.ts | 2 + packages/azure-store/dist/test/index.d.ts.map | 1 + packages/azure-store/dist/test/index.js | 29 +++ packages/azure-store/dist/test/index.js.map | 1 + packages/azure-store/package.json | 2 +- packages/utils/dist/constants.d.ts | 90 +++++++ packages/utils/dist/constants.d.ts.map | 1 + packages/utils/dist/constants.js | 110 +++++++++ packages/utils/dist/constants.js.map | 1 + packages/utils/dist/index.d.ts | 4 + packages/utils/dist/index.d.ts.map | 1 + packages/utils/dist/index.js | 4 + packages/utils/dist/index.js.map | 1 + packages/utils/dist/kvstores/FileKvStore.d.ts | 16 ++ .../utils/dist/kvstores/FileKvStore.d.ts.map | 1 + packages/utils/dist/kvstores/FileKvStore.js | 38 +++ .../utils/dist/kvstores/FileKvStore.js.map | 1 + .../utils/dist/kvstores/IoRedisKvStore.d.ts | 16 ++ .../dist/kvstores/IoRedisKvStore.d.ts.map | 1 + .../utils/dist/kvstores/IoRedisKvStore.js | 40 ++++ .../utils/dist/kvstores/IoRedisKvStore.js.map | 1 + .../utils/dist/kvstores/MemoryKvStore.d.ts | 14 ++ .../dist/kvstores/MemoryKvStore.d.ts.map | 1 + packages/utils/dist/kvstores/MemoryKvStore.js | 20 ++ .../utils/dist/kvstores/MemoryKvStore.js.map | 1 + .../utils/dist/kvstores/RedisKvStore.d.ts | 20 ++ .../utils/dist/kvstores/RedisKvStore.d.ts.map | 1 + packages/utils/dist/kvstores/RedisKvStore.js | 42 ++++ .../utils/dist/kvstores/RedisKvStore.js.map | 1 + packages/utils/dist/kvstores/Types.d.ts | 8 + packages/utils/dist/kvstores/Types.d.ts.map | 1 + packages/utils/dist/kvstores/Types.js | 2 + packages/utils/dist/kvstores/Types.js.map | 1 + packages/utils/dist/kvstores/index.d.ts | 6 + packages/utils/dist/kvstores/index.d.ts.map | 1 + packages/utils/dist/kvstores/index.js | 5 + packages/utils/dist/kvstores/index.js.map | 1 + packages/utils/dist/models/Context.d.ts | 26 ++ packages/utils/dist/models/Context.d.ts.map | 1 + packages/utils/dist/models/Context.js | 2 + packages/utils/dist/models/Context.js.map | 1 + packages/utils/dist/models/DataStore.d.ts | 43 ++++ packages/utils/dist/models/DataStore.d.ts.map | 1 + packages/utils/dist/models/DataStore.js | 59 +++++ packages/utils/dist/models/DataStore.js.map | 1 + packages/utils/dist/models/Locker.d.ts | 30 +++ packages/utils/dist/models/Locker.d.ts.map | 1 + packages/utils/dist/models/Locker.js | 2 + packages/utils/dist/models/Locker.js.map | 1 + packages/utils/dist/models/Metadata.d.ts | 6 + packages/utils/dist/models/Metadata.d.ts.map | 1 + packages/utils/dist/models/Metadata.js | 55 +++++ packages/utils/dist/models/Metadata.js.map | 1 + packages/utils/dist/models/StreamLimiter.d.ts | 13 + .../utils/dist/models/StreamLimiter.d.ts.map | 1 + packages/utils/dist/models/StreamLimiter.js | 31 +++ .../utils/dist/models/StreamLimiter.js.map | 1 + .../utils/dist/models/StreamSplitter.d.ts | 26 ++ .../utils/dist/models/StreamSplitter.d.ts.map | 1 + packages/utils/dist/models/StreamSplitter.js | 114 +++++++++ .../utils/dist/models/StreamSplitter.js.map | 1 + packages/utils/dist/models/Uid.d.ts | 4 + packages/utils/dist/models/Uid.d.ts.map | 1 + packages/utils/dist/models/Uid.js | 7 + packages/utils/dist/models/Uid.js.map | 1 + packages/utils/dist/models/Upload.d.ts | 24 ++ packages/utils/dist/models/Upload.d.ts.map | 1 + packages/utils/dist/models/Upload.js | 23 ++ packages/utils/dist/models/Upload.js.map | 1 + packages/utils/dist/models/index.d.ts | 9 + packages/utils/dist/models/index.d.ts.map | 1 + packages/utils/dist/models/index.js | 7 + packages/utils/dist/models/index.js.map | 1 + packages/utils/dist/test/Metadata.test.d.ts | 2 + .../utils/dist/test/Metadata.test.d.ts.map | 1 + packages/utils/dist/test/Metadata.test.js | 108 +++++++++ packages/utils/dist/test/Metadata.test.js.map | 1 + .../utils/dist/test/StreamSplitter.test.d.ts | 2 + .../dist/test/StreamSplitter.test.d.ts.map | 1 + .../utils/dist/test/StreamSplitter.test.js | 47 ++++ .../dist/test/StreamSplitter.test.js.map | 1 + packages/utils/dist/test/Uid.test.d.ts | 2 + packages/utils/dist/test/Uid.test.d.ts.map | 1 + packages/utils/dist/test/Uid.test.js | 20 ++ packages/utils/dist/test/Uid.test.js.map | 1 + packages/utils/dist/test/Upload.test.d.ts | 2 + packages/utils/dist/test/Upload.test.d.ts.map | 1 + packages/utils/dist/test/Upload.test.js | 27 +++ packages/utils/dist/test/Upload.test.js.map | 1 + packages/utils/dist/test/stores.d.ts | 10 + packages/utils/dist/test/stores.d.ts.map | 1 + packages/utils/dist/test/stores.js | 225 ++++++++++++++++++ packages/utils/dist/test/stores.js.map | 1 + 98 files changed, 1677 insertions(+), 2 deletions(-) create mode 100644 packages/azure-store/dist/index.d.ts create mode 100644 packages/azure-store/dist/index.d.ts.map create mode 100644 packages/azure-store/dist/index.js create mode 100644 packages/azure-store/dist/index.js.map create mode 100644 packages/azure-store/dist/test/index.d.ts create mode 100644 packages/azure-store/dist/test/index.d.ts.map create mode 100644 packages/azure-store/dist/test/index.js create mode 100644 packages/azure-store/dist/test/index.js.map create mode 100644 packages/utils/dist/constants.d.ts create mode 100644 packages/utils/dist/constants.d.ts.map create mode 100644 packages/utils/dist/constants.js create mode 100644 packages/utils/dist/constants.js.map create mode 100644 packages/utils/dist/index.d.ts create mode 100644 packages/utils/dist/index.d.ts.map create mode 100644 packages/utils/dist/index.js create mode 100644 packages/utils/dist/index.js.map create mode 100644 packages/utils/dist/kvstores/FileKvStore.d.ts create mode 100644 packages/utils/dist/kvstores/FileKvStore.d.ts.map create mode 100644 packages/utils/dist/kvstores/FileKvStore.js create mode 100644 packages/utils/dist/kvstores/FileKvStore.js.map create mode 100644 packages/utils/dist/kvstores/IoRedisKvStore.d.ts create mode 100644 packages/utils/dist/kvstores/IoRedisKvStore.d.ts.map create mode 100644 packages/utils/dist/kvstores/IoRedisKvStore.js create mode 100644 packages/utils/dist/kvstores/IoRedisKvStore.js.map create mode 100644 packages/utils/dist/kvstores/MemoryKvStore.d.ts create mode 100644 packages/utils/dist/kvstores/MemoryKvStore.d.ts.map create mode 100644 packages/utils/dist/kvstores/MemoryKvStore.js create mode 100644 packages/utils/dist/kvstores/MemoryKvStore.js.map create mode 100644 packages/utils/dist/kvstores/RedisKvStore.d.ts create mode 100644 packages/utils/dist/kvstores/RedisKvStore.d.ts.map create mode 100644 packages/utils/dist/kvstores/RedisKvStore.js create mode 100644 packages/utils/dist/kvstores/RedisKvStore.js.map create mode 100644 packages/utils/dist/kvstores/Types.d.ts create mode 100644 packages/utils/dist/kvstores/Types.d.ts.map create mode 100644 packages/utils/dist/kvstores/Types.js create mode 100644 packages/utils/dist/kvstores/Types.js.map create mode 100644 packages/utils/dist/kvstores/index.d.ts create mode 100644 packages/utils/dist/kvstores/index.d.ts.map create mode 100644 packages/utils/dist/kvstores/index.js create mode 100644 packages/utils/dist/kvstores/index.js.map create mode 100644 packages/utils/dist/models/Context.d.ts create mode 100644 packages/utils/dist/models/Context.d.ts.map create mode 100644 packages/utils/dist/models/Context.js create mode 100644 packages/utils/dist/models/Context.js.map create mode 100644 packages/utils/dist/models/DataStore.d.ts create mode 100644 packages/utils/dist/models/DataStore.d.ts.map create mode 100644 packages/utils/dist/models/DataStore.js create mode 100644 packages/utils/dist/models/DataStore.js.map create mode 100644 packages/utils/dist/models/Locker.d.ts create mode 100644 packages/utils/dist/models/Locker.d.ts.map create mode 100644 packages/utils/dist/models/Locker.js create mode 100644 packages/utils/dist/models/Locker.js.map create mode 100644 packages/utils/dist/models/Metadata.d.ts create mode 100644 packages/utils/dist/models/Metadata.d.ts.map create mode 100644 packages/utils/dist/models/Metadata.js create mode 100644 packages/utils/dist/models/Metadata.js.map create mode 100644 packages/utils/dist/models/StreamLimiter.d.ts create mode 100644 packages/utils/dist/models/StreamLimiter.d.ts.map create mode 100644 packages/utils/dist/models/StreamLimiter.js create mode 100644 packages/utils/dist/models/StreamLimiter.js.map create mode 100644 packages/utils/dist/models/StreamSplitter.d.ts create mode 100644 packages/utils/dist/models/StreamSplitter.d.ts.map create mode 100644 packages/utils/dist/models/StreamSplitter.js create mode 100644 packages/utils/dist/models/StreamSplitter.js.map create mode 100644 packages/utils/dist/models/Uid.d.ts create mode 100644 packages/utils/dist/models/Uid.d.ts.map create mode 100644 packages/utils/dist/models/Uid.js create mode 100644 packages/utils/dist/models/Uid.js.map create mode 100644 packages/utils/dist/models/Upload.d.ts create mode 100644 packages/utils/dist/models/Upload.d.ts.map create mode 100644 packages/utils/dist/models/Upload.js create mode 100644 packages/utils/dist/models/Upload.js.map create mode 100644 packages/utils/dist/models/index.d.ts create mode 100644 packages/utils/dist/models/index.d.ts.map create mode 100644 packages/utils/dist/models/index.js create mode 100644 packages/utils/dist/models/index.js.map create mode 100644 packages/utils/dist/test/Metadata.test.d.ts create mode 100644 packages/utils/dist/test/Metadata.test.d.ts.map create mode 100644 packages/utils/dist/test/Metadata.test.js create mode 100644 packages/utils/dist/test/Metadata.test.js.map create mode 100644 packages/utils/dist/test/StreamSplitter.test.d.ts create mode 100644 packages/utils/dist/test/StreamSplitter.test.d.ts.map create mode 100644 packages/utils/dist/test/StreamSplitter.test.js create mode 100644 packages/utils/dist/test/StreamSplitter.test.js.map create mode 100644 packages/utils/dist/test/Uid.test.d.ts create mode 100644 packages/utils/dist/test/Uid.test.d.ts.map create mode 100644 packages/utils/dist/test/Uid.test.js create mode 100644 packages/utils/dist/test/Uid.test.js.map create mode 100644 packages/utils/dist/test/Upload.test.d.ts create mode 100644 packages/utils/dist/test/Upload.test.d.ts.map create mode 100644 packages/utils/dist/test/Upload.test.js create mode 100644 packages/utils/dist/test/Upload.test.js.map create mode 100644 packages/utils/dist/test/stores.d.ts create mode 100644 packages/utils/dist/test/stores.d.ts.map create mode 100644 packages/utils/dist/test/stores.js create mode 100644 packages/utils/dist/test/stores.js.map diff --git a/.gitignore b/.gitignore index 9da13f3f..4aa7df5b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ .idea .eslintcache -dist +# dist .turbo *.tsbuildinfo output/ diff --git a/packages/azure-store/dist/index.d.ts b/packages/azure-store/dist/index.d.ts new file mode 100644 index 00000000..7acc8ca2 --- /dev/null +++ b/packages/azure-store/dist/index.d.ts @@ -0,0 +1,52 @@ +import type stream from 'node:stream'; +import { DataStore, Upload, type KvStore } from '@tus/utils'; +import type { TokenCredential } from '@azure/core-auth'; +type Options = { + cache?: KvStore; + account: string; + containerName: string; + accountKey?: string; + credential?: TokenCredential; +}; +/** + * Store using the Azure Storage SDK + * @author Bharath Battaje + */ +export declare class AzureStore extends DataStore { + private cache; + private blobServiceClient; + private containerClient; + private containerName; + constructor(options: Options); + /** + * Saves upload metadata to blob metada. Also upload metadata + * gets saved in local cache as well to avoid calling azure server everytime. + */ + private saveMetadata; + /** + * Retrieves upload metadata previously saved. + * It tries to get from local cache, else get from the blob metadata. + */ + private getMetadata; + /** + * provides the readable stream for the previously uploaded file + */ + read(file_id: string): Promise; + /** + * Creates a empty append blob on Azure storage and attaches the metadata to it. + */ + create(upload: Upload): Promise; + /** + * Gets the current file upload status + */ + getUpload(id: string): Promise; + /** + * Uploads each blob to the azure blob storage. Please note that current official Azure stoarge node sdk has some limitation + * when it comes to stream upload. So here we are concatenating all the chunks from a request into a block and then uploading + * to azure storage using the appendBlock. This can be upgraded to streamUpload when node sdk start supporting it. + */ + write(stream: stream.Readable, id: string, offset: number): Promise; + declareUploadLength(id: string, upload_length: number): Promise; +} +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/azure-store/dist/index.d.ts.map b/packages/azure-store/dist/index.d.ts.map new file mode 100644 index 00000000..8b539cf6 --- /dev/null +++ b/packages/azure-store/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC,OAAO,EACL,SAAS,EACT,MAAM,EAEN,KAAK,OAAO,EAIb,MAAM,YAAY,CAAA;AAQnB,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAA;AAErD,KAAK,OAAO,GAAG;IACb,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,eAAe,CAAA;CAC7B,CAAA;AAID;;;GAGG;AACH,qBAAa,UAAW,SAAQ,SAAS;IACvC,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,iBAAiB,CAAmB;IAC5C,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,aAAa,CAAQ;gBAEjB,OAAO,EAAE,OAAO;IA8B5B;;;OAGG;YACW,YAAY;IAoB1B;;;OAGG;YACW,WAAW;IA+BzB;;OAEG;IACU,IAAI,CAAC,OAAO,EAAE,MAAM;IAOjC;;OAEG;IACU,MAAM,CAAC,MAAM,EAAE,MAAM;IAqBlC;;OAEG;IACU,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBnD;;;;OAIG;IACU,KAAK,CAChB,MAAM,EAAE,MAAM,CAAC,QAAQ,EACvB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC;IAqDL,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM;CAYnE"} \ No newline at end of file diff --git a/packages/azure-store/dist/index.js b/packages/azure-store/dist/index.js new file mode 100644 index 00000000..5e9911c8 --- /dev/null +++ b/packages/azure-store/dist/index.js @@ -0,0 +1,183 @@ +import debug from 'debug'; +import { DataStore, Upload, ERRORS, MemoryKvStore, TUS_RESUMABLE, Metadata, } from '@tus/utils'; +import { BlobServiceClient, StorageSharedKeyCredential, } from '@azure/storage-blob'; +const log = debug('tus-node-server:stores:azurestore'); +/** + * Store using the Azure Storage SDK + * @author Bharath Battaje + */ +export class AzureStore extends DataStore { + cache; + blobServiceClient; + containerClient; + containerName; + constructor(options) { + super(); + this.cache = options.cache ?? new MemoryKvStore(); + this.extensions = ['creation', 'creation-defer-length']; + if (!options.account) { + throw new Error('Azure store must have a account'); + } + if (!options.containerName) { + throw new Error('Azure store must have a container name'); + } + if (!options.accountKey && !options.credential) { + throw new Error('Azure store requires either accountKey or credential'); + } + const storageAccountBaseUrl = `https://${options.account}.blob.core.windows.net`; + const credential = options.credential + ? options.credential + : new StorageSharedKeyCredential(options.account, options.accountKey); + this.blobServiceClient = new BlobServiceClient(storageAccountBaseUrl, credential); + this.containerClient = this.blobServiceClient.getContainerClient(options.containerName); + this.containerName = options.containerName; + } + /** + * Saves upload metadata to blob metada. Also upload metadata + * gets saved in local cache as well to avoid calling azure server everytime. + */ + async saveMetadata(appendBlobClient, upload) { + log(`[${upload.id}] saving metadata`); + await this.cache.set(appendBlobClient.url, upload); + await appendBlobClient.setMetadata({ + tus_version: TUS_RESUMABLE, + upload: JSON.stringify({ + ...upload, + // Base64 encode the metadata to avoid errors for non-ASCII characters + metadata: Metadata.stringify(upload.metadata ?? {}), + }), + }, {}); + log(`[${upload.id}] metadata saved`); + } + /** + * Retrieves upload metadata previously saved. + * It tries to get from local cache, else get from the blob metadata. + */ + async getMetadata(appendBlobClient) { + const cached = await this.cache.get(appendBlobClient.url); + if (cached) { + log(`[${cached.id}] metadata returned from cache`); + return cached; + } + let propertyData; + try { + propertyData = await appendBlobClient.getProperties(); + } + catch (error) { + log('Error while fetching the metadata.', error); + throw ERRORS.UNKNOWN_ERROR; + } + if (!propertyData.metadata) { + throw ERRORS.FILE_NOT_FOUND; + } + const upload = JSON.parse(propertyData.metadata.upload); + // Metadata is base64 encoded to avoid errors for non-ASCII characters + // so we need to decode it separately + upload.metadata = Metadata.parse(JSON.stringify(upload.metadata ?? {})); + await this.cache.set(appendBlobClient.url, upload); + log('metadata returned from blob get properties'); + return upload; + } + /** + * provides the readable stream for the previously uploaded file + */ + async read(file_id) { + const appendBlobClient = this.containerClient.getAppendBlobClient(file_id); + const downloadResponse = await appendBlobClient.download(); + return downloadResponse.readableStreamBody; + } + /** + * Creates a empty append blob on Azure storage and attaches the metadata to it. + */ + async create(upload) { + log(`[${upload.id}] initializing azure storage file upload`); + try { + const appendBlobClient = this.containerClient.getAppendBlobClient(upload.id); + await appendBlobClient.createIfNotExists(); + upload.storage = { + type: 'AzureBlobStore', + path: upload.id, + bucket: this.containerName, + }; + await this.saveMetadata(appendBlobClient, upload); + return upload; + } + catch (err) { + throw ERRORS.UNKNOWN_ERROR; + } + } + /** + * Gets the current file upload status + */ + async getUpload(id) { + const appendBlobClient = this.containerClient.getAppendBlobClient(id); + const upload = await this.getMetadata(appendBlobClient); + if (!upload) { + throw ERRORS.FILE_NOT_FOUND; + } + return new Upload({ + id: id, + size: upload.size, + metadata: upload.metadata, + offset: upload.offset, + storage: upload.storage, + creation_date: upload.creation_date, + }); + } + /** + * Uploads each blob to the azure blob storage. Please note that current official Azure stoarge node sdk has some limitation + * when it comes to stream upload. So here we are concatenating all the chunks from a request into a block and then uploading + * to azure storage using the appendBlock. This can be upgraded to streamUpload when node sdk start supporting it. + */ + async write(stream, id, offset) { + log(`started writing the file offset [${offset}]`); + const appendBlobClient = this.containerClient.getAppendBlobClient(id); + const upload = await this.getMetadata(appendBlobClient); + // biome-ignore lint/suspicious/noAsyncPromiseExecutor: + return new Promise(async (resolve, reject) => { + if (offset < upload.offset) { + //duplicate request scenario, dont want to write the same data + return resolve(upload.offset); + } + try { + const bufs = []; + stream.on('data', async (chunk) => { + if (stream.destroyed) { + return reject(ERRORS.ABORTED); + } + bufs.push(chunk); + }); + stream.on('end', async () => { + const buf = Buffer.concat(bufs); + if (buf.length > 0) { + await appendBlobClient.appendBlock(buf, buf.length); + } + upload.offset = upload.offset + buf.length; + log(`saved offset is [${upload.offset}]`); + await this.saveMetadata(appendBlobClient, upload); + if (upload.offset === upload.size) { + await this.cache.delete(appendBlobClient.url); + log(`file upload completed successfully [${id}]`); + } + return resolve(upload.offset); + }); + stream.on('error', async () => { + return reject(ERRORS.UNKNOWN_ERROR); + }); + } + catch (err) { + return reject('something went wrong while writing the file.'); + } + }); + } + async declareUploadLength(id, upload_length) { + const appendBlobClient = this.containerClient.getAppendBlobClient(id); + const upload = await this.getMetadata(appendBlobClient); + if (!upload) { + throw ERRORS.FILE_NOT_FOUND; + } + upload.size = upload_length; + await this.saveMetadata(appendBlobClient, upload); + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/azure-store/dist/index.js.map b/packages/azure-store/dist/index.js.map new file mode 100644 index 00000000..8923d2ae --- /dev/null +++ b/packages/azure-store/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EACL,SAAS,EACT,MAAM,EACN,MAAM,EAEN,aAAa,EACb,aAAa,EACb,QAAQ,GACT,MAAM,YAAY,CAAA;AACnB,OAAO,EAGL,iBAAiB,EAEjB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAA;AAW5B,MAAM,GAAG,GAAG,KAAK,CAAC,mCAAmC,CAAC,CAAA;AAEtD;;;GAGG;AACH,MAAM,OAAO,UAAW,SAAQ,SAAS;IAC/B,KAAK,CAAiB;IACtB,iBAAiB,CAAmB;IACpC,eAAe,CAAiB;IAChC,aAAa,CAAQ;IAE7B,YAAY,OAAgB;QAC1B,KAAK,EAAE,CAAA;QACP,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,aAAa,EAAU,CAAA;QACzD,IAAI,CAAC,UAAU,GAAG,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAA;QAEvD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;QACpD,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QAC3D,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAA;QACzE,CAAC;QAED,MAAM,qBAAqB,GAAG,WAAW,OAAO,CAAC,OAAO,wBAAwB,CAAA;QAChF,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU;YACnC,CAAC,CAAC,OAAO,CAAC,UAAU;YACpB,CAAC,CAAC,IAAI,0BAA0B,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,UAAW,CAAC,CAAA;QAExE,IAAI,CAAC,iBAAiB,GAAG,IAAI,iBAAiB,CAC5C,qBAAqB,EACrB,UAAU,CACX,CAAA;QACD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAC9D,OAAO,CAAC,aAAa,CACtB,CAAA;QACD,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAA;IAC5C,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,YAAY,CAAC,gBAAkC,EAAE,MAAc;QAC3E,GAAG,CAAC,IAAI,MAAM,CAAC,EAAE,mBAAmB,CAAC,CAAA;QAErC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QAElD,MAAM,gBAAgB,CAAC,WAAW,CAChC;YACE,WAAW,EAAE,aAAa;YAC1B,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;gBACrB,GAAG,MAAM;gBACT,sEAAsE;gBACtE,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;aACpD,CAAC;SACH,EACD,EAAE,CACH,CAAA;QAED,GAAG,CAAC,IAAI,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAA;IACtC,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,WAAW,CAAC,gBAAkC;QAC1D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAA;QAEzD,IAAI,MAAM,EAAE,CAAC;YACX,GAAG,CAAC,IAAI,MAAM,CAAC,EAAE,gCAAgC,CAAC,CAAA;YAClD,OAAO,MAAM,CAAA;QACf,CAAC;QAED,IAAI,YAAuC,CAAA;QAC3C,IAAI,CAAC;YACH,YAAY,GAAG,MAAM,gBAAgB,CAAC,aAAa,EAAE,CAAA;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAA;YAChD,MAAM,MAAM,CAAC,aAAa,CAAA;QAC5B,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC3B,MAAM,MAAM,CAAC,cAAc,CAAA;QAC7B,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAW,CAAA;QACjE,sEAAsE;QACtE,qCAAqC;QACrC,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAA;QAEvE,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QAElD,GAAG,CAAC,4CAA4C,CAAC,CAAA;QAEjD,OAAO,MAAM,CAAA;IACf,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAAC,OAAe;QAC/B,MAAM,gBAAgB,GAAG,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAA;QAC1E,MAAM,gBAAgB,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,CAAA;QAE1D,OAAO,gBAAgB,CAAC,kBAAkB,CAAA;IAC5C,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,MAAM,CAAC,MAAc;QAChC,GAAG,CAAC,IAAI,MAAM,CAAC,EAAE,0CAA0C,CAAC,CAAA;QAE5D,IAAI,CAAC;YACH,MAAM,gBAAgB,GAAG,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YAC5E,MAAM,gBAAgB,CAAC,iBAAiB,EAAE,CAAA;YAE1C,MAAM,CAAC,OAAO,GAAG;gBACf,IAAI,EAAE,gBAAgB;gBACtB,IAAI,EAAE,MAAM,CAAC,EAAE;gBACf,MAAM,EAAE,IAAI,CAAC,aAAa;aAC3B,CAAA;YAED,MAAM,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAA;YAEjD,OAAO,MAAM,CAAA;QACf,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,CAAC,aAAa,CAAA;QAC5B,CAAC;IACH,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,SAAS,CAAC,EAAU;QAC/B,MAAM,gBAAgB,GAAG,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAA;QACrE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAA;QAEvD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,MAAM,CAAC,cAAc,CAAA;QAC7B,CAAC;QAED,OAAO,IAAI,MAAM,CAAC;YAChB,EAAE,EAAE,EAAE;YACN,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,aAAa,EAAE,MAAM,CAAC,aAAa;SACpC,CAAC,CAAA;IACJ,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,KAAK,CAChB,MAAuB,EACvB,EAAU,EACV,MAAc;QAEd,GAAG,CAAC,oCAAoC,MAAM,GAAG,CAAC,CAAA;QAElD,MAAM,gBAAgB,GAAG,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAA;QACrE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAA;QAEvD,qEAAqE;QACrE,OAAO,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,IAAI,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC3B,8DAA8D;gBAC9D,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;YAC/B,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,IAAI,GAAa,EAAE,CAAA;gBAEzB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAa,EAAE,EAAE;oBACxC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;wBACrB,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;oBAC/B,CAAC;oBAED,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBAClB,CAAC,CAAC,CAAA;gBAEF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;oBAC1B,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;oBAE/B,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACnB,MAAM,gBAAgB,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;oBACrD,CAAC;oBAED,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAA;oBAC1C,GAAG,CAAC,oBAAoB,MAAM,CAAC,MAAM,GAAG,CAAC,CAAA;oBAEzC,MAAM,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAA;oBAEjD,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC;wBAClC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAA;wBAC7C,GAAG,CAAC,uCAAuC,EAAE,GAAG,CAAC,CAAA;oBACnD,CAAC;oBAED,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;gBAC/B,CAAC,CAAC,CAAA;gBAEF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;oBAC5B,OAAO,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;gBACrC,CAAC,CAAC,CAAA;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,MAAM,CAAC,8CAA8C,CAAC,CAAA;YAC/D,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAEM,KAAK,CAAC,mBAAmB,CAAC,EAAU,EAAE,aAAqB;QAChE,MAAM,gBAAgB,GAAG,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAA;QACrE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAA;QAEvD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,MAAM,CAAC,cAAc,CAAA;QAC7B,CAAC;QAED,MAAM,CAAC,IAAI,GAAG,aAAa,CAAA;QAE3B,MAAM,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAA;IACnD,CAAC;CACF"} \ No newline at end of file diff --git a/packages/azure-store/dist/test/index.d.ts b/packages/azure-store/dist/test/index.d.ts new file mode 100644 index 00000000..2f8a39e2 --- /dev/null +++ b/packages/azure-store/dist/test/index.d.ts @@ -0,0 +1,2 @@ +import 'should'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/azure-store/dist/test/index.d.ts.map b/packages/azure-store/dist/test/index.d.ts.map new file mode 100644 index 00000000..90649a39 --- /dev/null +++ b/packages/azure-store/dist/test/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAA"} \ No newline at end of file diff --git a/packages/azure-store/dist/test/index.js b/packages/azure-store/dist/test/index.js new file mode 100644 index 00000000..a505d242 --- /dev/null +++ b/packages/azure-store/dist/test/index.js @@ -0,0 +1,29 @@ +import 'should'; +import path from 'node:path'; +import { AzureStore } from '@tus/azure-store'; +import * as shared from '../../../utils/dist/test/stores.js'; +const fixturesPath = path.resolve('../', '../', 'test', 'fixtures'); +const storePath = path.resolve('../', '../', 'test', 'output', 'azure-store'); +describe('AzureStore', () => { + before(function () { + this.testFileSize = 960_244; + this.testFileName = 'test.mp4'; + this.storePath = storePath; + this.testFilePath = path.resolve(fixturesPath, this.testFileName); + }); + beforeEach(function () { + this.datastore = new AzureStore({ + account: process.env.AZURE_ACCOUNT_ID, + accountKey: process.env.AZURE_ACCOUNT_KEY, + containerName: process.env.AZURE_CONTAINER_NAME, + }); + }); + shared.shouldHaveStoreMethods(); + shared.shouldCreateUploads(); + // shared.shouldRemoveUploads() // Not implemented yet + // shared.shouldExpireUploads() // Not implemented yet + shared.shouldWriteUploads(); + shared.shouldHandleOffset(); + shared.shouldDeclareUploadLength(); // Creation-defer-length extension +}); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/azure-store/dist/test/index.js.map b/packages/azure-store/dist/test/index.js.map new file mode 100644 index 00000000..cf6cd079 --- /dev/null +++ b/packages/azure-store/dist/test/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAA;AACf,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,oCAAoC,CAAA;AAE5D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAA;AACnE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAA;AAE7E,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,MAAM,CAAC;QACL,IAAI,CAAC,YAAY,GAAG,OAAO,CAAA;QAC3B,IAAI,CAAC,YAAY,GAAG,UAAU,CAAA;QAC9B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;IACnE,CAAC,CAAC,CAAA;IAEF,UAAU,CAAC;QACT,IAAI,CAAC,SAAS,GAAG,IAAI,UAAU,CAAC;YAC9B,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,gBAA0B;YAC/C,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,iBAA2B;YACnD,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,oBAA8B;SAC1D,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,sBAAsB,EAAE,CAAA;IAC/B,MAAM,CAAC,mBAAmB,EAAE,CAAA;IAC5B,sDAAsD;IACtD,sDAAsD;IACtD,MAAM,CAAC,kBAAkB,EAAE,CAAA;IAC3B,MAAM,CAAC,kBAAkB,EAAE,CAAA;IAC3B,MAAM,CAAC,yBAAyB,EAAE,CAAA,CAAC,kCAAkC;AACvE,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/packages/azure-store/package.json b/packages/azure-store/package.json index 5c7a3061..ee25781e 100644 --- a/packages/azure-store/package.json +++ b/packages/azure-store/package.json @@ -36,4 +36,4 @@ "engines": { "node": ">=20.19.0" } -} +} \ No newline at end of file diff --git a/packages/utils/dist/constants.d.ts b/packages/utils/dist/constants.d.ts new file mode 100644 index 00000000..d5fabcb4 --- /dev/null +++ b/packages/utils/dist/constants.d.ts @@ -0,0 +1,90 @@ +export declare const REQUEST_METHODS: readonly ["POST", "HEAD", "PATCH", "OPTIONS", "DELETE"]; +export declare const HEADERS: readonly ["Authorization", "Content-Type", "Location", "Tus-Extension", "Tus-Max-Size", "Tus-Resumable", "Tus-Version", "Upload-Concat", "Upload-Defer-Length", "Upload-Length", "Upload-Metadata", "Upload-Offset", "X-HTTP-Method-Override", "X-Requested-With", "X-Forwarded-Host", "X-Forwarded-Proto", "Forwarded"]; +export declare const HEADERS_LOWERCASE: Array>; +export declare const ALLOWED_HEADERS: string; +export declare const ALLOWED_METHODS: string; +export declare const EXPOSED_HEADERS: string; +export declare const ERRORS: { + readonly MISSING_OFFSET: { + readonly status_code: 403; + readonly body: "Upload-Offset header required\n"; + }; + readonly ABORTED: { + readonly status_code: 400; + readonly body: "Request aborted due to lock acquired"; + }; + readonly INVALID_TERMINATION: { + readonly status_code: 400; + readonly body: "Cannot terminate an already completed upload"; + }; + readonly ERR_LOCK_TIMEOUT: { + readonly status_code: 500; + readonly body: "failed to acquire lock before timeout"; + }; + readonly INVALID_CONTENT_TYPE: { + readonly status_code: 403; + readonly body: "Content-Type header required\n"; + }; + readonly FILE_NOT_FOUND: { + readonly status_code: 404; + readonly body: "The file for this url was not found\n"; + }; + readonly INVALID_OFFSET: { + readonly status_code: 409; + readonly body: "Upload-Offset conflict\n"; + }; + readonly FILE_NO_LONGER_EXISTS: { + readonly status_code: 410; + readonly body: "The file for this url no longer exists\n"; + }; + readonly ERR_SIZE_EXCEEDED: { + readonly status_code: 413; + readonly body: "upload's size exceeded\n"; + }; + readonly ERR_MAX_SIZE_EXCEEDED: { + readonly status_code: 413; + readonly body: "Maximum size exceeded\n"; + }; + readonly INVALID_LENGTH: { + readonly status_code: 400; + readonly body: "Upload-Length or Upload-Defer-Length header required\n"; + }; + readonly INVALID_METADATA: { + readonly status_code: 400; + readonly body: "Upload-Metadata is invalid. It MUST consist of one or more comma-separated key-value pairs. The key and value MUST be separated by a space. The key MUST NOT contain spaces and commas and MUST NOT be empty. The key SHOULD be ASCII encoded and the value MUST be Base64 encoded. All keys MUST be unique"; + }; + readonly UNKNOWN_ERROR: { + readonly status_code: 500; + readonly body: "Something went wrong with that request\n"; + }; + readonly FILE_WRITE_ERROR: { + readonly status_code: 500; + readonly body: "Something went wrong receiving the file\n"; + }; + readonly UNSUPPORTED_CONCATENATION_EXTENSION: { + readonly status_code: 501; + readonly body: "Concatenation extension is not (yet) supported. Disable parallel uploads in the tus client.\n"; + }; + readonly UNSUPPORTED_CREATION_DEFER_LENGTH_EXTENSION: { + readonly status_code: 501; + readonly body: "creation-defer-length extension is not (yet) supported.\n"; + }; + readonly UNSUPPORTED_EXPIRATION_EXTENSION: { + readonly status_code: 501; + readonly body: "expiration extension is not (yet) supported.\n"; + }; +}; +export declare const POST_CREATE: "POST_CREATE"; +export declare const POST_RECEIVE: "POST_RECEIVE"; +export declare const POST_FINISH: "POST_FINISH"; +export declare const POST_TERMINATE: "POST_TERMINATE"; +export declare const EVENTS: { + readonly POST_CREATE: "POST_CREATE"; + readonly POST_RECEIVE: "POST_RECEIVE"; + readonly POST_FINISH: "POST_FINISH"; + readonly POST_TERMINATE: "POST_TERMINATE"; +}; +export declare const MAX_AGE: 86400; +export declare const TUS_RESUMABLE: "1.0.0"; +export declare const TUS_VERSION: readonly ["1.0.0"]; +//# sourceMappingURL=constants.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/constants.d.ts.map b/packages/utils/dist/constants.d.ts.map new file mode 100644 index 00000000..1c6c9615 --- /dev/null +++ b/packages/utils/dist/constants.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,yDAA0D,CAAA;AAEtF,eAAO,MAAM,OAAO,0TAkBV,CAAA;AAEV,eAAO,MAAM,iBAAiB,EAExB,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;AAEhD,eAAO,MAAM,eAAe,QAAqB,CAAA;AACjD,eAAO,MAAM,eAAe,QAA6B,CAAA;AACzD,eAAO,MAAM,eAAe,QAAqB,CAAA;AAEjD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqET,CAAA;AAEV,eAAO,MAAM,WAAW,EAAG,aAAsB,CAAA;AACjD,eAAO,MAAM,YAAY,EAAG,cAAuB,CAAA;AACnD,eAAO,MAAM,WAAW,EAAG,aAAsB,CAAA;AACjD,eAAO,MAAM,cAAc,EAAG,gBAAyB,CAAA;AACvD,eAAO,MAAM,MAAM;;;;;CAKT,CAAA;AAEV,eAAO,MAAM,OAAO,EAAG,KAAe,CAAA;AACtC,eAAO,MAAM,aAAa,EAAG,OAAgB,CAAA;AAC7C,eAAO,MAAM,WAAW,oBAAqB,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/constants.js b/packages/utils/dist/constants.js new file mode 100644 index 00000000..bfe451a7 --- /dev/null +++ b/packages/utils/dist/constants.js @@ -0,0 +1,110 @@ +export const REQUEST_METHODS = ['POST', 'HEAD', 'PATCH', 'OPTIONS', 'DELETE']; +export const HEADERS = [ + 'Authorization', + 'Content-Type', + 'Location', + 'Tus-Extension', + 'Tus-Max-Size', + 'Tus-Resumable', + 'Tus-Version', + 'Upload-Concat', + 'Upload-Defer-Length', + 'Upload-Length', + 'Upload-Metadata', + 'Upload-Offset', + 'X-HTTP-Method-Override', + 'X-Requested-With', + 'X-Forwarded-Host', + 'X-Forwarded-Proto', + 'Forwarded', +]; +export const HEADERS_LOWERCASE = HEADERS.map((header) => { + return header.toLowerCase(); +}); +export const ALLOWED_HEADERS = HEADERS.join(', '); +export const ALLOWED_METHODS = REQUEST_METHODS.join(', '); +export const EXPOSED_HEADERS = HEADERS.join(', '); +export const ERRORS = { + MISSING_OFFSET: { + status_code: 403, + body: 'Upload-Offset header required\n', + }, + ABORTED: { + status_code: 400, + body: 'Request aborted due to lock acquired', + }, + INVALID_TERMINATION: { + status_code: 400, + body: 'Cannot terminate an already completed upload', + }, + ERR_LOCK_TIMEOUT: { + status_code: 500, + body: 'failed to acquire lock before timeout', + }, + INVALID_CONTENT_TYPE: { + status_code: 403, + body: 'Content-Type header required\n', + }, + FILE_NOT_FOUND: { + status_code: 404, + body: 'The file for this url was not found\n', + }, + INVALID_OFFSET: { + status_code: 409, + body: 'Upload-Offset conflict\n', + }, + FILE_NO_LONGER_EXISTS: { + status_code: 410, + body: 'The file for this url no longer exists\n', + }, + ERR_SIZE_EXCEEDED: { + status_code: 413, + body: "upload's size exceeded\n", + }, + ERR_MAX_SIZE_EXCEEDED: { + status_code: 413, + body: 'Maximum size exceeded\n', + }, + INVALID_LENGTH: { + status_code: 400, + body: 'Upload-Length or Upload-Defer-Length header required\n', + }, + INVALID_METADATA: { + status_code: 400, + body: 'Upload-Metadata is invalid. It MUST consist of one or more comma-separated key-value pairs. The key and value MUST be separated by a space. The key MUST NOT contain spaces and commas and MUST NOT be empty. The key SHOULD be ASCII encoded and the value MUST be Base64 encoded. All keys MUST be unique', + }, + UNKNOWN_ERROR: { + status_code: 500, + body: 'Something went wrong with that request\n', + }, + FILE_WRITE_ERROR: { + status_code: 500, + body: 'Something went wrong receiving the file\n', + }, + UNSUPPORTED_CONCATENATION_EXTENSION: { + status_code: 501, + body: 'Concatenation extension is not (yet) supported. Disable parallel uploads in the tus client.\n', + }, + UNSUPPORTED_CREATION_DEFER_LENGTH_EXTENSION: { + status_code: 501, + body: 'creation-defer-length extension is not (yet) supported.\n', + }, + UNSUPPORTED_EXPIRATION_EXTENSION: { + status_code: 501, + body: 'expiration extension is not (yet) supported.\n', + }, +}; +export const POST_CREATE = 'POST_CREATE'; +export const POST_RECEIVE = 'POST_RECEIVE'; +export const POST_FINISH = 'POST_FINISH'; +export const POST_TERMINATE = 'POST_TERMINATE'; +export const EVENTS = { + POST_CREATE, + POST_RECEIVE, + POST_FINISH, + POST_TERMINATE, +}; +export const MAX_AGE = 86_400; +export const TUS_RESUMABLE = '1.0.0'; +export const TUS_VERSION = ['1.0.0']; +//# sourceMappingURL=constants.js.map \ No newline at end of file diff --git a/packages/utils/dist/constants.js.map b/packages/utils/dist/constants.js.map new file mode 100644 index 00000000..62e83c77 --- /dev/null +++ b/packages/utils/dist/constants.js.map @@ -0,0 +1 @@ +{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/utils/dist/index.d.ts b/packages/utils/dist/index.d.ts new file mode 100644 index 00000000..3b5ac364 --- /dev/null +++ b/packages/utils/dist/index.d.ts @@ -0,0 +1,4 @@ +export * from './models/index.js'; +export * from './constants.js'; +export * from './kvstores/index.js'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/index.d.ts.map b/packages/utils/dist/index.d.ts.map new file mode 100644 index 00000000..cca01cb5 --- /dev/null +++ b/packages/utils/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/index.js b/packages/utils/dist/index.js new file mode 100644 index 00000000..2fe856d6 --- /dev/null +++ b/packages/utils/dist/index.js @@ -0,0 +1,4 @@ +export * from './models/index.js'; +export * from './constants.js'; +export * from './kvstores/index.js'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/utils/dist/index.js.map b/packages/utils/dist/index.js.map new file mode 100644 index 00000000..2af37165 --- /dev/null +++ b/packages/utils/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/FileKvStore.d.ts b/packages/utils/dist/kvstores/FileKvStore.d.ts new file mode 100644 index 00000000..f1ed2de6 --- /dev/null +++ b/packages/utils/dist/kvstores/FileKvStore.d.ts @@ -0,0 +1,16 @@ +import type { KvStore } from './Types.js'; +import type { Upload } from '../models/index.js'; +/** + * FileConfigstore writes the `Upload` JSON metadata to disk next the uploaded file itself. + * It uses a queue which only processes one operation at a time to prevent unsafe concurrent access. + */ +export declare class FileKvStore implements KvStore { + directory: string; + constructor(path: string); + get(key: string): Promise; + set(key: string, value: T): Promise; + delete(key: string): Promise; + list(): Promise>; + private resolve; +} +//# sourceMappingURL=FileKvStore.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/FileKvStore.d.ts.map b/packages/utils/dist/kvstores/FileKvStore.d.ts.map new file mode 100644 index 00000000..98091416 --- /dev/null +++ b/packages/utils/dist/kvstores/FileKvStore.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"FileKvStore.d.ts","sourceRoot":"","sources":["../../src/kvstores/FileKvStore.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAA;AAE9C;;;GAGG;AACH,qBAAa,WAAW,CAAC,CAAC,GAAG,MAAM,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;IACxD,SAAS,EAAE,MAAM,CAAA;gBAEL,IAAI,EAAE,MAAM;IAIlB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IASxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAUpC,OAAO,CAAC,OAAO;CAGhB"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/FileKvStore.js b/packages/utils/dist/kvstores/FileKvStore.js new file mode 100644 index 00000000..4723a944 --- /dev/null +++ b/packages/utils/dist/kvstores/FileKvStore.js @@ -0,0 +1,38 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; +/** + * FileConfigstore writes the `Upload` JSON metadata to disk next the uploaded file itself. + * It uses a queue which only processes one operation at a time to prevent unsafe concurrent access. + */ +export class FileKvStore { + directory; + constructor(path) { + this.directory = path; + } + async get(key) { + try { + const buffer = await fs.readFile(this.resolve(key), 'utf8'); + return JSON.parse(buffer); + } + catch { + return undefined; + } + } + async set(key, value) { + await fs.writeFile(this.resolve(key), JSON.stringify(value)); + } + async delete(key) { + await fs.rm(this.resolve(key)); + } + async list() { + const files = await fs.readdir(this.directory); + const sorted = files.sort((a, b) => a.localeCompare(b)); + const name = (file) => path.basename(file, '.json'); + // To only return tus file IDs we check if the file has a corresponding JSON info file + return sorted.filter((file, idx) => idx < sorted.length - 1 && name(file) === name(sorted[idx + 1])); + } + resolve(key) { + return path.resolve(this.directory, `${key}.json`); + } +} +//# sourceMappingURL=FileKvStore.js.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/FileKvStore.js.map b/packages/utils/dist/kvstores/FileKvStore.js.map new file mode 100644 index 00000000..be3a085d --- /dev/null +++ b/packages/utils/dist/kvstores/FileKvStore.js.map @@ -0,0 +1 @@ +{"version":3,"file":"FileKvStore.js","sourceRoot":"","sources":["../../src/kvstores/FileKvStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,IAAI,MAAM,WAAW,CAAA;AAK5B;;;GAGG;AACH,MAAM,OAAO,WAAW;IACtB,SAAS,CAAQ;IAEjB,YAAY,IAAY;QACtB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAA;YAC3D,OAAO,IAAI,CAAC,KAAK,CAAC,MAAgB,CAAC,CAAA;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAQ;QAC7B,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;IAC9D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAA;IAChC,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;QACvD,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAC3D,sFAAsF;QACtF,OAAO,MAAM,CAAC,MAAM,CAClB,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAC/E,CAAA;IACH,CAAC;IAEO,OAAO,CAAC,GAAW;QACzB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,CAAA;IACpD,CAAC;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/IoRedisKvStore.d.ts b/packages/utils/dist/kvstores/IoRedisKvStore.d.ts new file mode 100644 index 00000000..ade3003a --- /dev/null +++ b/packages/utils/dist/kvstores/IoRedisKvStore.d.ts @@ -0,0 +1,16 @@ +import type { Redis as IoRedis } from 'ioredis'; +import type { KvStore } from './Types.js'; +import type { Upload } from '../models/index.js'; +export declare class IoRedisKvStore implements KvStore { + private redis; + private prefix; + constructor(redis: IoRedis, prefix?: string); + private prefixed; + get(key: string): Promise; + set(key: string, value: T): Promise; + delete(key: string): Promise; + list(): Promise>; + private serializeValue; + private deserializeValue; +} +//# sourceMappingURL=IoRedisKvStore.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/IoRedisKvStore.d.ts.map b/packages/utils/dist/kvstores/IoRedisKvStore.d.ts.map new file mode 100644 index 00000000..ef9eca5c --- /dev/null +++ b/packages/utils/dist/kvstores/IoRedisKvStore.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"IoRedisKvStore.d.ts","sourceRoot":"","sources":["../../src/kvstores/IoRedisKvStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,KAAK,IAAI,OAAO,EAAC,MAAM,SAAS,CAAA;AAC7C,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAA;AAE9C,qBAAa,cAAc,CAAC,CAAC,GAAG,MAAM,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;IAEzD,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,MAAM;gBADN,KAAK,EAAE,OAAO,EACd,MAAM,SAAK;IAMrB,OAAO,CAAC,QAAQ;IAIV,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAIxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAiBpC,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;CAGzB"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/IoRedisKvStore.js b/packages/utils/dist/kvstores/IoRedisKvStore.js new file mode 100644 index 00000000..0c0bb6dd --- /dev/null +++ b/packages/utils/dist/kvstores/IoRedisKvStore.js @@ -0,0 +1,40 @@ +export class IoRedisKvStore { + redis; + prefix; + constructor(redis, prefix = '') { + this.redis = redis; + this.prefix = prefix; + this.redis = redis; + this.prefix = prefix; + } + prefixed(key) { + return `${this.prefix}${key}`; + } + async get(key) { + return this.deserializeValue(await this.redis.get(this.prefixed(key))); + } + async set(key, value) { + await this.redis.set(this.prefixed(key), this.serializeValue(value)); + } + async delete(key) { + await this.redis.del(this.prefixed(key)); + } + async list() { + const keys = new Set(); + let cursor = '0'; + do { + const [next, batch] = await this.redis.scan(cursor, 'MATCH', this.prefixed('*'), 'COUNT', '20'); + cursor = next; + for (const key of batch) + keys.add(key); + } while (cursor !== '0'); + return Array.from(keys); + } + serializeValue(value) { + return JSON.stringify(value); + } + deserializeValue(buffer) { + return buffer ? JSON.parse(buffer) : undefined; + } +} +//# sourceMappingURL=IoRedisKvStore.js.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/IoRedisKvStore.js.map b/packages/utils/dist/kvstores/IoRedisKvStore.js.map new file mode 100644 index 00000000..270d1589 --- /dev/null +++ b/packages/utils/dist/kvstores/IoRedisKvStore.js.map @@ -0,0 +1 @@ +{"version":3,"file":"IoRedisKvStore.js","sourceRoot":"","sources":["../../src/kvstores/IoRedisKvStore.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,cAAc;IAEf;IACA;IAFV,YACU,KAAc,EACd,SAAS,EAAE;QADX,UAAK,GAAL,KAAK,CAAS;QACd,WAAM,GAAN,MAAM,CAAK;QAEnB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAEO,QAAQ,CAAC,GAAW;QAC1B,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAA;IAC/B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IACxE,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAQ;QAC7B,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IACtE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;IAC1C,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;QAC9B,IAAI,MAAM,GAAG,GAAG,CAAA;QAChB,GAAG,CAAC;YACF,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CACzC,MAAM,EACN,OAAO,EACP,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAClB,OAAO,EACP,IAAI,CACL,CAAA;YACD,MAAM,GAAG,IAAI,CAAA;YACb,KAAK,MAAM,GAAG,IAAI,KAAK;gBAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACxC,CAAC,QAAQ,MAAM,KAAK,GAAG,EAAC;QACxB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAEO,cAAc,CAAC,KAAQ;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAEO,gBAAgB,CAAC,MAAqB;QAC5C,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAChD,CAAC;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/MemoryKvStore.d.ts b/packages/utils/dist/kvstores/MemoryKvStore.d.ts new file mode 100644 index 00000000..6ffc2ce2 --- /dev/null +++ b/packages/utils/dist/kvstores/MemoryKvStore.d.ts @@ -0,0 +1,14 @@ +import type { Upload } from '../models/index.js'; +import type { KvStore } from './Types.js'; +/** + * Memory based configstore. + * Used mostly for unit tests. + */ +export declare class MemoryKvStore implements KvStore { + data: Map; + get(key: string): Promise; + set(key: string, value: T): Promise; + delete(key: string): Promise; + list(): Promise>; +} +//# sourceMappingURL=MemoryKvStore.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/MemoryKvStore.d.ts.map b/packages/utils/dist/kvstores/MemoryKvStore.d.ts.map new file mode 100644 index 00000000..cbd4e809 --- /dev/null +++ b/packages/utils/dist/kvstores/MemoryKvStore.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"MemoryKvStore.d.ts","sourceRoot":"","sources":["../../src/kvstores/MemoryKvStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAA;AAC9C,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA;AAEvC;;;GAGG;AACH,qBAAa,aAAa,CAAC,CAAC,GAAG,MAAM,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;IAC1D,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAY;IAE1B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAIxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;CAGrC"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/MemoryKvStore.js b/packages/utils/dist/kvstores/MemoryKvStore.js new file mode 100644 index 00000000..b54d23a3 --- /dev/null +++ b/packages/utils/dist/kvstores/MemoryKvStore.js @@ -0,0 +1,20 @@ +/** + * Memory based configstore. + * Used mostly for unit tests. + */ +export class MemoryKvStore { + data = new Map(); + async get(key) { + return this.data.get(key); + } + async set(key, value) { + this.data.set(key, value); + } + async delete(key) { + this.data.delete(key); + } + async list() { + return [...this.data.keys()]; + } +} +//# sourceMappingURL=MemoryKvStore.js.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/MemoryKvStore.js.map b/packages/utils/dist/kvstores/MemoryKvStore.js.map new file mode 100644 index 00000000..b860823a --- /dev/null +++ b/packages/utils/dist/kvstores/MemoryKvStore.js.map @@ -0,0 +1 @@ +{"version":3,"file":"MemoryKvStore.js","sourceRoot":"","sources":["../../src/kvstores/MemoryKvStore.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,OAAO,aAAa;IACxB,IAAI,GAAmB,IAAI,GAAG,EAAE,CAAA;IAEhC,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC3B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAQ;QAC7B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAC3B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IAC9B,CAAC;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/RedisKvStore.d.ts b/packages/utils/dist/kvstores/RedisKvStore.d.ts new file mode 100644 index 00000000..206640bb --- /dev/null +++ b/packages/utils/dist/kvstores/RedisKvStore.d.ts @@ -0,0 +1,20 @@ +import type { RedisClientType } from '@redis/client'; +import type { KvStore } from './Types.js'; +import type { Upload } from '../models/index.js'; +/** + * Redis based configstore. + * + * @author Mitja Puzigaća + */ +export declare class RedisKvStore implements KvStore { + private redis; + private prefix; + constructor(redis: RedisClientType, prefix?: string); + get(key: string): Promise; + set(key: string, value: T): Promise; + delete(key: string): Promise; + list(): Promise>; + private serializeValue; + private deserializeValue; +} +//# sourceMappingURL=RedisKvStore.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/RedisKvStore.d.ts.map b/packages/utils/dist/kvstores/RedisKvStore.d.ts.map new file mode 100644 index 00000000..3612894c --- /dev/null +++ b/packages/utils/dist/kvstores/RedisKvStore.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"RedisKvStore.d.ts","sourceRoot":"","sources":["../../src/kvstores/RedisKvStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,eAAe,CAAA;AAClD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAA;AAE9C;;;;GAIG;AACH,qBAAa,YAAY,CAAC,CAAC,GAAG,MAAM,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;IAEvD,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,MAAM;gBADN,KAAK,EAAE,eAAe,EACtB,MAAM,SAAK;IAMf,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAIxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAWpC,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;CAGzB"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/RedisKvStore.js b/packages/utils/dist/kvstores/RedisKvStore.js new file mode 100644 index 00000000..60736ccc --- /dev/null +++ b/packages/utils/dist/kvstores/RedisKvStore.js @@ -0,0 +1,42 @@ +/** + * Redis based configstore. + * + * @author Mitja Puzigaća + */ +export class RedisKvStore { + redis; + prefix; + constructor(redis, prefix = '') { + this.redis = redis; + this.prefix = prefix; + this.redis = redis; + this.prefix = prefix; + } + async get(key) { + return this.deserializeValue(await this.redis.get(this.prefix + key)); + } + async set(key, value) { + await this.redis.set(this.prefix + key, this.serializeValue(value)); + } + async delete(key) { + await this.redis.del(this.prefix + key); + } + async list() { + const keys = new Set(); + let cursor = 0; + do { + const result = await this.redis.scan(cursor, { MATCH: `${this.prefix}*`, COUNT: 20 }); + cursor = result.cursor; + for (const key of result.keys) + keys.add(key); + } while (cursor !== 0); + return Array.from(keys); + } + serializeValue(value) { + return JSON.stringify(value); + } + deserializeValue(buffer) { + return buffer ? JSON.parse(buffer) : undefined; + } +} +//# sourceMappingURL=RedisKvStore.js.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/RedisKvStore.js.map b/packages/utils/dist/kvstores/RedisKvStore.js.map new file mode 100644 index 00000000..1c00a519 --- /dev/null +++ b/packages/utils/dist/kvstores/RedisKvStore.js.map @@ -0,0 +1 @@ +{"version":3,"file":"RedisKvStore.js","sourceRoot":"","sources":["../../src/kvstores/RedisKvStore.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,OAAO,YAAY;IAEb;IACA;IAFV,YACU,KAAsB,EACtB,SAAS,EAAE;QADX,UAAK,GAAL,KAAK,CAAiB;QACtB,WAAM,GAAN,MAAM,CAAK;QAEnB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAA;IACvE,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAQ;QAC7B,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IACrE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAA;IACzC,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;QAC9B,IAAI,MAAM,GAAG,CAAC,CAAA;QACd,GAAG,CAAC;YACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAC,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,KAAK,EAAE,EAAE,EAAC,CAAC,CAAA;YACnF,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;YACtB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI;gBAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAC9C,CAAC,QAAQ,MAAM,KAAK,CAAC,EAAC;QACtB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAEO,cAAc,CAAC,KAAQ;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAEO,gBAAgB,CAAC,MAAqB;QAC5C,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAChD,CAAC;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/Types.d.ts b/packages/utils/dist/kvstores/Types.d.ts new file mode 100644 index 00000000..0bf84dc5 --- /dev/null +++ b/packages/utils/dist/kvstores/Types.d.ts @@ -0,0 +1,8 @@ +import type { Upload } from '../models/index.js'; +export interface KvStore { + get(key: string): Promise; + set(key: string, value: T): Promise; + delete(key: string): Promise; + list?(): Promise>; +} +//# sourceMappingURL=Types.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/Types.d.ts.map b/packages/utils/dist/kvstores/Types.d.ts.map new file mode 100644 index 00000000..f2a38457 --- /dev/null +++ b/packages/utils/dist/kvstores/Types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Types.d.ts","sourceRoot":"","sources":["../../src/kvstores/Types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAA;AAE9C,MAAM,WAAW,OAAO,CAAC,CAAC,GAAG,MAAM;IACjC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;IACxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAElC,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;CAChC"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/Types.js b/packages/utils/dist/kvstores/Types.js new file mode 100644 index 00000000..40e8ff7b --- /dev/null +++ b/packages/utils/dist/kvstores/Types.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=Types.js.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/Types.js.map b/packages/utils/dist/kvstores/Types.js.map new file mode 100644 index 00000000..435718d1 --- /dev/null +++ b/packages/utils/dist/kvstores/Types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Types.js","sourceRoot":"","sources":["../../src/kvstores/Types.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/index.d.ts b/packages/utils/dist/kvstores/index.d.ts new file mode 100644 index 00000000..68d089a0 --- /dev/null +++ b/packages/utils/dist/kvstores/index.d.ts @@ -0,0 +1,6 @@ +export { FileKvStore } from './FileKvStore.js'; +export { MemoryKvStore } from './MemoryKvStore.js'; +export { RedisKvStore } from './RedisKvStore.js'; +export { IoRedisKvStore } from './IoRedisKvStore.js'; +export { KvStore } from './Types.js'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/index.d.ts.map b/packages/utils/dist/kvstores/index.d.ts.map new file mode 100644 index 00000000..023b811b --- /dev/null +++ b/packages/utils/dist/kvstores/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/kvstores/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/index.js b/packages/utils/dist/kvstores/index.js new file mode 100644 index 00000000..18f87975 --- /dev/null +++ b/packages/utils/dist/kvstores/index.js @@ -0,0 +1,5 @@ +export { FileKvStore } from './FileKvStore.js'; +export { MemoryKvStore } from './MemoryKvStore.js'; +export { RedisKvStore } from './RedisKvStore.js'; +export { IoRedisKvStore } from './IoRedisKvStore.js'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/index.js.map b/packages/utils/dist/kvstores/index.js.map new file mode 100644 index 00000000..39d9e3c0 --- /dev/null +++ b/packages/utils/dist/kvstores/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/kvstores/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/models/Context.d.ts b/packages/utils/dist/models/Context.d.ts new file mode 100644 index 00000000..b3175a16 --- /dev/null +++ b/packages/utils/dist/models/Context.d.ts @@ -0,0 +1,26 @@ +/** + * The CancellationContext interface provides mechanisms to manage the termination of a request. + * It is designed to handle two types of request terminations: immediate abortion and graceful cancellation. + * + * Properties: + * - signal: An instance of AbortSignal. It allows external entities to listen for cancellation requests, + * making it possible to react accordingly. + * + * Methods: + * - abort(): This function should be called to immediately terminate the request. It is intended for scenarios + * where the request cannot continue and needs to be stopped as soon as possible, such as due to upload errors + * or invalid conditions. Implementers should ensure that invoking this method leads to the swift cessation of all + * request-related operations to save resources. + * + * - cancel(): This function is used for more controlled termination of the request. It signals that the request should + * be concluded, but allows for a short period of time to finalize operations gracefully. This could involve + * completing current transactions or cleaning up resources. The exact behavior and the time allowed for cancellation + * completion are determined by the implementation, but the goal is to try to end the request without abrupt interruption, + * ensuring orderly shutdown of ongoing processes. + */ +export interface CancellationContext { + signal: AbortSignal; + abort: () => void; + cancel: () => void; +} +//# sourceMappingURL=Context.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/Context.d.ts.map b/packages/utils/dist/models/Context.d.ts.map new file mode 100644 index 00000000..36fbf799 --- /dev/null +++ b/packages/utils/dist/models/Context.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Context.d.ts","sourceRoot":"","sources":["../../src/models/Context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB"} \ No newline at end of file diff --git a/packages/utils/dist/models/Context.js b/packages/utils/dist/models/Context.js new file mode 100644 index 00000000..7f4b1d55 --- /dev/null +++ b/packages/utils/dist/models/Context.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=Context.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/Context.js.map b/packages/utils/dist/models/Context.js.map new file mode 100644 index 00000000..0526461c --- /dev/null +++ b/packages/utils/dist/models/Context.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Context.js","sourceRoot":"","sources":["../../src/models/Context.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/utils/dist/models/DataStore.d.ts b/packages/utils/dist/models/DataStore.d.ts new file mode 100644 index 00000000..c979c833 --- /dev/null +++ b/packages/utils/dist/models/DataStore.d.ts @@ -0,0 +1,43 @@ +import EventEmitter from 'node:events'; +import stream from 'node:stream'; +import { Upload } from './Upload.js'; +export declare class DataStore extends EventEmitter { + extensions: string[]; + hasExtension(extension: string): boolean; + /** + * Called in POST requests. This method just creates a + * file, implementing the creation extension. + * + * http://tus.io/protocols/resumable-upload.html#creation + */ + create(file: Upload): Promise; + /** + * Called in DELETE requests. This method just deletes the file from the store. + * http://tus.io/protocols/resumable-upload.html#termination + */ + remove(id: string): Promise; + /** + * Called in PATCH requests. This method should write data + * to the DataStore file, and possibly implement the + * concatenation extension. + * + * http://tus.io/protocols/resumable-upload.html#concatenation + */ + write(stream: stream.Readable, id: string, offset: number): Promise; + /** + * Called in HEAD requests. This method should return the bytes + * writen to the DataStore, for the client to know where to resume + * the upload. + */ + getUpload(id: string): Promise; + /** + * Called in PATCH requests when upload length is known after being defered. + */ + declareUploadLength(id: string, upload_length: number): Promise; + /** + * Returns number of expired uploads that were deleted. + */ + deleteExpired(): Promise; + getExpiration(): number; +} +//# sourceMappingURL=DataStore.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/DataStore.d.ts.map b/packages/utils/dist/models/DataStore.d.ts.map new file mode 100644 index 00000000..a5972591 --- /dev/null +++ b/packages/utils/dist/models/DataStore.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"DataStore.d.ts","sourceRoot":"","sources":["../../src/models/DataStore.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAA;AACtC,OAAO,MAAM,MAAM,aAAa,CAAA;AAEhC,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAElC,qBAAa,SAAU,SAAQ,YAAY;IACzC,UAAU,EAAE,MAAM,EAAE,CAAK;IAEzB,YAAY,CAAC,SAAS,EAAE,MAAM;IAI9B;;;;;OAKG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM;IAIzB;;;OAGG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM;IAEvB;;;;;;OAMG;IACG,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAI/D;;;;OAIG;IACG,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAS5C;;OAEG;IACG,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM;IAE3D;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAItC,aAAa,IAAI,MAAM;CAGxB"} \ No newline at end of file diff --git a/packages/utils/dist/models/DataStore.js b/packages/utils/dist/models/DataStore.js new file mode 100644 index 00000000..4d1088c0 --- /dev/null +++ b/packages/utils/dist/models/DataStore.js @@ -0,0 +1,59 @@ +import EventEmitter from 'node:events'; +import { Upload } from './Upload.js'; +export class DataStore extends EventEmitter { + extensions = []; + hasExtension(extension) { + return this.extensions?.includes(extension); + } + /** + * Called in POST requests. This method just creates a + * file, implementing the creation extension. + * + * http://tus.io/protocols/resumable-upload.html#creation + */ + async create(file) { + return file; + } + /** + * Called in DELETE requests. This method just deletes the file from the store. + * http://tus.io/protocols/resumable-upload.html#termination + */ + async remove(id) { } + /** + * Called in PATCH requests. This method should write data + * to the DataStore file, and possibly implement the + * concatenation extension. + * + * http://tus.io/protocols/resumable-upload.html#concatenation + */ + async write(stream, id, offset) { + return 0; + } + /** + * Called in HEAD requests. This method should return the bytes + * writen to the DataStore, for the client to know where to resume + * the upload. + */ + async getUpload(id) { + return new Upload({ + id, + size: 0, + offset: 0, + storage: { type: 'datastore', path: '' }, + }); + } + /** + * Called in PATCH requests when upload length is known after being defered. + */ + async declareUploadLength(id, upload_length) { } + /** + * Returns number of expired uploads that were deleted. + */ + async deleteExpired() { + return 0; + } + getExpiration() { + return 0; + } +} +//# sourceMappingURL=DataStore.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/DataStore.js.map b/packages/utils/dist/models/DataStore.js.map new file mode 100644 index 00000000..682d5462 --- /dev/null +++ b/packages/utils/dist/models/DataStore.js.map @@ -0,0 +1 @@ +{"version":3,"file":"DataStore.js","sourceRoot":"","sources":["../../src/models/DataStore.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAA;AAGtC,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAElC,MAAM,OAAO,SAAU,SAAQ,YAAY;IACzC,UAAU,GAAa,EAAE,CAAA;IAEzB,YAAY,CAAC,SAAiB;QAC5B,OAAO,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAA;IAC7C,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,EAAU,IAAG,CAAC;IAE3B;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,CAAC,MAAuB,EAAE,EAAU,EAAE,MAAc;QAC7D,OAAO,CAAC,CAAA;IACV,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,SAAS,CAAC,EAAU;QACxB,OAAO,IAAI,MAAM,CAAC;YAChB,EAAE;YACF,IAAI,EAAE,CAAC;YACP,MAAM,EAAE,CAAC;YACT,OAAO,EAAE,EAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,EAAC;SACvC,CAAC,CAAA;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,mBAAmB,CAAC,EAAU,EAAE,aAAqB,IAAG,CAAC;IAE/D;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,OAAO,CAAC,CAAA;IACV,CAAC;IAED,aAAa;QACX,OAAO,CAAC,CAAA;IACV,CAAC;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/models/Locker.d.ts b/packages/utils/dist/models/Locker.d.ts new file mode 100644 index 00000000..560d98dc --- /dev/null +++ b/packages/utils/dist/models/Locker.d.ts @@ -0,0 +1,30 @@ +export type RequestRelease = () => Promise | void; +/** + * The Locker interface creates a Lock instance for a given resource identifier. + */ +export interface Locker { + newLock(id: string): Lock; +} +/** + * The Lock interface defines methods for implementing a locking mechanism. + * It is primarily used to ensure exclusive access to resources, such as uploads and their metadata. + * + * The interface adheres to TUS protocol recommendations, emphasizing the need to prevent prolonged lock retention. + * This approach helps manage resources efficiently and avoids issues with half-open TCP connections. + * + * Methods: + * - lock(id, cancelReq): Acquires a lock on a resource identified by 'id'. If the lock is already held by another request, + * the 'cancelReq' callback is provided to signal the current lock holder to release the lock. + * The 'cancelReq' callback should be invoked when there's an attempt by another request to acquire a previously locked resource. + * This mechanism ensures that locks are held only as long as necessary and are promptly released for other requests. + * + * - unlock(id): Releases the lock held on the resource identified by 'id'. This should be called by the lock holder + * after completing their operation or upon receiving a signal through the 'cancelReq' callback from a subsequent request + * attempting to acquire the lock. + * + */ +export interface Lock { + lock(signal: AbortSignal, cancelReq: RequestRelease): Promise; + unlock(): Promise; +} +//# sourceMappingURL=Locker.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/Locker.d.ts.map b/packages/utils/dist/models/Locker.d.ts.map new file mode 100644 index 00000000..bd0a14ea --- /dev/null +++ b/packages/utils/dist/models/Locker.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Locker.d.ts","sourceRoot":"","sources":["../../src/models/Locker.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;AAEvD;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,IAAI;IACnB,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACxB"} \ No newline at end of file diff --git a/packages/utils/dist/models/Locker.js b/packages/utils/dist/models/Locker.js new file mode 100644 index 00000000..93a9c26a --- /dev/null +++ b/packages/utils/dist/models/Locker.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=Locker.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/Locker.js.map b/packages/utils/dist/models/Locker.js.map new file mode 100644 index 00000000..8a10f8f9 --- /dev/null +++ b/packages/utils/dist/models/Locker.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Locker.js","sourceRoot":"","sources":["../../src/models/Locker.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/utils/dist/models/Metadata.d.ts b/packages/utils/dist/models/Metadata.d.ts new file mode 100644 index 00000000..c408f8bb --- /dev/null +++ b/packages/utils/dist/models/Metadata.d.ts @@ -0,0 +1,6 @@ +import type { Upload } from './Upload.js'; +export declare function validateKey(key: string): boolean; +export declare function validateValue(value: string): boolean; +export declare function parse(str?: string): Record; +export declare function stringify(metadata: NonNullable): string; +//# sourceMappingURL=Metadata.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/Metadata.d.ts.map b/packages/utils/dist/models/Metadata.d.ts.map new file mode 100644 index 00000000..ad519e91 --- /dev/null +++ b/packages/utils/dist/models/Metadata.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Metadata.d.ts","sourceRoot":"","sources":["../../src/models/Metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAMvC,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,WAiBtC;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,WAM1C;AAED,wBAAgB,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,iCAuBjC;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,MAAM,CAW3E"} \ No newline at end of file diff --git a/packages/utils/dist/models/Metadata.js b/packages/utils/dist/models/Metadata.js new file mode 100644 index 00000000..e0aadfb0 --- /dev/null +++ b/packages/utils/dist/models/Metadata.js @@ -0,0 +1,55 @@ +const ASCII_SPACE = ' '.codePointAt(0); +const ASCII_COMMA = ','.codePointAt(0); +const BASE64_REGEX = /^[\d+/A-Za-z]*={0,2}$/; +export function validateKey(key) { + if (key.length === 0) { + return false; + } + for (let i = 0; i < key.length; ++i) { + const charCodePoint = key.codePointAt(i); + if (charCodePoint > 127 || + charCodePoint === ASCII_SPACE || + charCodePoint === ASCII_COMMA) { + return false; + } + } + return true; +} +export function validateValue(value) { + if (value.length % 4 !== 0) { + return false; + } + return BASE64_REGEX.test(value); +} +export function parse(str) { + const meta = {}; + if (!str || str.trim().length === 0) { + throw new Error('Metadata string is not valid'); + } + for (const pair of str.split(',')) { + const tokens = pair.split(' '); + const [key, value] = tokens; + if (((tokens.length === 1 && validateKey(key)) || + (tokens.length === 2 && validateKey(key) && validateValue(value))) && + !(key in meta)) { + const decodedValue = value ? Buffer.from(value, 'base64').toString('utf8') : null; + meta[key] = decodedValue; + } + else { + throw new Error('Metadata string is not valid'); + } + } + return meta; +} +export function stringify(metadata) { + return Object.entries(metadata) + .map(([key, value]) => { + if (value === null) { + return key; + } + const encodedValue = Buffer.from(value, 'utf8').toString('base64'); + return `${key} ${encodedValue}`; + }) + .join(','); +} +//# sourceMappingURL=Metadata.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/Metadata.js.map b/packages/utils/dist/models/Metadata.js.map new file mode 100644 index 00000000..26e57979 --- /dev/null +++ b/packages/utils/dist/models/Metadata.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Metadata.js","sourceRoot":"","sources":["../../src/models/Metadata.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AACtC,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AACtC,MAAM,YAAY,GAAG,uBAAuB,CAAA;AAE5C,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;QACpC,MAAM,aAAa,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAW,CAAA;QAClD,IACE,aAAa,GAAG,GAAG;YACnB,aAAa,KAAK,WAAW;YAC7B,aAAa,KAAK,WAAW,EAC7B,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACjC,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAY;IAChC,MAAM,IAAI,GAAkC,EAAE,CAAA;IAE9C,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;IACjD,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAC9B,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,MAAM,CAAA;QAC3B,IACE,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;YACxC,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;YACpE,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,EACd,CAAC;YACD,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;YACjF,IAAI,CAAC,GAAG,CAAC,GAAG,YAAY,CAAA;QAC1B,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;QACjD,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAyC;IACjE,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;SAC5B,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACpB,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,GAAG,CAAA;QACZ,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QAClE,OAAO,GAAG,GAAG,IAAI,YAAY,EAAE,CAAA;IACjC,CAAC,CAAC;SACD,IAAI,CAAC,GAAG,CAAC,CAAA;AACd,CAAC"} \ No newline at end of file diff --git a/packages/utils/dist/models/StreamLimiter.d.ts b/packages/utils/dist/models/StreamLimiter.d.ts new file mode 100644 index 00000000..968f9091 --- /dev/null +++ b/packages/utils/dist/models/StreamLimiter.d.ts @@ -0,0 +1,13 @@ +import { Transform, type TransformCallback } from 'node:stream'; +export declare class MaxFileExceededError extends Error { + status_code: number; + body: string; + constructor(); +} +export declare class StreamLimiter extends Transform { + private maxSize; + private currentSize; + constructor(maxSize: number); + _transform(chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback): void; +} +//# sourceMappingURL=StreamLimiter.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/StreamLimiter.d.ts.map b/packages/utils/dist/models/StreamLimiter.d.ts.map new file mode 100644 index 00000000..706ec40f --- /dev/null +++ b/packages/utils/dist/models/StreamLimiter.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"StreamLimiter.d.ts","sourceRoot":"","sources":["../../src/models/StreamLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,KAAK,iBAAiB,EAAC,MAAM,aAAa,CAAA;AAI7D,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;;CAQb;AAED,qBAAa,aAAc,SAAQ,SAAS;IAC1C,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,WAAW,CAAI;gBAEX,OAAO,EAAE,MAAM;IAK3B,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI;CAQvF"} \ No newline at end of file diff --git a/packages/utils/dist/models/StreamLimiter.js b/packages/utils/dist/models/StreamLimiter.js new file mode 100644 index 00000000..e2575f9d --- /dev/null +++ b/packages/utils/dist/models/StreamLimiter.js @@ -0,0 +1,31 @@ +import { Transform } from 'node:stream'; +import { ERRORS } from '../constants.js'; +// TODO: create HttpError and use it everywhere instead of throwing objects +export class MaxFileExceededError extends Error { + status_code; + body; + constructor() { + super(ERRORS.ERR_MAX_SIZE_EXCEEDED.body); + this.status_code = ERRORS.ERR_MAX_SIZE_EXCEEDED.status_code; + this.body = ERRORS.ERR_MAX_SIZE_EXCEEDED.body; + Object.setPrototypeOf(this, MaxFileExceededError.prototype); + } +} +export class StreamLimiter extends Transform { + maxSize; + currentSize = 0; + constructor(maxSize) { + super(); + this.maxSize = maxSize; + } + _transform(chunk, encoding, callback) { + this.currentSize += chunk.length; + if (this.currentSize > this.maxSize) { + callback(new MaxFileExceededError()); + } + else { + callback(null, chunk); + } + } +} +//# sourceMappingURL=StreamLimiter.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/StreamLimiter.js.map b/packages/utils/dist/models/StreamLimiter.js.map new file mode 100644 index 00000000..cee6985d --- /dev/null +++ b/packages/utils/dist/models/StreamLimiter.js.map @@ -0,0 +1 @@ +{"version":3,"file":"StreamLimiter.js","sourceRoot":"","sources":["../../src/models/StreamLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAyB,MAAM,aAAa,CAAA;AAC7D,OAAO,EAAC,MAAM,EAAC,MAAM,iBAAiB,CAAA;AAEtC,2EAA2E;AAC3E,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,WAAW,CAAQ;IACnB,IAAI,CAAQ;IAEZ;QACE,KAAK,CAAC,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAA;QACxC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,qBAAqB,CAAC,WAAW,CAAA;QAC3D,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAA;QAC7C,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAA;IAC7D,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,SAAS;IAClC,OAAO,CAAQ;IACf,WAAW,GAAG,CAAC,CAAA;IAEvB,YAAY,OAAe;QACzB,KAAK,EAAE,CAAA;QACP,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,UAAU,CAAC,KAAa,EAAE,QAAwB,EAAE,QAA2B;QAC7E,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,MAAM,CAAA;QAChC,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YACpC,QAAQ,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAA;QACtC,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QACvB,CAAC;IACH,CAAC;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/models/StreamSplitter.d.ts b/packages/utils/dist/models/StreamSplitter.d.ts new file mode 100644 index 00000000..b480e790 --- /dev/null +++ b/packages/utils/dist/models/StreamSplitter.d.ts @@ -0,0 +1,26 @@ +import fs from 'node:fs/promises'; +import stream from 'node:stream'; +type Options = { + chunkSize: number; + directory: string; +}; +type Callback = (error: Error | null) => void; +export declare class StreamSplitter extends stream.Writable { + directory: Options['directory']; + currentChunkPath: string | null; + currentChunkSize: number; + fileHandle: fs.FileHandle | null; + filenameTemplate: string; + chunkSize: Options['chunkSize']; + part: number; + constructor({ chunkSize, directory }: Options, options?: stream.WritableOptions); + _write(chunk: Buffer, _: BufferEncoding, callback: Callback): Promise; + _final(callback: Callback): Promise; + _writeChunk(chunk: Buffer): Promise; + _handleError(): Promise; + _finishChunk(): Promise; + emitEvent(name: string, payload: T): Promise; + _newChunk(): Promise; +} +export {}; +//# sourceMappingURL=StreamSplitter.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/StreamSplitter.d.ts.map b/packages/utils/dist/models/StreamSplitter.d.ts.map new file mode 100644 index 00000000..405a75af --- /dev/null +++ b/packages/utils/dist/models/StreamSplitter.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"StreamSplitter.d.ts","sourceRoot":"","sources":["../../src/models/StreamSplitter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAEjC,OAAO,MAAM,MAAM,aAAa,CAAA;AAMhC,KAAK,OAAO,GAAG;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAA;AAE7C,qBAAa,cAAe,SAAQ,MAAM,CAAC,QAAQ;IACjD,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC/B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,IAAI,CAAA;IAChC,gBAAgB,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC/B,IAAI,EAAE,MAAM,CAAA;gBAEA,EAAC,SAAS,EAAE,SAAS,EAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,eAAe;IAavE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ;IA+B3D,MAAM,CAAC,QAAQ,EAAE,QAAQ;IAczB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzC,YAAY;IAcZ,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB7B,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAOrC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAajC"} \ No newline at end of file diff --git a/packages/utils/dist/models/StreamSplitter.js b/packages/utils/dist/models/StreamSplitter.js new file mode 100644 index 00000000..76bd548c --- /dev/null +++ b/packages/utils/dist/models/StreamSplitter.js @@ -0,0 +1,114 @@ +/* global BufferEncoding */ +import crypto from 'node:crypto'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import stream from 'node:stream'; +function randomString(size) { + return crypto.randomBytes(size).toString('base64url').slice(0, size); +} +export class StreamSplitter extends stream.Writable { + directory; + currentChunkPath; + currentChunkSize; + fileHandle; + filenameTemplate; + chunkSize; + part; + constructor({ chunkSize, directory }, options) { + super(options); + this.chunkSize = chunkSize; + this.currentChunkPath = null; + this.currentChunkSize = 0; + this.fileHandle = null; + this.directory = directory; + this.filenameTemplate = randomString(10); + this.part = 0; + this.on('error', this._handleError.bind(this)); + } + async _write(chunk, _, callback) { + try { + // In order to start writing a chunk, we must first create + // a file system reference for it + if (this.fileHandle === null) { + await this._newChunk(); + } + let overflow = this.currentChunkSize + chunk.length - this.chunkSize; + // The current chunk will be more than our defined part size if we would + // write all of it to disk. + while (overflow > 0) { + // Only write to disk the up to our defined part size. + await this._writeChunk(chunk.subarray(0, chunk.length - overflow)); + await this._finishChunk(); + // We still have some overflow left, so we write it to a new chunk. + await this._newChunk(); + chunk = chunk.subarray(chunk.length - overflow, chunk.length); + overflow = this.currentChunkSize + chunk.length - this.chunkSize; + } + // The chunk is smaller than our defined part size so we can just write it to disk. + await this._writeChunk(chunk); + callback(null); + } + catch (error) { + callback(error); + } + } + async _final(callback) { + if (this.fileHandle === null) { + callback(null); + return; + } + try { + await this._finishChunk(); + callback(null); + } + catch (error) { + callback(error); + } + } + async _writeChunk(chunk) { + await fs.appendFile(this.fileHandle, chunk); + this.currentChunkSize += chunk.length; + } + async _handleError() { + await this.emitEvent('chunkError', this.currentChunkPath); + // If there was an error, we want to stop allowing to write on disk as we cannot advance further. + // At this point the chunk might be incomplete advancing further might cause data loss. + // some scenarios where this might happen is if the disk is full or if we abort the stream midway. + if (this.fileHandle === null) { + return; + } + await this.fileHandle.close(); + this.currentChunkPath = null; + this.fileHandle = null; + } + async _finishChunk() { + if (this.fileHandle === null) { + return; + } + await this.fileHandle.close(); + await this.emitEvent('chunkFinished', { + path: this.currentChunkPath, + size: this.currentChunkSize, + }); + this.currentChunkPath = null; + this.fileHandle = null; + this.currentChunkSize = 0; + this.part += 1; + } + async emitEvent(name, payload) { + const listeners = this.listeners(name); + for (const listener of listeners) { + await listener(payload); + } + } + async _newChunk() { + const currentChunkPath = path.join(this.directory, `${this.filenameTemplate}-${this.part}`); + await this.emitEvent('beforeChunkStarted', currentChunkPath); + this.currentChunkPath = currentChunkPath; + const fileHandle = await fs.open(this.currentChunkPath, 'w'); + await this.emitEvent('chunkStarted', this.currentChunkPath); + this.currentChunkSize = 0; + this.fileHandle = fileHandle; + } +} +//# sourceMappingURL=StreamSplitter.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/StreamSplitter.js.map b/packages/utils/dist/models/StreamSplitter.js.map new file mode 100644 index 00000000..d52cb112 --- /dev/null +++ b/packages/utils/dist/models/StreamSplitter.js.map @@ -0,0 +1 @@ +{"version":3,"file":"StreamSplitter.js","sourceRoot":"","sources":["../../src/models/StreamSplitter.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/utils/dist/models/Uid.d.ts b/packages/utils/dist/models/Uid.d.ts new file mode 100644 index 00000000..6e80bd97 --- /dev/null +++ b/packages/utils/dist/models/Uid.d.ts @@ -0,0 +1,4 @@ +export declare const Uid: { + rand(): string; +}; +//# sourceMappingURL=Uid.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/Uid.d.ts.map b/packages/utils/dist/models/Uid.d.ts.map new file mode 100644 index 00000000..88361885 --- /dev/null +++ b/packages/utils/dist/models/Uid.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Uid.d.ts","sourceRoot":"","sources":["../../src/models/Uid.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,GAAG;;CAIf,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/models/Uid.js b/packages/utils/dist/models/Uid.js new file mode 100644 index 00000000..1de5406b --- /dev/null +++ b/packages/utils/dist/models/Uid.js @@ -0,0 +1,7 @@ +import crypto from 'node:crypto'; +export const Uid = { + rand() { + return crypto.randomBytes(16).toString('hex'); + }, +}; +//# sourceMappingURL=Uid.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/Uid.js.map b/packages/utils/dist/models/Uid.js.map new file mode 100644 index 00000000..791c410d --- /dev/null +++ b/packages/utils/dist/models/Uid.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Uid.js","sourceRoot":"","sources":["../../src/models/Uid.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAEhC,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,IAAI;QACF,OAAO,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC/C,CAAC;CACF,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/models/Upload.d.ts b/packages/utils/dist/models/Upload.d.ts new file mode 100644 index 00000000..a1b4c210 --- /dev/null +++ b/packages/utils/dist/models/Upload.d.ts @@ -0,0 +1,24 @@ +type TUpload = { + id: string; + size?: number; + offset: number; + metadata?: Record; + storage?: { + type: string; + path: string; + bucket?: string; + }; + creation_date?: string; +}; +export declare class Upload { + id: TUpload['id']; + metadata: TUpload['metadata']; + size: TUpload['size']; + offset: TUpload['offset']; + creation_date: TUpload['creation_date']; + storage: TUpload['storage']; + constructor(upload: TUpload); + get sizeIsDeferred(): boolean; +} +export {}; +//# sourceMappingURL=Upload.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/Upload.d.ts.map b/packages/utils/dist/models/Upload.d.ts.map new file mode 100644 index 00000000..ed78ebd9 --- /dev/null +++ b/packages/utils/dist/models/Upload.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Upload.d.ts","sourceRoot":"","sources":["../../src/models/Upload.ts"],"names":[],"mappings":"AAAA,KAAK,OAAO,GAAG;IACb,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAA;IACxC,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,qBAAa,MAAM;IACjB,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;IAC7B,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACrB,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IACzB,aAAa,EAAE,OAAO,CAAC,eAAe,CAAC,CAAA;IACvC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;gBAEf,MAAM,EAAE,OAAO;IAc3B,IAAI,cAAc,IAAI,OAAO,CAE5B;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/models/Upload.js b/packages/utils/dist/models/Upload.js new file mode 100644 index 00000000..ceb92ca5 --- /dev/null +++ b/packages/utils/dist/models/Upload.js @@ -0,0 +1,23 @@ +export class Upload { + id; + metadata; + size; + offset; + creation_date; + storage; + constructor(upload) { + if (!upload.id) { + throw new Error('[File] constructor must be given an ID'); + } + this.id = upload.id; + this.size = upload.size; + this.offset = upload.offset; + this.metadata = upload.metadata; + this.storage = upload.storage; + this.creation_date = upload.creation_date ?? new Date().toISOString(); + } + get sizeIsDeferred() { + return this.size === undefined; + } +} +//# sourceMappingURL=Upload.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/Upload.js.map b/packages/utils/dist/models/Upload.js.map new file mode 100644 index 00000000..72b3f1f4 --- /dev/null +++ b/packages/utils/dist/models/Upload.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Upload.js","sourceRoot":"","sources":["../../src/models/Upload.ts"],"names":[],"mappings":"AAaA,MAAM,OAAO,MAAM;IACjB,EAAE,CAAe;IACjB,QAAQ,CAAqB;IAC7B,IAAI,CAAiB;IACrB,MAAM,CAAmB;IACzB,aAAa,CAA0B;IACvC,OAAO,CAAoB;IAE3B,YAAY,MAAe;QACzB,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QAC3D,CAAC;QAED,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAA;QACnB,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;QAC3B,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;QAC/B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;QAE7B,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IACvE,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,CAAA;IAChC,CAAC;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/models/index.d.ts b/packages/utils/dist/models/index.d.ts new file mode 100644 index 00000000..4d4ff440 --- /dev/null +++ b/packages/utils/dist/models/index.d.ts @@ -0,0 +1,9 @@ +export { DataStore } from './DataStore.js'; +export * as Metadata from './Metadata.js'; +export { StreamSplitter } from './StreamSplitter.js'; +export { StreamLimiter } from './StreamLimiter.js'; +export { Uid } from './Uid.js'; +export { Upload } from './Upload.js'; +export { Locker, Lock, RequestRelease } from './Locker.js'; +export { CancellationContext } from './Context.js'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/index.d.ts.map b/packages/utils/dist/models/index.d.ts.map new file mode 100644 index 00000000..e948033b --- /dev/null +++ b/packages/utils/dist/models/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAA;AACxC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAC,GAAG,EAAC,MAAM,UAAU,CAAA;AAC5B,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAClC,OAAO,EAAC,MAAM,EAAE,IAAI,EAAE,cAAc,EAAC,MAAM,aAAa,CAAA;AACxD,OAAO,EAAC,mBAAmB,EAAC,MAAM,cAAc,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/models/index.js b/packages/utils/dist/models/index.js new file mode 100644 index 00000000..02dac6a7 --- /dev/null +++ b/packages/utils/dist/models/index.js @@ -0,0 +1,7 @@ +export { DataStore } from './DataStore.js'; +export * as Metadata from './Metadata.js'; +export { StreamSplitter } from './StreamSplitter.js'; +export { StreamLimiter } from './StreamLimiter.js'; +export { Uid } from './Uid.js'; +export { Upload } from './Upload.js'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/index.js.map b/packages/utils/dist/models/index.js.map new file mode 100644 index 00000000..fed8cf01 --- /dev/null +++ b/packages/utils/dist/models/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAA;AACxC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAC,GAAG,EAAC,MAAM,UAAU,CAAA;AAC5B,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/test/Metadata.test.d.ts b/packages/utils/dist/test/Metadata.test.d.ts new file mode 100644 index 00000000..ca0a1d4a --- /dev/null +++ b/packages/utils/dist/test/Metadata.test.d.ts @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=Metadata.test.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/test/Metadata.test.d.ts.map b/packages/utils/dist/test/Metadata.test.d.ts.map new file mode 100644 index 00000000..3db6b19f --- /dev/null +++ b/packages/utils/dist/test/Metadata.test.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Metadata.test.d.ts","sourceRoot":"","sources":["../../src/test/Metadata.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/utils/dist/test/Metadata.test.js b/packages/utils/dist/test/Metadata.test.js new file mode 100644 index 00000000..0c061231 --- /dev/null +++ b/packages/utils/dist/test/Metadata.test.js @@ -0,0 +1,108 @@ +import { strict as assert } from 'node:assert'; +import { parse, stringify } from '../models/Metadata.js'; +describe('Metadata', () => { + it('parse valid metadata string', () => { + const str = 'file/name dGVzdC5tcDQ=,size OTYwMjQ0,type! dmlkZW8vbXA0,video,withWhitespace '; + const obj = { + 'file/name': 'test.mp4', + size: '960244', + 'type!': 'video/mp4', + video: null, + withWhitespace: null, + }; + const decoded = parse(str); + assert.deepStrictEqual(decoded, obj); + }); + it('check length of metadata string', () => { + const obj = { + filename: 'test.mp4', + size: '960244', + type: 'video/mp4', + video: null, + withWhitespace: null, + }; + const encoded = stringify(obj); + assert.strictEqual(encoded.split(',').length, Object.entries(obj).length); + }); + it('verify metadata stringification', () => { + assert.strictEqual(stringify({ filename: 'test.mp4' }), 'filename dGVzdC5tcDQ='); + assert.strictEqual(stringify({ size: '960244' }), 'size OTYwMjQ0'); + assert.strictEqual(stringify({ type: 'video/mp4' }), 'type dmlkZW8vbXA0'); + // Multiple valid options + assert.notStrictEqual(['video', 'video '].indexOf(stringify({ video: null })), -1); + assert.notStrictEqual(['withWhitespace', 'withWhitespace '].indexOf(stringify({ withWhitespace: null })), -1); + }); + it('verify metadata parsing', () => { + assert.deepStrictEqual(parse('filename dGVzdC5tcDQ='), { + filename: 'test.mp4', + }); + assert.deepStrictEqual(parse('size OTYwMjQ0'), { size: '960244' }); + assert.deepStrictEqual(parse('type dmlkZW8vbXA0'), { + type: 'video/mp4', + }); + assert.deepStrictEqual(parse('video'), { video: null }); + assert.deepStrictEqual(parse('video '), { video: null }); + assert.deepStrictEqual(parse('withWhitespace'), { + withWhitespace: null, + }); + assert.deepStrictEqual(parse('withWhitespace '), { + withWhitespace: null, + }); + }); + it('cyclic test', () => { + const obj = { + filename: 'world_domination_plan.pdf', + is_confidential: null, + }; + // Object -> string -> object + assert.deepStrictEqual(parse(stringify(obj)), obj); + }); + describe('verify invalid metadata string', () => { + it('duplicate keys', () => { + assert.throws(() => { + parse('filename dGVzdC5tcDQ=, filename cGFja2FnZS5qc29u'); + }); + assert.throws(() => { + parse('video ,video dHJ1ZQ=='); + }); + assert.throws(() => { + parse('size,size '); + }); + assert.throws(() => { + parse(''); + }); + assert.throws(() => { + parse('\t\n'); + }); + }); + it('invalid key', () => { + assert.throws(() => { + parse('🦁 ZW1vamk='); + }); + assert.throws(() => { + parse('€¢ß'); + }); + assert.throws(() => { + parse('test, te st '); + }); + assert.throws(() => { + parse('test,,test'); + }); + }); + it('invalid base64 value', () => { + assert.throws(() => { + parse('key ZW1vamk'); + }); // Value is not a multiple of 4 characters + assert.throws(() => { + parse('key invalid-base64=='); + }); + assert.throws(() => { + parse('key =ZW1vamk'); + }); // Padding can not be at the beginning + assert.throws(() => { + parse('key '); + }); // Only single whitespace is allowed + }); + }); +}); +//# sourceMappingURL=Metadata.test.js.map \ No newline at end of file diff --git a/packages/utils/dist/test/Metadata.test.js.map b/packages/utils/dist/test/Metadata.test.js.map new file mode 100644 index 00000000..f253fc7b --- /dev/null +++ b/packages/utils/dist/test/Metadata.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Metadata.test.js","sourceRoot":"","sources":["../../src/test/Metadata.test.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/utils/dist/test/StreamSplitter.test.d.ts b/packages/utils/dist/test/StreamSplitter.test.d.ts new file mode 100644 index 00000000..02f563f2 --- /dev/null +++ b/packages/utils/dist/test/StreamSplitter.test.d.ts @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=StreamSplitter.test.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/test/StreamSplitter.test.d.ts.map b/packages/utils/dist/test/StreamSplitter.test.d.ts.map new file mode 100644 index 00000000..833b2f3f --- /dev/null +++ b/packages/utils/dist/test/StreamSplitter.test.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"StreamSplitter.test.d.ts","sourceRoot":"","sources":["../../src/test/StreamSplitter.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/utils/dist/test/StreamSplitter.test.js b/packages/utils/dist/test/StreamSplitter.test.js new file mode 100644 index 00000000..0e52514b --- /dev/null +++ b/packages/utils/dist/test/StreamSplitter.test.js @@ -0,0 +1,47 @@ +import os from 'node:os'; +import fs from 'node:fs'; +import stream from 'node:stream/promises'; +import { strict as assert } from 'node:assert'; +import { StreamSplitter } from '../models/index.js'; +import { Readable } from 'node:stream'; +const fileSize = 20_971_520; +describe('StreamSplitter', () => { + it('should buffer chunks until optimal part size', async () => { + const readStream = fs.createReadStream('../../test/fixtures/test.pdf'); + const optimalChunkSize = 8 * 1024 * 1024; + const parts = [optimalChunkSize, optimalChunkSize, fileSize - optimalChunkSize * 2]; + let offset = 0; + let index = 0; + const splitterStream = new StreamSplitter({ + chunkSize: optimalChunkSize, + directory: os.tmpdir(), + }).on('chunkFinished', ({ size }) => { + offset += size; + assert.equal(parts[index], size); + index++; + }); + await stream.pipeline(readStream, splitterStream); + assert.equal(offset, fileSize); + }); + it('should split to multiple chunks when single buffer exceeds chunk size', async () => { + const optimalChunkSize = 1024; + const expectedChunks = 7; + const readStream = Readable.from([Buffer.alloc(expectedChunks * optimalChunkSize)]); + let chunksStarted = 0; + let chunksFinished = 0; + const splitterStream = new StreamSplitter({ + chunkSize: optimalChunkSize, + directory: os.tmpdir(), + }) + .on('chunkStarted', () => { + chunksStarted++; + }) + .on('chunkFinished', () => { + chunksFinished++; + }); + await stream.pipeline(readStream, splitterStream); + assert.equal(chunksStarted, expectedChunks); + assert.equal(chunksFinished, expectedChunks); + }); +}); +//# sourceMappingURL=StreamSplitter.test.js.map \ No newline at end of file diff --git a/packages/utils/dist/test/StreamSplitter.test.js.map b/packages/utils/dist/test/StreamSplitter.test.js.map new file mode 100644 index 00000000..de0b6d47 --- /dev/null +++ b/packages/utils/dist/test/StreamSplitter.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"StreamSplitter.test.js","sourceRoot":"","sources":["../../src/test/StreamSplitter.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,MAAM,MAAM,sBAAsB,CAAA;AACzC,OAAO,EAAC,MAAM,IAAI,MAAM,EAAC,MAAM,aAAa,CAAA;AAE5C,OAAO,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAA;AAEpC,MAAM,QAAQ,GAAG,UAAU,CAAA;AAE3B,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,UAAU,GAAG,EAAE,CAAC,gBAAgB,CAAC,8BAA8B,CAAC,CAAA;QACtE,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA;QACxC,MAAM,KAAK,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,QAAQ,GAAG,gBAAgB,GAAG,CAAC,CAAC,CAAA;QACnF,IAAI,MAAM,GAAG,CAAC,CAAA;QACd,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC;YACxC,SAAS,EAAE,gBAAgB;YAC3B,SAAS,EAAE,EAAE,CAAC,MAAM,EAAE;SACvB,CAAC,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,EAAC,IAAI,EAAC,EAAE,EAAE;YAChC,MAAM,IAAI,IAAI,CAAA;YACd,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAA;YAChC,KAAK,EAAE,CAAA;QACT,CAAC,CAAC,CAAA;QACF,MAAM,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;QACjD,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAChC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,gBAAgB,GAAG,IAAI,CAAA;QAC7B,MAAM,cAAc,GAAG,CAAC,CAAA;QAExB,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAA;QAEnF,IAAI,aAAa,GAAG,CAAC,CAAA;QACrB,IAAI,cAAc,GAAG,CAAC,CAAA;QACtB,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC;YACxC,SAAS,EAAE,gBAAgB;YAC3B,SAAS,EAAE,EAAE,CAAC,MAAM,EAAE;SACvB,CAAC;aACC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;YACvB,aAAa,EAAE,CAAA;QACjB,CAAC,CAAC;aACD,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACxB,cAAc,EAAE,CAAA;QAClB,CAAC,CAAC,CAAA;QAEJ,MAAM,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;QAEjD,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,cAAc,CAAC,CAAA;QAC3C,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,cAAc,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/test/Uid.test.d.ts b/packages/utils/dist/test/Uid.test.d.ts new file mode 100644 index 00000000..6d5eceac --- /dev/null +++ b/packages/utils/dist/test/Uid.test.d.ts @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=Uid.test.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/test/Uid.test.d.ts.map b/packages/utils/dist/test/Uid.test.d.ts.map new file mode 100644 index 00000000..9978e438 --- /dev/null +++ b/packages/utils/dist/test/Uid.test.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Uid.test.d.ts","sourceRoot":"","sources":["../../src/test/Uid.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/utils/dist/test/Uid.test.js b/packages/utils/dist/test/Uid.test.js new file mode 100644 index 00000000..f90ee5c7 --- /dev/null +++ b/packages/utils/dist/test/Uid.test.js @@ -0,0 +1,20 @@ +import { strict as assert } from 'node:assert'; +import { Uid } from '../models/index.js'; +describe('Uid', () => { + it('returns a 32 char string', (done) => { + const id = Uid.rand(); + assert.equal(typeof id, 'string'); + assert.equal(id.length, 32); + done(); + }); + it('returns a different string every time', (done) => { + const ids = {}; + for (let i = 0; i < 16; i++) { + const id = Uid.rand(); + assert(!ids[id], 'id was encountered multiple times'); + ids[id] = true; + } + done(); + }); +}); +//# sourceMappingURL=Uid.test.js.map \ No newline at end of file diff --git a/packages/utils/dist/test/Uid.test.js.map b/packages/utils/dist/test/Uid.test.js.map new file mode 100644 index 00000000..deeae000 --- /dev/null +++ b/packages/utils/dist/test/Uid.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Uid.test.js","sourceRoot":"","sources":["../../src/test/Uid.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,IAAI,MAAM,EAAC,MAAM,aAAa,CAAA;AAE5C,OAAO,EAAC,GAAG,EAAC,MAAM,oBAAoB,CAAA;AAEtC,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE;IACnB,EAAE,CAAC,0BAA0B,EAAE,CAAC,IAAI,EAAE,EAAE;QACtC,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;QACrB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAA;QACjC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;QAC3B,IAAI,EAAE,CAAA;IACR,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uCAAuC,EAAE,CAAC,IAAI,EAAE,EAAE;QACnD,MAAM,GAAG,GAA4B,EAAE,CAAA;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;YACrB,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,mCAAmC,CAAC,CAAA;YACrD,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAA;QAChB,CAAC;QAED,IAAI,EAAE,CAAA;IACR,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/test/Upload.test.d.ts b/packages/utils/dist/test/Upload.test.d.ts new file mode 100644 index 00000000..0e059028 --- /dev/null +++ b/packages/utils/dist/test/Upload.test.d.ts @@ -0,0 +1,2 @@ +import 'should'; +//# sourceMappingURL=Upload.test.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/test/Upload.test.d.ts.map b/packages/utils/dist/test/Upload.test.d.ts.map new file mode 100644 index 00000000..d4e30c89 --- /dev/null +++ b/packages/utils/dist/test/Upload.test.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Upload.test.d.ts","sourceRoot":"","sources":["../../src/test/Upload.test.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/test/Upload.test.js b/packages/utils/dist/test/Upload.test.js new file mode 100644 index 00000000..4b6de604 --- /dev/null +++ b/packages/utils/dist/test/Upload.test.js @@ -0,0 +1,27 @@ +import 'should'; +import { strict as assert } from 'node:assert'; +import { Upload } from '../models/Upload.js'; +import { Uid } from '../models/Uid.js'; +describe('Upload', () => { + describe('constructor', () => { + it('must require a file_name', () => { + assert.throws(() => { + // @ts-expect-error TS(2554): Expected 4 arguments, but got 0. + new Upload(); + }, Error); + }); + it('should set properties given', () => { + const id = Uid.rand(); + const size = 1234; + const offset = 0; + const metadata = { foo: 'bar' }; + const upload = new Upload({ id, size, offset, metadata }); + assert.equal(upload.id, id); + assert.equal(upload.size, size); + assert.equal(upload.offset, offset); + assert.equal(upload.sizeIsDeferred, false); + assert.equal(upload.metadata, metadata); + }); + }); +}); +//# sourceMappingURL=Upload.test.js.map \ No newline at end of file diff --git a/packages/utils/dist/test/Upload.test.js.map b/packages/utils/dist/test/Upload.test.js.map new file mode 100644 index 00000000..7aa4e6eb --- /dev/null +++ b/packages/utils/dist/test/Upload.test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Upload.test.js","sourceRoot":"","sources":["../../src/test/Upload.test.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAA;AACf,OAAO,EAAC,MAAM,IAAI,MAAM,EAAC,MAAM,aAAa,CAAA;AAE5C,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAC1C,OAAO,EAAC,GAAG,EAAC,MAAM,kBAAkB,CAAA;AAEpC,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;YAClC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE;gBACjB,8DAA8D;gBAC9D,IAAI,MAAM,EAAE,CAAA;YACd,CAAC,EAAE,KAAK,CAAC,CAAA;QACX,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;YACrB,MAAM,IAAI,GAAG,IAAI,CAAA;YACjB,MAAM,MAAM,GAAG,CAAC,CAAA;YAChB,MAAM,QAAQ,GAAG,EAAC,GAAG,EAAE,KAAK,EAAC,CAAA;YAC7B,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAC,CAAC,CAAA;YACvD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;YAC3B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YAC/B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;YACnC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;YAC1C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QACzC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/test/stores.d.ts b/packages/utils/dist/test/stores.d.ts new file mode 100644 index 00000000..59305e6d --- /dev/null +++ b/packages/utils/dist/test/stores.d.ts @@ -0,0 +1,10 @@ +import 'should'; +export declare function testId(id: string): string; +export declare const shouldHaveStoreMethods: () => void; +export declare const shouldCreateUploads: () => void; +export declare const shouldExpireUploads: () => void; +export declare const shouldRemoveUploads: () => void; +export declare const shouldWriteUploads: () => void; +export declare const shouldHandleOffset: () => void; +export declare const shouldDeclareUploadLength: () => void; +//# sourceMappingURL=stores.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/test/stores.d.ts.map b/packages/utils/dist/test/stores.d.ts.map new file mode 100644 index 00000000..13cdd4dd --- /dev/null +++ b/packages/utils/dist/test/stores.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"stores.d.ts","sourceRoot":"","sources":["../../src/test/stores.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAA;AAQf,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,UAEhC;AAED,eAAO,MAAM,sBAAsB,YAYlC,CAAA;AAED,eAAO,MAAM,mBAAmB,YA4D/B,CAAA;AAED,eAAO,MAAM,mBAAmB,YAuB/B,CAAA;AAED,eAAO,MAAM,mBAAmB,YAkD/B,CAAA;AAED,eAAO,MAAM,kBAAkB,YA2C9B,CAAA;AAED,eAAO,MAAM,kBAAkB,YAwB9B,CAAA;AAED,eAAO,MAAM,yBAAyB,YAuBrC,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/test/stores.js b/packages/utils/dist/test/stores.js new file mode 100644 index 00000000..14f84054 --- /dev/null +++ b/packages/utils/dist/test/stores.js @@ -0,0 +1,225 @@ +import 'should'; +import { strict as assert } from 'node:assert'; +import fs from 'node:fs'; +import stream from 'node:stream'; +import { setTimeout as promSetTimeout } from 'node:timers/promises'; +import { Upload, Uid } from '@tus/utils'; +export function testId(id) { + return `${id}-${Uid.rand()}`; +} +export const shouldHaveStoreMethods = () => { + describe('the class', () => { + it('must have a write method', function (done) { + this.datastore.should.have.property('write'); + done(); + }); + it('must have a getUpload method', function (done) { + this.datastore.should.have.property('getUpload'); + done(); + }); + }); +}; +export const shouldCreateUploads = () => { + describe('create', () => { + const file = new Upload({ + id: testId('create-test'), + size: 1000, + offset: 0, + metadata: { filename: 'world_domination_plan.pdf', is_confidential: null }, + }); + const file_defered = new Upload({ + id: testId('create-test-deferred'), + offset: 0, + }); + it('should resolve to file', async function () { + const newFile = await this.datastore.create(file); + assert.ok(newFile.storage.path); + assert.ok(newFile.storage.type); + assert.equal(newFile instanceof Upload, true); + }); + it("should report 'creation' extension", function () { + assert.equal(this.datastore.hasExtension('creation'), true); + }); + it('should create new upload resource', async function () { + await this.datastore.create(file); + const upload = await this.datastore.getUpload(file.id); + assert.equal(upload.offset, 0); + }); + it('should store `upload_length` when creating new resource', async function () { + await this.datastore.create(file); + const upload = await this.datastore.getUpload(file.id); + assert.strictEqual(upload.size, file.size); + }); + it('should store `upload_defer_length` when creating new resource', async function () { + await this.datastore.create(file_defered); + const upload = await this.datastore.getUpload(file_defered.id); + assert.strictEqual(upload.sizeIsDeferred, file_defered.sizeIsDeferred); + }); + it('should store `upload_metadata` when creating new resource', async function () { + await this.datastore.create(file); + const upload = await this.datastore.getUpload(file.id); + assert.deepStrictEqual(upload.metadata, file.metadata); + }); + it('should store `upload_metadata` with non-ASCII characters', async function () { + const file = new Upload({ + id: testId('create-test-non-ascii'), + size: 1000, + offset: 0, + metadata: { filename: '世界_domination_plan.pdf', is_confidential: null }, + }); + await this.datastore.create(file); + const upload = await this.datastore.getUpload(file.id); + assert.deepStrictEqual(upload.metadata, file.metadata); + }); + }); +}; +export const shouldExpireUploads = () => { + describe('expiration extension', () => { + it("should report 'expiration' extension", function () { + assert.equal(this.datastore.hasExtension('expiration'), true); + }); + it('should expire upload', async function () { + const file = new Upload({ + id: testId('expiration-test'), + size: this.testFileSize, + offset: 0, + metadata: { filename: 'world_domination_plan.pdf', is_confidential: null }, + }); + this.datastore.expirationPeriodInMilliseconds = 100; + await this.datastore.create(file); + const readable = fs.createReadStream(this.testFilePath); + const offset = await this.datastore.write(readable, file.id, 0); + await promSetTimeout(100); + const n = await this.datastore.deleteExpired(); + assert.equal(offset, this.testFileSize); + assert.equal(n, 1); + }); + }); +}; +export const shouldRemoveUploads = () => { + const file = new Upload({ id: testId('remove-test'), size: 1000, offset: 0 }); + describe('remove (termination extension)', () => { + it("should report 'termination' extension", function () { + assert.equal(this.datastore.hasExtension('termination'), true); + }); + it('should reject when the file does not exist', function () { + return this.datastore.remove('doesnt_exist').should.be.rejected(); + }); + it('should delete the file when it does exist', async function () { + await this.datastore.create(file); + return this.datastore.remove(file.id); + }); + it('should delete the file during upload', async function () { + const file = new Upload({ + id: testId('termination-test'), + size: this.testFileSize, + offset: 0, + metadata: { filename: 'terminate_during_upload.pdf', is_confidential: null }, + }); + await this.datastore.create(file); + const readable = fs.createReadStream(this.testFilePath, { + highWaterMark: 100 * 1024, + }); + // Pause between chunks read to make sure that file is still uploading when terminate function is invoked + readable.on('data', () => { + readable.pause(); + setTimeout(() => readable.resume(), 1000); + }); + await Promise.allSettled([ + this.datastore.write(readable, file.id, 0), + this.datastore.remove(file.id), + ]); + try { + await this.datastore.getUpload(file.id); + assert.fail('getUpload should have thrown an error'); + } + catch (error) { + assert.equal([404, 410].includes(error?.status_code), true); + } + readable.destroy(); + }); + }); +}; +export const shouldWriteUploads = () => { + describe('write', () => { + it('should reject write streams that can not be open', async function () { + const stream = fs.createReadStream(this.testFilePath); + return this.datastore.write(stream, 'doesnt_exist', 0).should.be.rejected(); + }); + it('should reject when readable stream has an error', async function () { + const stream = fs.createReadStream(this.testFilePath); + return this.datastore.write(stream, 'doesnt_exist', 0).should.be.rejected(); + }); + it('should write a stream and resolve the new offset', async function () { + const file = new Upload({ + id: testId('write-test'), + size: this.testFileSize, + offset: 0, + metadata: { filename: 'world_domination_plan.pdf', is_confidential: null }, + }); + await this.datastore.create(file); + const readable = fs.createReadStream(this.testFilePath); + const offset = await this.datastore.write(readable, file.id, 0); + assert.equal(offset, this.testFileSize); + }); + it('should reject when stream is destroyed', async function () { + const file = new Upload({ + id: testId('write-test-reject'), + size: this.testFileSize, + offset: 0, + metadata: { filename: 'world_domination_plan.pdf', is_confidential: null }, + }); + await this.datastore.create(file); + const readable = new stream.Readable({ + read() { + this.push('some data'); + this.destroy(); + }, + }); + const offset = this.datastore.write(readable, file.id, 0); + return offset.should.be.rejected(); + }); + }); +}; +export const shouldHandleOffset = () => { + describe('getUpload', () => { + it('should reject non-existant files', function () { + return this.datastore.getUpload('doesnt_exist').should.be.rejected(); + }); + it('should resolve the stats for existing files', async function () { + const file = new Upload({ + id: testId('offset-test'), + size: this.testFileSize, + offset: 0, + metadata: { filename: 'world_domination_plan.pdf', is_confidential: null }, + }); + await this.datastore.create(file); + const offset = await this.datastore.write(fs.createReadStream(this.testFilePath), file.id, file.offset); + const upload = await this.datastore.getUpload(file.id); + assert.equal(upload.offset, offset); + }); + }); +}; +export const shouldDeclareUploadLength = () => { + describe('declareUploadLength', () => { + it('should reject non-existant files', function () { + return this.datastore.declareUploadLength('doesnt_exist', '10').should.be.rejected(); + }); + it('should update upload_length after declaring upload length', async function () { + const file = new Upload({ + id: testId('declare-length-test'), + offset: 0, + metadata: { filename: 'world_domination_plan.pdf', is_confidential: null }, + }); + await this.datastore.create(file); + let upload = await this.datastore.getUpload(file.id); + assert.equal(upload.size, undefined); + assert.equal(upload.sizeIsDeferred, true); + await this.datastore.declareUploadLength(file.id, 10); + upload = await this.datastore.getUpload(file.id); + assert.equal(upload.size, 10); + assert.equal(upload.sizeIsDeferred, false); + }); + }); +}; +//# sourceMappingURL=stores.js.map \ No newline at end of file diff --git a/packages/utils/dist/test/stores.js.map b/packages/utils/dist/test/stores.js.map new file mode 100644 index 00000000..62f0b815 --- /dev/null +++ b/packages/utils/dist/test/stores.js.map @@ -0,0 +1 @@ +{"version":3,"file":"stores.js","sourceRoot":"","sources":["../../src/test/stores.ts"],"names":[],"mappings":"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"} \ No newline at end of file From 09b2dbb04e43eae62306c3eb48a40a219456c894 Mon Sep 17 00:00:00 2001 From: Samuel Adeoye Date: Sat, 14 Feb 2026 05:06:02 -0330 Subject: [PATCH 03/11] Remove dist and include in gitignore --- .gitignore | 2 +- packages/azure-store/dist/index.d.ts | 52 ---- packages/azure-store/dist/index.d.ts.map | 1 - packages/azure-store/dist/index.js | 183 -------------- packages/azure-store/dist/index.js.map | 1 - packages/azure-store/dist/test/index.d.ts | 2 - packages/azure-store/dist/test/index.d.ts.map | 1 - packages/azure-store/dist/test/index.js | 29 --- packages/azure-store/dist/test/index.js.map | 1 - packages/utils/dist/constants.d.ts | 90 ------- packages/utils/dist/constants.d.ts.map | 1 - packages/utils/dist/constants.js | 110 --------- packages/utils/dist/constants.js.map | 1 - packages/utils/dist/index.d.ts | 4 - packages/utils/dist/index.d.ts.map | 1 - packages/utils/dist/index.js | 4 - packages/utils/dist/index.js.map | 1 - packages/utils/dist/kvstores/FileKvStore.d.ts | 16 -- .../utils/dist/kvstores/FileKvStore.d.ts.map | 1 - packages/utils/dist/kvstores/FileKvStore.js | 38 --- .../utils/dist/kvstores/FileKvStore.js.map | 1 - .../utils/dist/kvstores/IoRedisKvStore.d.ts | 16 -- .../dist/kvstores/IoRedisKvStore.d.ts.map | 1 - .../utils/dist/kvstores/IoRedisKvStore.js | 40 ---- .../utils/dist/kvstores/IoRedisKvStore.js.map | 1 - .../utils/dist/kvstores/MemoryKvStore.d.ts | 14 -- .../dist/kvstores/MemoryKvStore.d.ts.map | 1 - packages/utils/dist/kvstores/MemoryKvStore.js | 20 -- .../utils/dist/kvstores/MemoryKvStore.js.map | 1 - .../utils/dist/kvstores/RedisKvStore.d.ts | 20 -- .../utils/dist/kvstores/RedisKvStore.d.ts.map | 1 - packages/utils/dist/kvstores/RedisKvStore.js | 42 ---- .../utils/dist/kvstores/RedisKvStore.js.map | 1 - packages/utils/dist/kvstores/Types.d.ts | 8 - packages/utils/dist/kvstores/Types.d.ts.map | 1 - packages/utils/dist/kvstores/Types.js | 2 - packages/utils/dist/kvstores/Types.js.map | 1 - packages/utils/dist/kvstores/index.d.ts | 6 - packages/utils/dist/kvstores/index.d.ts.map | 1 - packages/utils/dist/kvstores/index.js | 5 - packages/utils/dist/kvstores/index.js.map | 1 - packages/utils/dist/models/Context.d.ts | 26 -- packages/utils/dist/models/Context.d.ts.map | 1 - packages/utils/dist/models/Context.js | 2 - packages/utils/dist/models/Context.js.map | 1 - packages/utils/dist/models/DataStore.d.ts | 43 ---- packages/utils/dist/models/DataStore.d.ts.map | 1 - packages/utils/dist/models/DataStore.js | 59 ----- packages/utils/dist/models/DataStore.js.map | 1 - packages/utils/dist/models/Locker.d.ts | 30 --- packages/utils/dist/models/Locker.d.ts.map | 1 - packages/utils/dist/models/Locker.js | 2 - packages/utils/dist/models/Locker.js.map | 1 - packages/utils/dist/models/Metadata.d.ts | 6 - packages/utils/dist/models/Metadata.d.ts.map | 1 - packages/utils/dist/models/Metadata.js | 55 ----- packages/utils/dist/models/Metadata.js.map | 1 - packages/utils/dist/models/StreamLimiter.d.ts | 13 - .../utils/dist/models/StreamLimiter.d.ts.map | 1 - packages/utils/dist/models/StreamLimiter.js | 31 --- .../utils/dist/models/StreamLimiter.js.map | 1 - .../utils/dist/models/StreamSplitter.d.ts | 26 -- .../utils/dist/models/StreamSplitter.d.ts.map | 1 - packages/utils/dist/models/StreamSplitter.js | 114 --------- .../utils/dist/models/StreamSplitter.js.map | 1 - packages/utils/dist/models/Uid.d.ts | 4 - packages/utils/dist/models/Uid.d.ts.map | 1 - packages/utils/dist/models/Uid.js | 7 - packages/utils/dist/models/Uid.js.map | 1 - packages/utils/dist/models/Upload.d.ts | 24 -- packages/utils/dist/models/Upload.d.ts.map | 1 - packages/utils/dist/models/Upload.js | 23 -- packages/utils/dist/models/Upload.js.map | 1 - packages/utils/dist/models/index.d.ts | 9 - packages/utils/dist/models/index.d.ts.map | 1 - packages/utils/dist/models/index.js | 7 - packages/utils/dist/models/index.js.map | 1 - packages/utils/dist/test/Metadata.test.d.ts | 2 - .../utils/dist/test/Metadata.test.d.ts.map | 1 - packages/utils/dist/test/Metadata.test.js | 108 --------- packages/utils/dist/test/Metadata.test.js.map | 1 - .../utils/dist/test/StreamSplitter.test.d.ts | 2 - .../dist/test/StreamSplitter.test.d.ts.map | 1 - .../utils/dist/test/StreamSplitter.test.js | 47 ---- .../dist/test/StreamSplitter.test.js.map | 1 - packages/utils/dist/test/Uid.test.d.ts | 2 - packages/utils/dist/test/Uid.test.d.ts.map | 1 - packages/utils/dist/test/Uid.test.js | 20 -- packages/utils/dist/test/Uid.test.js.map | 1 - packages/utils/dist/test/Upload.test.d.ts | 2 - packages/utils/dist/test/Upload.test.d.ts.map | 1 - packages/utils/dist/test/Upload.test.js | 27 --- packages/utils/dist/test/Upload.test.js.map | 1 - packages/utils/dist/test/stores.d.ts | 10 - packages/utils/dist/test/stores.d.ts.map | 1 - packages/utils/dist/test/stores.js | 225 ------------------ packages/utils/dist/test/stores.js.map | 1 - 97 files changed, 1 insertion(+), 1676 deletions(-) delete mode 100644 packages/azure-store/dist/index.d.ts delete mode 100644 packages/azure-store/dist/index.d.ts.map delete mode 100644 packages/azure-store/dist/index.js delete mode 100644 packages/azure-store/dist/index.js.map delete mode 100644 packages/azure-store/dist/test/index.d.ts delete mode 100644 packages/azure-store/dist/test/index.d.ts.map delete mode 100644 packages/azure-store/dist/test/index.js delete mode 100644 packages/azure-store/dist/test/index.js.map delete mode 100644 packages/utils/dist/constants.d.ts delete mode 100644 packages/utils/dist/constants.d.ts.map delete mode 100644 packages/utils/dist/constants.js delete mode 100644 packages/utils/dist/constants.js.map delete mode 100644 packages/utils/dist/index.d.ts delete mode 100644 packages/utils/dist/index.d.ts.map delete mode 100644 packages/utils/dist/index.js delete mode 100644 packages/utils/dist/index.js.map delete mode 100644 packages/utils/dist/kvstores/FileKvStore.d.ts delete mode 100644 packages/utils/dist/kvstores/FileKvStore.d.ts.map delete mode 100644 packages/utils/dist/kvstores/FileKvStore.js delete mode 100644 packages/utils/dist/kvstores/FileKvStore.js.map delete mode 100644 packages/utils/dist/kvstores/IoRedisKvStore.d.ts delete mode 100644 packages/utils/dist/kvstores/IoRedisKvStore.d.ts.map delete mode 100644 packages/utils/dist/kvstores/IoRedisKvStore.js delete mode 100644 packages/utils/dist/kvstores/IoRedisKvStore.js.map delete mode 100644 packages/utils/dist/kvstores/MemoryKvStore.d.ts delete mode 100644 packages/utils/dist/kvstores/MemoryKvStore.d.ts.map delete mode 100644 packages/utils/dist/kvstores/MemoryKvStore.js delete mode 100644 packages/utils/dist/kvstores/MemoryKvStore.js.map delete mode 100644 packages/utils/dist/kvstores/RedisKvStore.d.ts delete mode 100644 packages/utils/dist/kvstores/RedisKvStore.d.ts.map delete mode 100644 packages/utils/dist/kvstores/RedisKvStore.js delete mode 100644 packages/utils/dist/kvstores/RedisKvStore.js.map delete mode 100644 packages/utils/dist/kvstores/Types.d.ts delete mode 100644 packages/utils/dist/kvstores/Types.d.ts.map delete mode 100644 packages/utils/dist/kvstores/Types.js delete mode 100644 packages/utils/dist/kvstores/Types.js.map delete mode 100644 packages/utils/dist/kvstores/index.d.ts delete mode 100644 packages/utils/dist/kvstores/index.d.ts.map delete mode 100644 packages/utils/dist/kvstores/index.js delete mode 100644 packages/utils/dist/kvstores/index.js.map delete mode 100644 packages/utils/dist/models/Context.d.ts delete mode 100644 packages/utils/dist/models/Context.d.ts.map delete mode 100644 packages/utils/dist/models/Context.js delete mode 100644 packages/utils/dist/models/Context.js.map delete mode 100644 packages/utils/dist/models/DataStore.d.ts delete mode 100644 packages/utils/dist/models/DataStore.d.ts.map delete mode 100644 packages/utils/dist/models/DataStore.js delete mode 100644 packages/utils/dist/models/DataStore.js.map delete mode 100644 packages/utils/dist/models/Locker.d.ts delete mode 100644 packages/utils/dist/models/Locker.d.ts.map delete mode 100644 packages/utils/dist/models/Locker.js delete mode 100644 packages/utils/dist/models/Locker.js.map delete mode 100644 packages/utils/dist/models/Metadata.d.ts delete mode 100644 packages/utils/dist/models/Metadata.d.ts.map delete mode 100644 packages/utils/dist/models/Metadata.js delete mode 100644 packages/utils/dist/models/Metadata.js.map delete mode 100644 packages/utils/dist/models/StreamLimiter.d.ts delete mode 100644 packages/utils/dist/models/StreamLimiter.d.ts.map delete mode 100644 packages/utils/dist/models/StreamLimiter.js delete mode 100644 packages/utils/dist/models/StreamLimiter.js.map delete mode 100644 packages/utils/dist/models/StreamSplitter.d.ts delete mode 100644 packages/utils/dist/models/StreamSplitter.d.ts.map delete mode 100644 packages/utils/dist/models/StreamSplitter.js delete mode 100644 packages/utils/dist/models/StreamSplitter.js.map delete mode 100644 packages/utils/dist/models/Uid.d.ts delete mode 100644 packages/utils/dist/models/Uid.d.ts.map delete mode 100644 packages/utils/dist/models/Uid.js delete mode 100644 packages/utils/dist/models/Uid.js.map delete mode 100644 packages/utils/dist/models/Upload.d.ts delete mode 100644 packages/utils/dist/models/Upload.d.ts.map delete mode 100644 packages/utils/dist/models/Upload.js delete mode 100644 packages/utils/dist/models/Upload.js.map delete mode 100644 packages/utils/dist/models/index.d.ts delete mode 100644 packages/utils/dist/models/index.d.ts.map delete mode 100644 packages/utils/dist/models/index.js delete mode 100644 packages/utils/dist/models/index.js.map delete mode 100644 packages/utils/dist/test/Metadata.test.d.ts delete mode 100644 packages/utils/dist/test/Metadata.test.d.ts.map delete mode 100644 packages/utils/dist/test/Metadata.test.js delete mode 100644 packages/utils/dist/test/Metadata.test.js.map delete mode 100644 packages/utils/dist/test/StreamSplitter.test.d.ts delete mode 100644 packages/utils/dist/test/StreamSplitter.test.d.ts.map delete mode 100644 packages/utils/dist/test/StreamSplitter.test.js delete mode 100644 packages/utils/dist/test/StreamSplitter.test.js.map delete mode 100644 packages/utils/dist/test/Uid.test.d.ts delete mode 100644 packages/utils/dist/test/Uid.test.d.ts.map delete mode 100644 packages/utils/dist/test/Uid.test.js delete mode 100644 packages/utils/dist/test/Uid.test.js.map delete mode 100644 packages/utils/dist/test/Upload.test.d.ts delete mode 100644 packages/utils/dist/test/Upload.test.d.ts.map delete mode 100644 packages/utils/dist/test/Upload.test.js delete mode 100644 packages/utils/dist/test/Upload.test.js.map delete mode 100644 packages/utils/dist/test/stores.d.ts delete mode 100644 packages/utils/dist/test/stores.d.ts.map delete mode 100644 packages/utils/dist/test/stores.js delete mode 100644 packages/utils/dist/test/stores.js.map diff --git a/.gitignore b/.gitignore index 4aa7df5b..9da13f3f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ .idea .eslintcache -# dist +dist .turbo *.tsbuildinfo output/ diff --git a/packages/azure-store/dist/index.d.ts b/packages/azure-store/dist/index.d.ts deleted file mode 100644 index 7acc8ca2..00000000 --- a/packages/azure-store/dist/index.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -import type stream from 'node:stream'; -import { DataStore, Upload, type KvStore } from '@tus/utils'; -import type { TokenCredential } from '@azure/core-auth'; -type Options = { - cache?: KvStore; - account: string; - containerName: string; - accountKey?: string; - credential?: TokenCredential; -}; -/** - * Store using the Azure Storage SDK - * @author Bharath Battaje - */ -export declare class AzureStore extends DataStore { - private cache; - private blobServiceClient; - private containerClient; - private containerName; - constructor(options: Options); - /** - * Saves upload metadata to blob metada. Also upload metadata - * gets saved in local cache as well to avoid calling azure server everytime. - */ - private saveMetadata; - /** - * Retrieves upload metadata previously saved. - * It tries to get from local cache, else get from the blob metadata. - */ - private getMetadata; - /** - * provides the readable stream for the previously uploaded file - */ - read(file_id: string): Promise; - /** - * Creates a empty append blob on Azure storage and attaches the metadata to it. - */ - create(upload: Upload): Promise; - /** - * Gets the current file upload status - */ - getUpload(id: string): Promise; - /** - * Uploads each blob to the azure blob storage. Please note that current official Azure stoarge node sdk has some limitation - * when it comes to stream upload. So here we are concatenating all the chunks from a request into a block and then uploading - * to azure storage using the appendBlock. This can be upgraded to streamUpload when node sdk start supporting it. - */ - write(stream: stream.Readable, id: string, offset: number): Promise; - declareUploadLength(id: string, upload_length: number): Promise; -} -export {}; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/azure-store/dist/index.d.ts.map b/packages/azure-store/dist/index.d.ts.map deleted file mode 100644 index 8b539cf6..00000000 --- a/packages/azure-store/dist/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC,OAAO,EACL,SAAS,EACT,MAAM,EAEN,KAAK,OAAO,EAIb,MAAM,YAAY,CAAA;AAQnB,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAA;AAErD,KAAK,OAAO,GAAG;IACb,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,eAAe,CAAA;CAC7B,CAAA;AAID;;;GAGG;AACH,qBAAa,UAAW,SAAQ,SAAS;IACvC,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,iBAAiB,CAAmB;IAC5C,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,aAAa,CAAQ;gBAEjB,OAAO,EAAE,OAAO;IA8B5B;;;OAGG;YACW,YAAY;IAoB1B;;;OAGG;YACW,WAAW;IA+BzB;;OAEG;IACU,IAAI,CAAC,OAAO,EAAE,MAAM;IAOjC;;OAEG;IACU,MAAM,CAAC,MAAM,EAAE,MAAM;IAqBlC;;OAEG;IACU,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBnD;;;;OAIG;IACU,KAAK,CAChB,MAAM,EAAE,MAAM,CAAC,QAAQ,EACvB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC;IAqDL,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM;CAYnE"} \ No newline at end of file diff --git a/packages/azure-store/dist/index.js b/packages/azure-store/dist/index.js deleted file mode 100644 index 5e9911c8..00000000 --- a/packages/azure-store/dist/index.js +++ /dev/null @@ -1,183 +0,0 @@ -import debug from 'debug'; -import { DataStore, Upload, ERRORS, MemoryKvStore, TUS_RESUMABLE, Metadata, } from '@tus/utils'; -import { BlobServiceClient, StorageSharedKeyCredential, } from '@azure/storage-blob'; -const log = debug('tus-node-server:stores:azurestore'); -/** - * Store using the Azure Storage SDK - * @author Bharath Battaje - */ -export class AzureStore extends DataStore { - cache; - blobServiceClient; - containerClient; - containerName; - constructor(options) { - super(); - this.cache = options.cache ?? new MemoryKvStore(); - this.extensions = ['creation', 'creation-defer-length']; - if (!options.account) { - throw new Error('Azure store must have a account'); - } - if (!options.containerName) { - throw new Error('Azure store must have a container name'); - } - if (!options.accountKey && !options.credential) { - throw new Error('Azure store requires either accountKey or credential'); - } - const storageAccountBaseUrl = `https://${options.account}.blob.core.windows.net`; - const credential = options.credential - ? options.credential - : new StorageSharedKeyCredential(options.account, options.accountKey); - this.blobServiceClient = new BlobServiceClient(storageAccountBaseUrl, credential); - this.containerClient = this.blobServiceClient.getContainerClient(options.containerName); - this.containerName = options.containerName; - } - /** - * Saves upload metadata to blob metada. Also upload metadata - * gets saved in local cache as well to avoid calling azure server everytime. - */ - async saveMetadata(appendBlobClient, upload) { - log(`[${upload.id}] saving metadata`); - await this.cache.set(appendBlobClient.url, upload); - await appendBlobClient.setMetadata({ - tus_version: TUS_RESUMABLE, - upload: JSON.stringify({ - ...upload, - // Base64 encode the metadata to avoid errors for non-ASCII characters - metadata: Metadata.stringify(upload.metadata ?? {}), - }), - }, {}); - log(`[${upload.id}] metadata saved`); - } - /** - * Retrieves upload metadata previously saved. - * It tries to get from local cache, else get from the blob metadata. - */ - async getMetadata(appendBlobClient) { - const cached = await this.cache.get(appendBlobClient.url); - if (cached) { - log(`[${cached.id}] metadata returned from cache`); - return cached; - } - let propertyData; - try { - propertyData = await appendBlobClient.getProperties(); - } - catch (error) { - log('Error while fetching the metadata.', error); - throw ERRORS.UNKNOWN_ERROR; - } - if (!propertyData.metadata) { - throw ERRORS.FILE_NOT_FOUND; - } - const upload = JSON.parse(propertyData.metadata.upload); - // Metadata is base64 encoded to avoid errors for non-ASCII characters - // so we need to decode it separately - upload.metadata = Metadata.parse(JSON.stringify(upload.metadata ?? {})); - await this.cache.set(appendBlobClient.url, upload); - log('metadata returned from blob get properties'); - return upload; - } - /** - * provides the readable stream for the previously uploaded file - */ - async read(file_id) { - const appendBlobClient = this.containerClient.getAppendBlobClient(file_id); - const downloadResponse = await appendBlobClient.download(); - return downloadResponse.readableStreamBody; - } - /** - * Creates a empty append blob on Azure storage and attaches the metadata to it. - */ - async create(upload) { - log(`[${upload.id}] initializing azure storage file upload`); - try { - const appendBlobClient = this.containerClient.getAppendBlobClient(upload.id); - await appendBlobClient.createIfNotExists(); - upload.storage = { - type: 'AzureBlobStore', - path: upload.id, - bucket: this.containerName, - }; - await this.saveMetadata(appendBlobClient, upload); - return upload; - } - catch (err) { - throw ERRORS.UNKNOWN_ERROR; - } - } - /** - * Gets the current file upload status - */ - async getUpload(id) { - const appendBlobClient = this.containerClient.getAppendBlobClient(id); - const upload = await this.getMetadata(appendBlobClient); - if (!upload) { - throw ERRORS.FILE_NOT_FOUND; - } - return new Upload({ - id: id, - size: upload.size, - metadata: upload.metadata, - offset: upload.offset, - storage: upload.storage, - creation_date: upload.creation_date, - }); - } - /** - * Uploads each blob to the azure blob storage. Please note that current official Azure stoarge node sdk has some limitation - * when it comes to stream upload. So here we are concatenating all the chunks from a request into a block and then uploading - * to azure storage using the appendBlock. This can be upgraded to streamUpload when node sdk start supporting it. - */ - async write(stream, id, offset) { - log(`started writing the file offset [${offset}]`); - const appendBlobClient = this.containerClient.getAppendBlobClient(id); - const upload = await this.getMetadata(appendBlobClient); - // biome-ignore lint/suspicious/noAsyncPromiseExecutor: - return new Promise(async (resolve, reject) => { - if (offset < upload.offset) { - //duplicate request scenario, dont want to write the same data - return resolve(upload.offset); - } - try { - const bufs = []; - stream.on('data', async (chunk) => { - if (stream.destroyed) { - return reject(ERRORS.ABORTED); - } - bufs.push(chunk); - }); - stream.on('end', async () => { - const buf = Buffer.concat(bufs); - if (buf.length > 0) { - await appendBlobClient.appendBlock(buf, buf.length); - } - upload.offset = upload.offset + buf.length; - log(`saved offset is [${upload.offset}]`); - await this.saveMetadata(appendBlobClient, upload); - if (upload.offset === upload.size) { - await this.cache.delete(appendBlobClient.url); - log(`file upload completed successfully [${id}]`); - } - return resolve(upload.offset); - }); - stream.on('error', async () => { - return reject(ERRORS.UNKNOWN_ERROR); - }); - } - catch (err) { - return reject('something went wrong while writing the file.'); - } - }); - } - async declareUploadLength(id, upload_length) { - const appendBlobClient = this.containerClient.getAppendBlobClient(id); - const upload = await this.getMetadata(appendBlobClient); - if (!upload) { - throw ERRORS.FILE_NOT_FOUND; - } - upload.size = upload_length; - await this.saveMetadata(appendBlobClient, upload); - } -} -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/azure-store/dist/index.js.map b/packages/azure-store/dist/index.js.map deleted file mode 100644 index 8923d2ae..00000000 --- a/packages/azure-store/dist/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/azure-store/dist/test/index.d.ts b/packages/azure-store/dist/test/index.d.ts deleted file mode 100644 index 2f8a39e2..00000000 --- a/packages/azure-store/dist/test/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import 'should'; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/azure-store/dist/test/index.d.ts.map b/packages/azure-store/dist/test/index.d.ts.map deleted file mode 100644 index 90649a39..00000000 --- a/packages/azure-store/dist/test/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAA"} \ No newline at end of file diff --git a/packages/azure-store/dist/test/index.js b/packages/azure-store/dist/test/index.js deleted file mode 100644 index a505d242..00000000 --- a/packages/azure-store/dist/test/index.js +++ /dev/null @@ -1,29 +0,0 @@ -import 'should'; -import path from 'node:path'; -import { AzureStore } from '@tus/azure-store'; -import * as shared from '../../../utils/dist/test/stores.js'; -const fixturesPath = path.resolve('../', '../', 'test', 'fixtures'); -const storePath = path.resolve('../', '../', 'test', 'output', 'azure-store'); -describe('AzureStore', () => { - before(function () { - this.testFileSize = 960_244; - this.testFileName = 'test.mp4'; - this.storePath = storePath; - this.testFilePath = path.resolve(fixturesPath, this.testFileName); - }); - beforeEach(function () { - this.datastore = new AzureStore({ - account: process.env.AZURE_ACCOUNT_ID, - accountKey: process.env.AZURE_ACCOUNT_KEY, - containerName: process.env.AZURE_CONTAINER_NAME, - }); - }); - shared.shouldHaveStoreMethods(); - shared.shouldCreateUploads(); - // shared.shouldRemoveUploads() // Not implemented yet - // shared.shouldExpireUploads() // Not implemented yet - shared.shouldWriteUploads(); - shared.shouldHandleOffset(); - shared.shouldDeclareUploadLength(); // Creation-defer-length extension -}); -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/azure-store/dist/test/index.js.map b/packages/azure-store/dist/test/index.js.map deleted file mode 100644 index cf6cd079..00000000 --- a/packages/azure-store/dist/test/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAA;AACf,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,oCAAoC,CAAA;AAE5D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAA;AACnE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAA;AAE7E,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,MAAM,CAAC;QACL,IAAI,CAAC,YAAY,GAAG,OAAO,CAAA;QAC3B,IAAI,CAAC,YAAY,GAAG,UAAU,CAAA;QAC9B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;IACnE,CAAC,CAAC,CAAA;IAEF,UAAU,CAAC;QACT,IAAI,CAAC,SAAS,GAAG,IAAI,UAAU,CAAC;YAC9B,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,gBAA0B;YAC/C,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,iBAA2B;YACnD,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,oBAA8B;SAC1D,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,sBAAsB,EAAE,CAAA;IAC/B,MAAM,CAAC,mBAAmB,EAAE,CAAA;IAC5B,sDAAsD;IACtD,sDAAsD;IACtD,MAAM,CAAC,kBAAkB,EAAE,CAAA;IAC3B,MAAM,CAAC,kBAAkB,EAAE,CAAA;IAC3B,MAAM,CAAC,yBAAyB,EAAE,CAAA,CAAC,kCAAkC;AACvE,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/constants.d.ts b/packages/utils/dist/constants.d.ts deleted file mode 100644 index d5fabcb4..00000000 --- a/packages/utils/dist/constants.d.ts +++ /dev/null @@ -1,90 +0,0 @@ -export declare const REQUEST_METHODS: readonly ["POST", "HEAD", "PATCH", "OPTIONS", "DELETE"]; -export declare const HEADERS: readonly ["Authorization", "Content-Type", "Location", "Tus-Extension", "Tus-Max-Size", "Tus-Resumable", "Tus-Version", "Upload-Concat", "Upload-Defer-Length", "Upload-Length", "Upload-Metadata", "Upload-Offset", "X-HTTP-Method-Override", "X-Requested-With", "X-Forwarded-Host", "X-Forwarded-Proto", "Forwarded"]; -export declare const HEADERS_LOWERCASE: Array>; -export declare const ALLOWED_HEADERS: string; -export declare const ALLOWED_METHODS: string; -export declare const EXPOSED_HEADERS: string; -export declare const ERRORS: { - readonly MISSING_OFFSET: { - readonly status_code: 403; - readonly body: "Upload-Offset header required\n"; - }; - readonly ABORTED: { - readonly status_code: 400; - readonly body: "Request aborted due to lock acquired"; - }; - readonly INVALID_TERMINATION: { - readonly status_code: 400; - readonly body: "Cannot terminate an already completed upload"; - }; - readonly ERR_LOCK_TIMEOUT: { - readonly status_code: 500; - readonly body: "failed to acquire lock before timeout"; - }; - readonly INVALID_CONTENT_TYPE: { - readonly status_code: 403; - readonly body: "Content-Type header required\n"; - }; - readonly FILE_NOT_FOUND: { - readonly status_code: 404; - readonly body: "The file for this url was not found\n"; - }; - readonly INVALID_OFFSET: { - readonly status_code: 409; - readonly body: "Upload-Offset conflict\n"; - }; - readonly FILE_NO_LONGER_EXISTS: { - readonly status_code: 410; - readonly body: "The file for this url no longer exists\n"; - }; - readonly ERR_SIZE_EXCEEDED: { - readonly status_code: 413; - readonly body: "upload's size exceeded\n"; - }; - readonly ERR_MAX_SIZE_EXCEEDED: { - readonly status_code: 413; - readonly body: "Maximum size exceeded\n"; - }; - readonly INVALID_LENGTH: { - readonly status_code: 400; - readonly body: "Upload-Length or Upload-Defer-Length header required\n"; - }; - readonly INVALID_METADATA: { - readonly status_code: 400; - readonly body: "Upload-Metadata is invalid. It MUST consist of one or more comma-separated key-value pairs. The key and value MUST be separated by a space. The key MUST NOT contain spaces and commas and MUST NOT be empty. The key SHOULD be ASCII encoded and the value MUST be Base64 encoded. All keys MUST be unique"; - }; - readonly UNKNOWN_ERROR: { - readonly status_code: 500; - readonly body: "Something went wrong with that request\n"; - }; - readonly FILE_WRITE_ERROR: { - readonly status_code: 500; - readonly body: "Something went wrong receiving the file\n"; - }; - readonly UNSUPPORTED_CONCATENATION_EXTENSION: { - readonly status_code: 501; - readonly body: "Concatenation extension is not (yet) supported. Disable parallel uploads in the tus client.\n"; - }; - readonly UNSUPPORTED_CREATION_DEFER_LENGTH_EXTENSION: { - readonly status_code: 501; - readonly body: "creation-defer-length extension is not (yet) supported.\n"; - }; - readonly UNSUPPORTED_EXPIRATION_EXTENSION: { - readonly status_code: 501; - readonly body: "expiration extension is not (yet) supported.\n"; - }; -}; -export declare const POST_CREATE: "POST_CREATE"; -export declare const POST_RECEIVE: "POST_RECEIVE"; -export declare const POST_FINISH: "POST_FINISH"; -export declare const POST_TERMINATE: "POST_TERMINATE"; -export declare const EVENTS: { - readonly POST_CREATE: "POST_CREATE"; - readonly POST_RECEIVE: "POST_RECEIVE"; - readonly POST_FINISH: "POST_FINISH"; - readonly POST_TERMINATE: "POST_TERMINATE"; -}; -export declare const MAX_AGE: 86400; -export declare const TUS_RESUMABLE: "1.0.0"; -export declare const TUS_VERSION: readonly ["1.0.0"]; -//# sourceMappingURL=constants.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/constants.d.ts.map b/packages/utils/dist/constants.d.ts.map deleted file mode 100644 index 1c6c9615..00000000 --- a/packages/utils/dist/constants.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,yDAA0D,CAAA;AAEtF,eAAO,MAAM,OAAO,0TAkBV,CAAA;AAEV,eAAO,MAAM,iBAAiB,EAExB,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;AAEhD,eAAO,MAAM,eAAe,QAAqB,CAAA;AACjD,eAAO,MAAM,eAAe,QAA6B,CAAA;AACzD,eAAO,MAAM,eAAe,QAAqB,CAAA;AAEjD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqET,CAAA;AAEV,eAAO,MAAM,WAAW,EAAG,aAAsB,CAAA;AACjD,eAAO,MAAM,YAAY,EAAG,cAAuB,CAAA;AACnD,eAAO,MAAM,WAAW,EAAG,aAAsB,CAAA;AACjD,eAAO,MAAM,cAAc,EAAG,gBAAyB,CAAA;AACvD,eAAO,MAAM,MAAM;;;;;CAKT,CAAA;AAEV,eAAO,MAAM,OAAO,EAAG,KAAe,CAAA;AACtC,eAAO,MAAM,aAAa,EAAG,OAAgB,CAAA;AAC7C,eAAO,MAAM,WAAW,oBAAqB,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/constants.js b/packages/utils/dist/constants.js deleted file mode 100644 index bfe451a7..00000000 --- a/packages/utils/dist/constants.js +++ /dev/null @@ -1,110 +0,0 @@ -export const REQUEST_METHODS = ['POST', 'HEAD', 'PATCH', 'OPTIONS', 'DELETE']; -export const HEADERS = [ - 'Authorization', - 'Content-Type', - 'Location', - 'Tus-Extension', - 'Tus-Max-Size', - 'Tus-Resumable', - 'Tus-Version', - 'Upload-Concat', - 'Upload-Defer-Length', - 'Upload-Length', - 'Upload-Metadata', - 'Upload-Offset', - 'X-HTTP-Method-Override', - 'X-Requested-With', - 'X-Forwarded-Host', - 'X-Forwarded-Proto', - 'Forwarded', -]; -export const HEADERS_LOWERCASE = HEADERS.map((header) => { - return header.toLowerCase(); -}); -export const ALLOWED_HEADERS = HEADERS.join(', '); -export const ALLOWED_METHODS = REQUEST_METHODS.join(', '); -export const EXPOSED_HEADERS = HEADERS.join(', '); -export const ERRORS = { - MISSING_OFFSET: { - status_code: 403, - body: 'Upload-Offset header required\n', - }, - ABORTED: { - status_code: 400, - body: 'Request aborted due to lock acquired', - }, - INVALID_TERMINATION: { - status_code: 400, - body: 'Cannot terminate an already completed upload', - }, - ERR_LOCK_TIMEOUT: { - status_code: 500, - body: 'failed to acquire lock before timeout', - }, - INVALID_CONTENT_TYPE: { - status_code: 403, - body: 'Content-Type header required\n', - }, - FILE_NOT_FOUND: { - status_code: 404, - body: 'The file for this url was not found\n', - }, - INVALID_OFFSET: { - status_code: 409, - body: 'Upload-Offset conflict\n', - }, - FILE_NO_LONGER_EXISTS: { - status_code: 410, - body: 'The file for this url no longer exists\n', - }, - ERR_SIZE_EXCEEDED: { - status_code: 413, - body: "upload's size exceeded\n", - }, - ERR_MAX_SIZE_EXCEEDED: { - status_code: 413, - body: 'Maximum size exceeded\n', - }, - INVALID_LENGTH: { - status_code: 400, - body: 'Upload-Length or Upload-Defer-Length header required\n', - }, - INVALID_METADATA: { - status_code: 400, - body: 'Upload-Metadata is invalid. It MUST consist of one or more comma-separated key-value pairs. The key and value MUST be separated by a space. The key MUST NOT contain spaces and commas and MUST NOT be empty. The key SHOULD be ASCII encoded and the value MUST be Base64 encoded. All keys MUST be unique', - }, - UNKNOWN_ERROR: { - status_code: 500, - body: 'Something went wrong with that request\n', - }, - FILE_WRITE_ERROR: { - status_code: 500, - body: 'Something went wrong receiving the file\n', - }, - UNSUPPORTED_CONCATENATION_EXTENSION: { - status_code: 501, - body: 'Concatenation extension is not (yet) supported. Disable parallel uploads in the tus client.\n', - }, - UNSUPPORTED_CREATION_DEFER_LENGTH_EXTENSION: { - status_code: 501, - body: 'creation-defer-length extension is not (yet) supported.\n', - }, - UNSUPPORTED_EXPIRATION_EXTENSION: { - status_code: 501, - body: 'expiration extension is not (yet) supported.\n', - }, -}; -export const POST_CREATE = 'POST_CREATE'; -export const POST_RECEIVE = 'POST_RECEIVE'; -export const POST_FINISH = 'POST_FINISH'; -export const POST_TERMINATE = 'POST_TERMINATE'; -export const EVENTS = { - POST_CREATE, - POST_RECEIVE, - POST_FINISH, - POST_TERMINATE, -}; -export const MAX_AGE = 86_400; -export const TUS_RESUMABLE = '1.0.0'; -export const TUS_VERSION = ['1.0.0']; -//# sourceMappingURL=constants.js.map \ No newline at end of file diff --git a/packages/utils/dist/constants.js.map b/packages/utils/dist/constants.js.map deleted file mode 100644 index 62e83c77..00000000 --- a/packages/utils/dist/constants.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/utils/dist/index.d.ts b/packages/utils/dist/index.d.ts deleted file mode 100644 index 3b5ac364..00000000 --- a/packages/utils/dist/index.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './models/index.js'; -export * from './constants.js'; -export * from './kvstores/index.js'; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/index.d.ts.map b/packages/utils/dist/index.d.ts.map deleted file mode 100644 index cca01cb5..00000000 --- a/packages/utils/dist/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/index.js b/packages/utils/dist/index.js deleted file mode 100644 index 2fe856d6..00000000 --- a/packages/utils/dist/index.js +++ /dev/null @@ -1,4 +0,0 @@ -export * from './models/index.js'; -export * from './constants.js'; -export * from './kvstores/index.js'; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/utils/dist/index.js.map b/packages/utils/dist/index.js.map deleted file mode 100644 index 2af37165..00000000 --- a/packages/utils/dist/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/FileKvStore.d.ts b/packages/utils/dist/kvstores/FileKvStore.d.ts deleted file mode 100644 index f1ed2de6..00000000 --- a/packages/utils/dist/kvstores/FileKvStore.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { KvStore } from './Types.js'; -import type { Upload } from '../models/index.js'; -/** - * FileConfigstore writes the `Upload` JSON metadata to disk next the uploaded file itself. - * It uses a queue which only processes one operation at a time to prevent unsafe concurrent access. - */ -export declare class FileKvStore implements KvStore { - directory: string; - constructor(path: string); - get(key: string): Promise; - set(key: string, value: T): Promise; - delete(key: string): Promise; - list(): Promise>; - private resolve; -} -//# sourceMappingURL=FileKvStore.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/FileKvStore.d.ts.map b/packages/utils/dist/kvstores/FileKvStore.d.ts.map deleted file mode 100644 index 98091416..00000000 --- a/packages/utils/dist/kvstores/FileKvStore.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"FileKvStore.d.ts","sourceRoot":"","sources":["../../src/kvstores/FileKvStore.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAA;AAE9C;;;GAGG;AACH,qBAAa,WAAW,CAAC,CAAC,GAAG,MAAM,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;IACxD,SAAS,EAAE,MAAM,CAAA;gBAEL,IAAI,EAAE,MAAM;IAIlB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IASxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAUpC,OAAO,CAAC,OAAO;CAGhB"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/FileKvStore.js b/packages/utils/dist/kvstores/FileKvStore.js deleted file mode 100644 index 4723a944..00000000 --- a/packages/utils/dist/kvstores/FileKvStore.js +++ /dev/null @@ -1,38 +0,0 @@ -import fs from 'node:fs/promises'; -import path from 'node:path'; -/** - * FileConfigstore writes the `Upload` JSON metadata to disk next the uploaded file itself. - * It uses a queue which only processes one operation at a time to prevent unsafe concurrent access. - */ -export class FileKvStore { - directory; - constructor(path) { - this.directory = path; - } - async get(key) { - try { - const buffer = await fs.readFile(this.resolve(key), 'utf8'); - return JSON.parse(buffer); - } - catch { - return undefined; - } - } - async set(key, value) { - await fs.writeFile(this.resolve(key), JSON.stringify(value)); - } - async delete(key) { - await fs.rm(this.resolve(key)); - } - async list() { - const files = await fs.readdir(this.directory); - const sorted = files.sort((a, b) => a.localeCompare(b)); - const name = (file) => path.basename(file, '.json'); - // To only return tus file IDs we check if the file has a corresponding JSON info file - return sorted.filter((file, idx) => idx < sorted.length - 1 && name(file) === name(sorted[idx + 1])); - } - resolve(key) { - return path.resolve(this.directory, `${key}.json`); - } -} -//# sourceMappingURL=FileKvStore.js.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/FileKvStore.js.map b/packages/utils/dist/kvstores/FileKvStore.js.map deleted file mode 100644 index be3a085d..00000000 --- a/packages/utils/dist/kvstores/FileKvStore.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"FileKvStore.js","sourceRoot":"","sources":["../../src/kvstores/FileKvStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,IAAI,MAAM,WAAW,CAAA;AAK5B;;;GAGG;AACH,MAAM,OAAO,WAAW;IACtB,SAAS,CAAQ;IAEjB,YAAY,IAAY;QACtB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAA;YAC3D,OAAO,IAAI,CAAC,KAAK,CAAC,MAAgB,CAAC,CAAA;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAQ;QAC7B,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;IAC9D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAA;IAChC,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;QACvD,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAC3D,sFAAsF;QACtF,OAAO,MAAM,CAAC,MAAM,CAClB,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAC/E,CAAA;IACH,CAAC;IAEO,OAAO,CAAC,GAAW;QACzB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,CAAA;IACpD,CAAC;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/IoRedisKvStore.d.ts b/packages/utils/dist/kvstores/IoRedisKvStore.d.ts deleted file mode 100644 index ade3003a..00000000 --- a/packages/utils/dist/kvstores/IoRedisKvStore.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { Redis as IoRedis } from 'ioredis'; -import type { KvStore } from './Types.js'; -import type { Upload } from '../models/index.js'; -export declare class IoRedisKvStore implements KvStore { - private redis; - private prefix; - constructor(redis: IoRedis, prefix?: string); - private prefixed; - get(key: string): Promise; - set(key: string, value: T): Promise; - delete(key: string): Promise; - list(): Promise>; - private serializeValue; - private deserializeValue; -} -//# sourceMappingURL=IoRedisKvStore.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/IoRedisKvStore.d.ts.map b/packages/utils/dist/kvstores/IoRedisKvStore.d.ts.map deleted file mode 100644 index ef9eca5c..00000000 --- a/packages/utils/dist/kvstores/IoRedisKvStore.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"IoRedisKvStore.d.ts","sourceRoot":"","sources":["../../src/kvstores/IoRedisKvStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,KAAK,IAAI,OAAO,EAAC,MAAM,SAAS,CAAA;AAC7C,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAA;AAE9C,qBAAa,cAAc,CAAC,CAAC,GAAG,MAAM,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;IAEzD,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,MAAM;gBADN,KAAK,EAAE,OAAO,EACd,MAAM,SAAK;IAMrB,OAAO,CAAC,QAAQ;IAIV,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAIxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAiBpC,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;CAGzB"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/IoRedisKvStore.js b/packages/utils/dist/kvstores/IoRedisKvStore.js deleted file mode 100644 index 0c0bb6dd..00000000 --- a/packages/utils/dist/kvstores/IoRedisKvStore.js +++ /dev/null @@ -1,40 +0,0 @@ -export class IoRedisKvStore { - redis; - prefix; - constructor(redis, prefix = '') { - this.redis = redis; - this.prefix = prefix; - this.redis = redis; - this.prefix = prefix; - } - prefixed(key) { - return `${this.prefix}${key}`; - } - async get(key) { - return this.deserializeValue(await this.redis.get(this.prefixed(key))); - } - async set(key, value) { - await this.redis.set(this.prefixed(key), this.serializeValue(value)); - } - async delete(key) { - await this.redis.del(this.prefixed(key)); - } - async list() { - const keys = new Set(); - let cursor = '0'; - do { - const [next, batch] = await this.redis.scan(cursor, 'MATCH', this.prefixed('*'), 'COUNT', '20'); - cursor = next; - for (const key of batch) - keys.add(key); - } while (cursor !== '0'); - return Array.from(keys); - } - serializeValue(value) { - return JSON.stringify(value); - } - deserializeValue(buffer) { - return buffer ? JSON.parse(buffer) : undefined; - } -} -//# sourceMappingURL=IoRedisKvStore.js.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/IoRedisKvStore.js.map b/packages/utils/dist/kvstores/IoRedisKvStore.js.map deleted file mode 100644 index 270d1589..00000000 --- a/packages/utils/dist/kvstores/IoRedisKvStore.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"IoRedisKvStore.js","sourceRoot":"","sources":["../../src/kvstores/IoRedisKvStore.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,cAAc;IAEf;IACA;IAFV,YACU,KAAc,EACd,SAAS,EAAE;QADX,UAAK,GAAL,KAAK,CAAS;QACd,WAAM,GAAN,MAAM,CAAK;QAEnB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAEO,QAAQ,CAAC,GAAW;QAC1B,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAA;IAC/B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IACxE,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAQ;QAC7B,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IACtE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;IAC1C,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;QAC9B,IAAI,MAAM,GAAG,GAAG,CAAA;QAChB,GAAG,CAAC;YACF,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CACzC,MAAM,EACN,OAAO,EACP,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAClB,OAAO,EACP,IAAI,CACL,CAAA;YACD,MAAM,GAAG,IAAI,CAAA;YACb,KAAK,MAAM,GAAG,IAAI,KAAK;gBAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACxC,CAAC,QAAQ,MAAM,KAAK,GAAG,EAAC;QACxB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAEO,cAAc,CAAC,KAAQ;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAEO,gBAAgB,CAAC,MAAqB;QAC5C,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAChD,CAAC;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/MemoryKvStore.d.ts b/packages/utils/dist/kvstores/MemoryKvStore.d.ts deleted file mode 100644 index 6ffc2ce2..00000000 --- a/packages/utils/dist/kvstores/MemoryKvStore.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { Upload } from '../models/index.js'; -import type { KvStore } from './Types.js'; -/** - * Memory based configstore. - * Used mostly for unit tests. - */ -export declare class MemoryKvStore implements KvStore { - data: Map; - get(key: string): Promise; - set(key: string, value: T): Promise; - delete(key: string): Promise; - list(): Promise>; -} -//# sourceMappingURL=MemoryKvStore.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/MemoryKvStore.d.ts.map b/packages/utils/dist/kvstores/MemoryKvStore.d.ts.map deleted file mode 100644 index cbd4e809..00000000 --- a/packages/utils/dist/kvstores/MemoryKvStore.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MemoryKvStore.d.ts","sourceRoot":"","sources":["../../src/kvstores/MemoryKvStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAA;AAC9C,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA;AAEvC;;;GAGG;AACH,qBAAa,aAAa,CAAC,CAAC,GAAG,MAAM,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;IAC1D,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAY;IAE1B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAIxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;CAGrC"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/MemoryKvStore.js b/packages/utils/dist/kvstores/MemoryKvStore.js deleted file mode 100644 index b54d23a3..00000000 --- a/packages/utils/dist/kvstores/MemoryKvStore.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Memory based configstore. - * Used mostly for unit tests. - */ -export class MemoryKvStore { - data = new Map(); - async get(key) { - return this.data.get(key); - } - async set(key, value) { - this.data.set(key, value); - } - async delete(key) { - this.data.delete(key); - } - async list() { - return [...this.data.keys()]; - } -} -//# sourceMappingURL=MemoryKvStore.js.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/MemoryKvStore.js.map b/packages/utils/dist/kvstores/MemoryKvStore.js.map deleted file mode 100644 index b860823a..00000000 --- a/packages/utils/dist/kvstores/MemoryKvStore.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MemoryKvStore.js","sourceRoot":"","sources":["../../src/kvstores/MemoryKvStore.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,OAAO,aAAa;IACxB,IAAI,GAAmB,IAAI,GAAG,EAAE,CAAA;IAEhC,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC3B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAQ;QAC7B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAC3B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IAC9B,CAAC;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/RedisKvStore.d.ts b/packages/utils/dist/kvstores/RedisKvStore.d.ts deleted file mode 100644 index 206640bb..00000000 --- a/packages/utils/dist/kvstores/RedisKvStore.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { RedisClientType } from '@redis/client'; -import type { KvStore } from './Types.js'; -import type { Upload } from '../models/index.js'; -/** - * Redis based configstore. - * - * @author Mitja Puzigaća - */ -export declare class RedisKvStore implements KvStore { - private redis; - private prefix; - constructor(redis: RedisClientType, prefix?: string); - get(key: string): Promise; - set(key: string, value: T): Promise; - delete(key: string): Promise; - list(): Promise>; - private serializeValue; - private deserializeValue; -} -//# sourceMappingURL=RedisKvStore.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/RedisKvStore.d.ts.map b/packages/utils/dist/kvstores/RedisKvStore.d.ts.map deleted file mode 100644 index 3612894c..00000000 --- a/packages/utils/dist/kvstores/RedisKvStore.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"RedisKvStore.d.ts","sourceRoot":"","sources":["../../src/kvstores/RedisKvStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,eAAe,CAAA;AAClD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAA;AAE9C;;;;GAIG;AACH,qBAAa,YAAY,CAAC,CAAC,GAAG,MAAM,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;IAEvD,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,MAAM;gBADN,KAAK,EAAE,eAAe,EACtB,MAAM,SAAK;IAMf,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAIxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAWpC,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;CAGzB"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/RedisKvStore.js b/packages/utils/dist/kvstores/RedisKvStore.js deleted file mode 100644 index 60736ccc..00000000 --- a/packages/utils/dist/kvstores/RedisKvStore.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Redis based configstore. - * - * @author Mitja Puzigaća - */ -export class RedisKvStore { - redis; - prefix; - constructor(redis, prefix = '') { - this.redis = redis; - this.prefix = prefix; - this.redis = redis; - this.prefix = prefix; - } - async get(key) { - return this.deserializeValue(await this.redis.get(this.prefix + key)); - } - async set(key, value) { - await this.redis.set(this.prefix + key, this.serializeValue(value)); - } - async delete(key) { - await this.redis.del(this.prefix + key); - } - async list() { - const keys = new Set(); - let cursor = 0; - do { - const result = await this.redis.scan(cursor, { MATCH: `${this.prefix}*`, COUNT: 20 }); - cursor = result.cursor; - for (const key of result.keys) - keys.add(key); - } while (cursor !== 0); - return Array.from(keys); - } - serializeValue(value) { - return JSON.stringify(value); - } - deserializeValue(buffer) { - return buffer ? JSON.parse(buffer) : undefined; - } -} -//# sourceMappingURL=RedisKvStore.js.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/RedisKvStore.js.map b/packages/utils/dist/kvstores/RedisKvStore.js.map deleted file mode 100644 index 1c00a519..00000000 --- a/packages/utils/dist/kvstores/RedisKvStore.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"RedisKvStore.js","sourceRoot":"","sources":["../../src/kvstores/RedisKvStore.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,OAAO,YAAY;IAEb;IACA;IAFV,YACU,KAAsB,EACtB,SAAS,EAAE;QADX,UAAK,GAAL,KAAK,CAAiB;QACtB,WAAM,GAAN,MAAM,CAAK;QAEnB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAA;IACvE,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAQ;QAC7B,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IACrE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAA;IACzC,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;QAC9B,IAAI,MAAM,GAAG,CAAC,CAAA;QACd,GAAG,CAAC;YACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAC,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,KAAK,EAAE,EAAE,EAAC,CAAC,CAAA;YACnF,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;YACtB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI;gBAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAC9C,CAAC,QAAQ,MAAM,KAAK,CAAC,EAAC;QACtB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAEO,cAAc,CAAC,KAAQ;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAEO,gBAAgB,CAAC,MAAqB;QAC5C,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAChD,CAAC;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/Types.d.ts b/packages/utils/dist/kvstores/Types.d.ts deleted file mode 100644 index 0bf84dc5..00000000 --- a/packages/utils/dist/kvstores/Types.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Upload } from '../models/index.js'; -export interface KvStore { - get(key: string): Promise; - set(key: string, value: T): Promise; - delete(key: string): Promise; - list?(): Promise>; -} -//# sourceMappingURL=Types.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/Types.d.ts.map b/packages/utils/dist/kvstores/Types.d.ts.map deleted file mode 100644 index f2a38457..00000000 --- a/packages/utils/dist/kvstores/Types.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Types.d.ts","sourceRoot":"","sources":["../../src/kvstores/Types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAA;AAE9C,MAAM,WAAW,OAAO,CAAC,CAAC,GAAG,MAAM;IACjC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;IACxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAElC,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;CAChC"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/Types.js b/packages/utils/dist/kvstores/Types.js deleted file mode 100644 index 40e8ff7b..00000000 --- a/packages/utils/dist/kvstores/Types.js +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=Types.js.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/Types.js.map b/packages/utils/dist/kvstores/Types.js.map deleted file mode 100644 index 435718d1..00000000 --- a/packages/utils/dist/kvstores/Types.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Types.js","sourceRoot":"","sources":["../../src/kvstores/Types.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/index.d.ts b/packages/utils/dist/kvstores/index.d.ts deleted file mode 100644 index 68d089a0..00000000 --- a/packages/utils/dist/kvstores/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { FileKvStore } from './FileKvStore.js'; -export { MemoryKvStore } from './MemoryKvStore.js'; -export { RedisKvStore } from './RedisKvStore.js'; -export { IoRedisKvStore } from './IoRedisKvStore.js'; -export { KvStore } from './Types.js'; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/index.d.ts.map b/packages/utils/dist/kvstores/index.d.ts.map deleted file mode 100644 index 023b811b..00000000 --- a/packages/utils/dist/kvstores/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/kvstores/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/kvstores/index.js b/packages/utils/dist/kvstores/index.js deleted file mode 100644 index 18f87975..00000000 --- a/packages/utils/dist/kvstores/index.js +++ /dev/null @@ -1,5 +0,0 @@ -export { FileKvStore } from './FileKvStore.js'; -export { MemoryKvStore } from './MemoryKvStore.js'; -export { RedisKvStore } from './RedisKvStore.js'; -export { IoRedisKvStore } from './IoRedisKvStore.js'; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/utils/dist/kvstores/index.js.map b/packages/utils/dist/kvstores/index.js.map deleted file mode 100644 index 39d9e3c0..00000000 --- a/packages/utils/dist/kvstores/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/kvstores/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/models/Context.d.ts b/packages/utils/dist/models/Context.d.ts deleted file mode 100644 index b3175a16..00000000 --- a/packages/utils/dist/models/Context.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * The CancellationContext interface provides mechanisms to manage the termination of a request. - * It is designed to handle two types of request terminations: immediate abortion and graceful cancellation. - * - * Properties: - * - signal: An instance of AbortSignal. It allows external entities to listen for cancellation requests, - * making it possible to react accordingly. - * - * Methods: - * - abort(): This function should be called to immediately terminate the request. It is intended for scenarios - * where the request cannot continue and needs to be stopped as soon as possible, such as due to upload errors - * or invalid conditions. Implementers should ensure that invoking this method leads to the swift cessation of all - * request-related operations to save resources. - * - * - cancel(): This function is used for more controlled termination of the request. It signals that the request should - * be concluded, but allows for a short period of time to finalize operations gracefully. This could involve - * completing current transactions or cleaning up resources. The exact behavior and the time allowed for cancellation - * completion are determined by the implementation, but the goal is to try to end the request without abrupt interruption, - * ensuring orderly shutdown of ongoing processes. - */ -export interface CancellationContext { - signal: AbortSignal; - abort: () => void; - cancel: () => void; -} -//# sourceMappingURL=Context.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/Context.d.ts.map b/packages/utils/dist/models/Context.d.ts.map deleted file mode 100644 index 36fbf799..00000000 --- a/packages/utils/dist/models/Context.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Context.d.ts","sourceRoot":"","sources":["../../src/models/Context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB"} \ No newline at end of file diff --git a/packages/utils/dist/models/Context.js b/packages/utils/dist/models/Context.js deleted file mode 100644 index 7f4b1d55..00000000 --- a/packages/utils/dist/models/Context.js +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=Context.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/Context.js.map b/packages/utils/dist/models/Context.js.map deleted file mode 100644 index 0526461c..00000000 --- a/packages/utils/dist/models/Context.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Context.js","sourceRoot":"","sources":["../../src/models/Context.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/utils/dist/models/DataStore.d.ts b/packages/utils/dist/models/DataStore.d.ts deleted file mode 100644 index c979c833..00000000 --- a/packages/utils/dist/models/DataStore.d.ts +++ /dev/null @@ -1,43 +0,0 @@ -import EventEmitter from 'node:events'; -import stream from 'node:stream'; -import { Upload } from './Upload.js'; -export declare class DataStore extends EventEmitter { - extensions: string[]; - hasExtension(extension: string): boolean; - /** - * Called in POST requests. This method just creates a - * file, implementing the creation extension. - * - * http://tus.io/protocols/resumable-upload.html#creation - */ - create(file: Upload): Promise; - /** - * Called in DELETE requests. This method just deletes the file from the store. - * http://tus.io/protocols/resumable-upload.html#termination - */ - remove(id: string): Promise; - /** - * Called in PATCH requests. This method should write data - * to the DataStore file, and possibly implement the - * concatenation extension. - * - * http://tus.io/protocols/resumable-upload.html#concatenation - */ - write(stream: stream.Readable, id: string, offset: number): Promise; - /** - * Called in HEAD requests. This method should return the bytes - * writen to the DataStore, for the client to know where to resume - * the upload. - */ - getUpload(id: string): Promise; - /** - * Called in PATCH requests when upload length is known after being defered. - */ - declareUploadLength(id: string, upload_length: number): Promise; - /** - * Returns number of expired uploads that were deleted. - */ - deleteExpired(): Promise; - getExpiration(): number; -} -//# sourceMappingURL=DataStore.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/DataStore.d.ts.map b/packages/utils/dist/models/DataStore.d.ts.map deleted file mode 100644 index a5972591..00000000 --- a/packages/utils/dist/models/DataStore.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"DataStore.d.ts","sourceRoot":"","sources":["../../src/models/DataStore.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAA;AACtC,OAAO,MAAM,MAAM,aAAa,CAAA;AAEhC,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAElC,qBAAa,SAAU,SAAQ,YAAY;IACzC,UAAU,EAAE,MAAM,EAAE,CAAK;IAEzB,YAAY,CAAC,SAAS,EAAE,MAAM;IAI9B;;;;;OAKG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM;IAIzB;;;OAGG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM;IAEvB;;;;;;OAMG;IACG,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAI/D;;;;OAIG;IACG,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAS5C;;OAEG;IACG,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM;IAE3D;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAItC,aAAa,IAAI,MAAM;CAGxB"} \ No newline at end of file diff --git a/packages/utils/dist/models/DataStore.js b/packages/utils/dist/models/DataStore.js deleted file mode 100644 index 4d1088c0..00000000 --- a/packages/utils/dist/models/DataStore.js +++ /dev/null @@ -1,59 +0,0 @@ -import EventEmitter from 'node:events'; -import { Upload } from './Upload.js'; -export class DataStore extends EventEmitter { - extensions = []; - hasExtension(extension) { - return this.extensions?.includes(extension); - } - /** - * Called in POST requests. This method just creates a - * file, implementing the creation extension. - * - * http://tus.io/protocols/resumable-upload.html#creation - */ - async create(file) { - return file; - } - /** - * Called in DELETE requests. This method just deletes the file from the store. - * http://tus.io/protocols/resumable-upload.html#termination - */ - async remove(id) { } - /** - * Called in PATCH requests. This method should write data - * to the DataStore file, and possibly implement the - * concatenation extension. - * - * http://tus.io/protocols/resumable-upload.html#concatenation - */ - async write(stream, id, offset) { - return 0; - } - /** - * Called in HEAD requests. This method should return the bytes - * writen to the DataStore, for the client to know where to resume - * the upload. - */ - async getUpload(id) { - return new Upload({ - id, - size: 0, - offset: 0, - storage: { type: 'datastore', path: '' }, - }); - } - /** - * Called in PATCH requests when upload length is known after being defered. - */ - async declareUploadLength(id, upload_length) { } - /** - * Returns number of expired uploads that were deleted. - */ - async deleteExpired() { - return 0; - } - getExpiration() { - return 0; - } -} -//# sourceMappingURL=DataStore.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/DataStore.js.map b/packages/utils/dist/models/DataStore.js.map deleted file mode 100644 index 682d5462..00000000 --- a/packages/utils/dist/models/DataStore.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"DataStore.js","sourceRoot":"","sources":["../../src/models/DataStore.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAA;AAGtC,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAElC,MAAM,OAAO,SAAU,SAAQ,YAAY;IACzC,UAAU,GAAa,EAAE,CAAA;IAEzB,YAAY,CAAC,SAAiB;QAC5B,OAAO,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAA;IAC7C,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,EAAU,IAAG,CAAC;IAE3B;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,CAAC,MAAuB,EAAE,EAAU,EAAE,MAAc;QAC7D,OAAO,CAAC,CAAA;IACV,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,SAAS,CAAC,EAAU;QACxB,OAAO,IAAI,MAAM,CAAC;YAChB,EAAE;YACF,IAAI,EAAE,CAAC;YACP,MAAM,EAAE,CAAC;YACT,OAAO,EAAE,EAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,EAAC;SACvC,CAAC,CAAA;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,mBAAmB,CAAC,EAAU,EAAE,aAAqB,IAAG,CAAC;IAE/D;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,OAAO,CAAC,CAAA;IACV,CAAC;IAED,aAAa;QACX,OAAO,CAAC,CAAA;IACV,CAAC;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/models/Locker.d.ts b/packages/utils/dist/models/Locker.d.ts deleted file mode 100644 index 560d98dc..00000000 --- a/packages/utils/dist/models/Locker.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -export type RequestRelease = () => Promise | void; -/** - * The Locker interface creates a Lock instance for a given resource identifier. - */ -export interface Locker { - newLock(id: string): Lock; -} -/** - * The Lock interface defines methods for implementing a locking mechanism. - * It is primarily used to ensure exclusive access to resources, such as uploads and their metadata. - * - * The interface adheres to TUS protocol recommendations, emphasizing the need to prevent prolonged lock retention. - * This approach helps manage resources efficiently and avoids issues with half-open TCP connections. - * - * Methods: - * - lock(id, cancelReq): Acquires a lock on a resource identified by 'id'. If the lock is already held by another request, - * the 'cancelReq' callback is provided to signal the current lock holder to release the lock. - * The 'cancelReq' callback should be invoked when there's an attempt by another request to acquire a previously locked resource. - * This mechanism ensures that locks are held only as long as necessary and are promptly released for other requests. - * - * - unlock(id): Releases the lock held on the resource identified by 'id'. This should be called by the lock holder - * after completing their operation or upon receiving a signal through the 'cancelReq' callback from a subsequent request - * attempting to acquire the lock. - * - */ -export interface Lock { - lock(signal: AbortSignal, cancelReq: RequestRelease): Promise; - unlock(): Promise; -} -//# sourceMappingURL=Locker.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/Locker.d.ts.map b/packages/utils/dist/models/Locker.d.ts.map deleted file mode 100644 index bd0a14ea..00000000 --- a/packages/utils/dist/models/Locker.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Locker.d.ts","sourceRoot":"","sources":["../../src/models/Locker.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;AAEvD;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,IAAI;IACnB,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACxB"} \ No newline at end of file diff --git a/packages/utils/dist/models/Locker.js b/packages/utils/dist/models/Locker.js deleted file mode 100644 index 93a9c26a..00000000 --- a/packages/utils/dist/models/Locker.js +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=Locker.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/Locker.js.map b/packages/utils/dist/models/Locker.js.map deleted file mode 100644 index 8a10f8f9..00000000 --- a/packages/utils/dist/models/Locker.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Locker.js","sourceRoot":"","sources":["../../src/models/Locker.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/utils/dist/models/Metadata.d.ts b/packages/utils/dist/models/Metadata.d.ts deleted file mode 100644 index c408f8bb..00000000 --- a/packages/utils/dist/models/Metadata.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { Upload } from './Upload.js'; -export declare function validateKey(key: string): boolean; -export declare function validateValue(value: string): boolean; -export declare function parse(str?: string): Record; -export declare function stringify(metadata: NonNullable): string; -//# sourceMappingURL=Metadata.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/Metadata.d.ts.map b/packages/utils/dist/models/Metadata.d.ts.map deleted file mode 100644 index ad519e91..00000000 --- a/packages/utils/dist/models/Metadata.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Metadata.d.ts","sourceRoot":"","sources":["../../src/models/Metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAMvC,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,WAiBtC;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,WAM1C;AAED,wBAAgB,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,iCAuBjC;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,MAAM,CAW3E"} \ No newline at end of file diff --git a/packages/utils/dist/models/Metadata.js b/packages/utils/dist/models/Metadata.js deleted file mode 100644 index e0aadfb0..00000000 --- a/packages/utils/dist/models/Metadata.js +++ /dev/null @@ -1,55 +0,0 @@ -const ASCII_SPACE = ' '.codePointAt(0); -const ASCII_COMMA = ','.codePointAt(0); -const BASE64_REGEX = /^[\d+/A-Za-z]*={0,2}$/; -export function validateKey(key) { - if (key.length === 0) { - return false; - } - for (let i = 0; i < key.length; ++i) { - const charCodePoint = key.codePointAt(i); - if (charCodePoint > 127 || - charCodePoint === ASCII_SPACE || - charCodePoint === ASCII_COMMA) { - return false; - } - } - return true; -} -export function validateValue(value) { - if (value.length % 4 !== 0) { - return false; - } - return BASE64_REGEX.test(value); -} -export function parse(str) { - const meta = {}; - if (!str || str.trim().length === 0) { - throw new Error('Metadata string is not valid'); - } - for (const pair of str.split(',')) { - const tokens = pair.split(' '); - const [key, value] = tokens; - if (((tokens.length === 1 && validateKey(key)) || - (tokens.length === 2 && validateKey(key) && validateValue(value))) && - !(key in meta)) { - const decodedValue = value ? Buffer.from(value, 'base64').toString('utf8') : null; - meta[key] = decodedValue; - } - else { - throw new Error('Metadata string is not valid'); - } - } - return meta; -} -export function stringify(metadata) { - return Object.entries(metadata) - .map(([key, value]) => { - if (value === null) { - return key; - } - const encodedValue = Buffer.from(value, 'utf8').toString('base64'); - return `${key} ${encodedValue}`; - }) - .join(','); -} -//# sourceMappingURL=Metadata.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/Metadata.js.map b/packages/utils/dist/models/Metadata.js.map deleted file mode 100644 index 26e57979..00000000 --- a/packages/utils/dist/models/Metadata.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Metadata.js","sourceRoot":"","sources":["../../src/models/Metadata.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AACtC,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AACtC,MAAM,YAAY,GAAG,uBAAuB,CAAA;AAE5C,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;QACpC,MAAM,aAAa,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAW,CAAA;QAClD,IACE,aAAa,GAAG,GAAG;YACnB,aAAa,KAAK,WAAW;YAC7B,aAAa,KAAK,WAAW,EAC7B,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACjC,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAY;IAChC,MAAM,IAAI,GAAkC,EAAE,CAAA;IAE9C,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;IACjD,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAC9B,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,MAAM,CAAA;QAC3B,IACE,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;YACxC,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;YACpE,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,EACd,CAAC;YACD,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;YACjF,IAAI,CAAC,GAAG,CAAC,GAAG,YAAY,CAAA;QAC1B,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;QACjD,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAyC;IACjE,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;SAC5B,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACpB,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,GAAG,CAAA;QACZ,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QAClE,OAAO,GAAG,GAAG,IAAI,YAAY,EAAE,CAAA;IACjC,CAAC,CAAC;SACD,IAAI,CAAC,GAAG,CAAC,CAAA;AACd,CAAC"} \ No newline at end of file diff --git a/packages/utils/dist/models/StreamLimiter.d.ts b/packages/utils/dist/models/StreamLimiter.d.ts deleted file mode 100644 index 968f9091..00000000 --- a/packages/utils/dist/models/StreamLimiter.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Transform, type TransformCallback } from 'node:stream'; -export declare class MaxFileExceededError extends Error { - status_code: number; - body: string; - constructor(); -} -export declare class StreamLimiter extends Transform { - private maxSize; - private currentSize; - constructor(maxSize: number); - _transform(chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback): void; -} -//# sourceMappingURL=StreamLimiter.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/StreamLimiter.d.ts.map b/packages/utils/dist/models/StreamLimiter.d.ts.map deleted file mode 100644 index 706ec40f..00000000 --- a/packages/utils/dist/models/StreamLimiter.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"StreamLimiter.d.ts","sourceRoot":"","sources":["../../src/models/StreamLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,KAAK,iBAAiB,EAAC,MAAM,aAAa,CAAA;AAI7D,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;;CAQb;AAED,qBAAa,aAAc,SAAQ,SAAS;IAC1C,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,WAAW,CAAI;gBAEX,OAAO,EAAE,MAAM;IAK3B,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI;CAQvF"} \ No newline at end of file diff --git a/packages/utils/dist/models/StreamLimiter.js b/packages/utils/dist/models/StreamLimiter.js deleted file mode 100644 index e2575f9d..00000000 --- a/packages/utils/dist/models/StreamLimiter.js +++ /dev/null @@ -1,31 +0,0 @@ -import { Transform } from 'node:stream'; -import { ERRORS } from '../constants.js'; -// TODO: create HttpError and use it everywhere instead of throwing objects -export class MaxFileExceededError extends Error { - status_code; - body; - constructor() { - super(ERRORS.ERR_MAX_SIZE_EXCEEDED.body); - this.status_code = ERRORS.ERR_MAX_SIZE_EXCEEDED.status_code; - this.body = ERRORS.ERR_MAX_SIZE_EXCEEDED.body; - Object.setPrototypeOf(this, MaxFileExceededError.prototype); - } -} -export class StreamLimiter extends Transform { - maxSize; - currentSize = 0; - constructor(maxSize) { - super(); - this.maxSize = maxSize; - } - _transform(chunk, encoding, callback) { - this.currentSize += chunk.length; - if (this.currentSize > this.maxSize) { - callback(new MaxFileExceededError()); - } - else { - callback(null, chunk); - } - } -} -//# sourceMappingURL=StreamLimiter.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/StreamLimiter.js.map b/packages/utils/dist/models/StreamLimiter.js.map deleted file mode 100644 index cee6985d..00000000 --- a/packages/utils/dist/models/StreamLimiter.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"StreamLimiter.js","sourceRoot":"","sources":["../../src/models/StreamLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAyB,MAAM,aAAa,CAAA;AAC7D,OAAO,EAAC,MAAM,EAAC,MAAM,iBAAiB,CAAA;AAEtC,2EAA2E;AAC3E,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,WAAW,CAAQ;IACnB,IAAI,CAAQ;IAEZ;QACE,KAAK,CAAC,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAA;QACxC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,qBAAqB,CAAC,WAAW,CAAA;QAC3D,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAA;QAC7C,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAA;IAC7D,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,SAAS;IAClC,OAAO,CAAQ;IACf,WAAW,GAAG,CAAC,CAAA;IAEvB,YAAY,OAAe;QACzB,KAAK,EAAE,CAAA;QACP,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,UAAU,CAAC,KAAa,EAAE,QAAwB,EAAE,QAA2B;QAC7E,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,MAAM,CAAA;QAChC,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YACpC,QAAQ,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAA;QACtC,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QACvB,CAAC;IACH,CAAC;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/models/StreamSplitter.d.ts b/packages/utils/dist/models/StreamSplitter.d.ts deleted file mode 100644 index b480e790..00000000 --- a/packages/utils/dist/models/StreamSplitter.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -import fs from 'node:fs/promises'; -import stream from 'node:stream'; -type Options = { - chunkSize: number; - directory: string; -}; -type Callback = (error: Error | null) => void; -export declare class StreamSplitter extends stream.Writable { - directory: Options['directory']; - currentChunkPath: string | null; - currentChunkSize: number; - fileHandle: fs.FileHandle | null; - filenameTemplate: string; - chunkSize: Options['chunkSize']; - part: number; - constructor({ chunkSize, directory }: Options, options?: stream.WritableOptions); - _write(chunk: Buffer, _: BufferEncoding, callback: Callback): Promise; - _final(callback: Callback): Promise; - _writeChunk(chunk: Buffer): Promise; - _handleError(): Promise; - _finishChunk(): Promise; - emitEvent(name: string, payload: T): Promise; - _newChunk(): Promise; -} -export {}; -//# sourceMappingURL=StreamSplitter.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/StreamSplitter.d.ts.map b/packages/utils/dist/models/StreamSplitter.d.ts.map deleted file mode 100644 index 405a75af..00000000 --- a/packages/utils/dist/models/StreamSplitter.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"StreamSplitter.d.ts","sourceRoot":"","sources":["../../src/models/StreamSplitter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAEjC,OAAO,MAAM,MAAM,aAAa,CAAA;AAMhC,KAAK,OAAO,GAAG;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAA;AAE7C,qBAAa,cAAe,SAAQ,MAAM,CAAC,QAAQ;IACjD,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC/B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,IAAI,CAAA;IAChC,gBAAgB,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC/B,IAAI,EAAE,MAAM,CAAA;gBAEA,EAAC,SAAS,EAAE,SAAS,EAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,eAAe;IAavE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ;IA+B3D,MAAM,CAAC,QAAQ,EAAE,QAAQ;IAczB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzC,YAAY;IAcZ,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB7B,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAOrC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAajC"} \ No newline at end of file diff --git a/packages/utils/dist/models/StreamSplitter.js b/packages/utils/dist/models/StreamSplitter.js deleted file mode 100644 index 76bd548c..00000000 --- a/packages/utils/dist/models/StreamSplitter.js +++ /dev/null @@ -1,114 +0,0 @@ -/* global BufferEncoding */ -import crypto from 'node:crypto'; -import fs from 'node:fs/promises'; -import path from 'node:path'; -import stream from 'node:stream'; -function randomString(size) { - return crypto.randomBytes(size).toString('base64url').slice(0, size); -} -export class StreamSplitter extends stream.Writable { - directory; - currentChunkPath; - currentChunkSize; - fileHandle; - filenameTemplate; - chunkSize; - part; - constructor({ chunkSize, directory }, options) { - super(options); - this.chunkSize = chunkSize; - this.currentChunkPath = null; - this.currentChunkSize = 0; - this.fileHandle = null; - this.directory = directory; - this.filenameTemplate = randomString(10); - this.part = 0; - this.on('error', this._handleError.bind(this)); - } - async _write(chunk, _, callback) { - try { - // In order to start writing a chunk, we must first create - // a file system reference for it - if (this.fileHandle === null) { - await this._newChunk(); - } - let overflow = this.currentChunkSize + chunk.length - this.chunkSize; - // The current chunk will be more than our defined part size if we would - // write all of it to disk. - while (overflow > 0) { - // Only write to disk the up to our defined part size. - await this._writeChunk(chunk.subarray(0, chunk.length - overflow)); - await this._finishChunk(); - // We still have some overflow left, so we write it to a new chunk. - await this._newChunk(); - chunk = chunk.subarray(chunk.length - overflow, chunk.length); - overflow = this.currentChunkSize + chunk.length - this.chunkSize; - } - // The chunk is smaller than our defined part size so we can just write it to disk. - await this._writeChunk(chunk); - callback(null); - } - catch (error) { - callback(error); - } - } - async _final(callback) { - if (this.fileHandle === null) { - callback(null); - return; - } - try { - await this._finishChunk(); - callback(null); - } - catch (error) { - callback(error); - } - } - async _writeChunk(chunk) { - await fs.appendFile(this.fileHandle, chunk); - this.currentChunkSize += chunk.length; - } - async _handleError() { - await this.emitEvent('chunkError', this.currentChunkPath); - // If there was an error, we want to stop allowing to write on disk as we cannot advance further. - // At this point the chunk might be incomplete advancing further might cause data loss. - // some scenarios where this might happen is if the disk is full or if we abort the stream midway. - if (this.fileHandle === null) { - return; - } - await this.fileHandle.close(); - this.currentChunkPath = null; - this.fileHandle = null; - } - async _finishChunk() { - if (this.fileHandle === null) { - return; - } - await this.fileHandle.close(); - await this.emitEvent('chunkFinished', { - path: this.currentChunkPath, - size: this.currentChunkSize, - }); - this.currentChunkPath = null; - this.fileHandle = null; - this.currentChunkSize = 0; - this.part += 1; - } - async emitEvent(name, payload) { - const listeners = this.listeners(name); - for (const listener of listeners) { - await listener(payload); - } - } - async _newChunk() { - const currentChunkPath = path.join(this.directory, `${this.filenameTemplate}-${this.part}`); - await this.emitEvent('beforeChunkStarted', currentChunkPath); - this.currentChunkPath = currentChunkPath; - const fileHandle = await fs.open(this.currentChunkPath, 'w'); - await this.emitEvent('chunkStarted', this.currentChunkPath); - this.currentChunkSize = 0; - this.fileHandle = fileHandle; - } -} -//# sourceMappingURL=StreamSplitter.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/StreamSplitter.js.map b/packages/utils/dist/models/StreamSplitter.js.map deleted file mode 100644 index d52cb112..00000000 --- a/packages/utils/dist/models/StreamSplitter.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"StreamSplitter.js","sourceRoot":"","sources":["../../src/models/StreamSplitter.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/utils/dist/models/Uid.d.ts b/packages/utils/dist/models/Uid.d.ts deleted file mode 100644 index 6e80bd97..00000000 --- a/packages/utils/dist/models/Uid.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export declare const Uid: { - rand(): string; -}; -//# sourceMappingURL=Uid.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/Uid.d.ts.map b/packages/utils/dist/models/Uid.d.ts.map deleted file mode 100644 index 88361885..00000000 --- a/packages/utils/dist/models/Uid.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Uid.d.ts","sourceRoot":"","sources":["../../src/models/Uid.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,GAAG;;CAIf,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/models/Uid.js b/packages/utils/dist/models/Uid.js deleted file mode 100644 index 1de5406b..00000000 --- a/packages/utils/dist/models/Uid.js +++ /dev/null @@ -1,7 +0,0 @@ -import crypto from 'node:crypto'; -export const Uid = { - rand() { - return crypto.randomBytes(16).toString('hex'); - }, -}; -//# sourceMappingURL=Uid.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/Uid.js.map b/packages/utils/dist/models/Uid.js.map deleted file mode 100644 index 791c410d..00000000 --- a/packages/utils/dist/models/Uid.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Uid.js","sourceRoot":"","sources":["../../src/models/Uid.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAEhC,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,IAAI;QACF,OAAO,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC/C,CAAC;CACF,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/models/Upload.d.ts b/packages/utils/dist/models/Upload.d.ts deleted file mode 100644 index a1b4c210..00000000 --- a/packages/utils/dist/models/Upload.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -type TUpload = { - id: string; - size?: number; - offset: number; - metadata?: Record; - storage?: { - type: string; - path: string; - bucket?: string; - }; - creation_date?: string; -}; -export declare class Upload { - id: TUpload['id']; - metadata: TUpload['metadata']; - size: TUpload['size']; - offset: TUpload['offset']; - creation_date: TUpload['creation_date']; - storage: TUpload['storage']; - constructor(upload: TUpload); - get sizeIsDeferred(): boolean; -} -export {}; -//# sourceMappingURL=Upload.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/Upload.d.ts.map b/packages/utils/dist/models/Upload.d.ts.map deleted file mode 100644 index ed78ebd9..00000000 --- a/packages/utils/dist/models/Upload.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Upload.d.ts","sourceRoot":"","sources":["../../src/models/Upload.ts"],"names":[],"mappings":"AAAA,KAAK,OAAO,GAAG;IACb,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAA;IACxC,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,qBAAa,MAAM;IACjB,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;IAC7B,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACrB,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IACzB,aAAa,EAAE,OAAO,CAAC,eAAe,CAAC,CAAA;IACvC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;gBAEf,MAAM,EAAE,OAAO;IAc3B,IAAI,cAAc,IAAI,OAAO,CAE5B;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/models/Upload.js b/packages/utils/dist/models/Upload.js deleted file mode 100644 index ceb92ca5..00000000 --- a/packages/utils/dist/models/Upload.js +++ /dev/null @@ -1,23 +0,0 @@ -export class Upload { - id; - metadata; - size; - offset; - creation_date; - storage; - constructor(upload) { - if (!upload.id) { - throw new Error('[File] constructor must be given an ID'); - } - this.id = upload.id; - this.size = upload.size; - this.offset = upload.offset; - this.metadata = upload.metadata; - this.storage = upload.storage; - this.creation_date = upload.creation_date ?? new Date().toISOString(); - } - get sizeIsDeferred() { - return this.size === undefined; - } -} -//# sourceMappingURL=Upload.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/Upload.js.map b/packages/utils/dist/models/Upload.js.map deleted file mode 100644 index 72b3f1f4..00000000 --- a/packages/utils/dist/models/Upload.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Upload.js","sourceRoot":"","sources":["../../src/models/Upload.ts"],"names":[],"mappings":"AAaA,MAAM,OAAO,MAAM;IACjB,EAAE,CAAe;IACjB,QAAQ,CAAqB;IAC7B,IAAI,CAAiB;IACrB,MAAM,CAAmB;IACzB,aAAa,CAA0B;IACvC,OAAO,CAAoB;IAE3B,YAAY,MAAe;QACzB,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QAC3D,CAAC;QAED,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAA;QACnB,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;QAC3B,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;QAC/B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;QAE7B,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IACvE,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,CAAA;IAChC,CAAC;CACF"} \ No newline at end of file diff --git a/packages/utils/dist/models/index.d.ts b/packages/utils/dist/models/index.d.ts deleted file mode 100644 index 4d4ff440..00000000 --- a/packages/utils/dist/models/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export { DataStore } from './DataStore.js'; -export * as Metadata from './Metadata.js'; -export { StreamSplitter } from './StreamSplitter.js'; -export { StreamLimiter } from './StreamLimiter.js'; -export { Uid } from './Uid.js'; -export { Upload } from './Upload.js'; -export { Locker, Lock, RequestRelease } from './Locker.js'; -export { CancellationContext } from './Context.js'; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/models/index.d.ts.map b/packages/utils/dist/models/index.d.ts.map deleted file mode 100644 index e948033b..00000000 --- a/packages/utils/dist/models/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAA;AACxC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAC,GAAG,EAAC,MAAM,UAAU,CAAA;AAC5B,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAClC,OAAO,EAAC,MAAM,EAAE,IAAI,EAAE,cAAc,EAAC,MAAM,aAAa,CAAA;AACxD,OAAO,EAAC,mBAAmB,EAAC,MAAM,cAAc,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/models/index.js b/packages/utils/dist/models/index.js deleted file mode 100644 index 02dac6a7..00000000 --- a/packages/utils/dist/models/index.js +++ /dev/null @@ -1,7 +0,0 @@ -export { DataStore } from './DataStore.js'; -export * as Metadata from './Metadata.js'; -export { StreamSplitter } from './StreamSplitter.js'; -export { StreamLimiter } from './StreamLimiter.js'; -export { Uid } from './Uid.js'; -export { Upload } from './Upload.js'; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/utils/dist/models/index.js.map b/packages/utils/dist/models/index.js.map deleted file mode 100644 index fed8cf01..00000000 --- a/packages/utils/dist/models/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAA;AACxC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAC,GAAG,EAAC,MAAM,UAAU,CAAA;AAC5B,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/test/Metadata.test.d.ts b/packages/utils/dist/test/Metadata.test.d.ts deleted file mode 100644 index ca0a1d4a..00000000 --- a/packages/utils/dist/test/Metadata.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=Metadata.test.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/test/Metadata.test.d.ts.map b/packages/utils/dist/test/Metadata.test.d.ts.map deleted file mode 100644 index 3db6b19f..00000000 --- a/packages/utils/dist/test/Metadata.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Metadata.test.d.ts","sourceRoot":"","sources":["../../src/test/Metadata.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/utils/dist/test/Metadata.test.js b/packages/utils/dist/test/Metadata.test.js deleted file mode 100644 index 0c061231..00000000 --- a/packages/utils/dist/test/Metadata.test.js +++ /dev/null @@ -1,108 +0,0 @@ -import { strict as assert } from 'node:assert'; -import { parse, stringify } from '../models/Metadata.js'; -describe('Metadata', () => { - it('parse valid metadata string', () => { - const str = 'file/name dGVzdC5tcDQ=,size OTYwMjQ0,type! dmlkZW8vbXA0,video,withWhitespace '; - const obj = { - 'file/name': 'test.mp4', - size: '960244', - 'type!': 'video/mp4', - video: null, - withWhitespace: null, - }; - const decoded = parse(str); - assert.deepStrictEqual(decoded, obj); - }); - it('check length of metadata string', () => { - const obj = { - filename: 'test.mp4', - size: '960244', - type: 'video/mp4', - video: null, - withWhitespace: null, - }; - const encoded = stringify(obj); - assert.strictEqual(encoded.split(',').length, Object.entries(obj).length); - }); - it('verify metadata stringification', () => { - assert.strictEqual(stringify({ filename: 'test.mp4' }), 'filename dGVzdC5tcDQ='); - assert.strictEqual(stringify({ size: '960244' }), 'size OTYwMjQ0'); - assert.strictEqual(stringify({ type: 'video/mp4' }), 'type dmlkZW8vbXA0'); - // Multiple valid options - assert.notStrictEqual(['video', 'video '].indexOf(stringify({ video: null })), -1); - assert.notStrictEqual(['withWhitespace', 'withWhitespace '].indexOf(stringify({ withWhitespace: null })), -1); - }); - it('verify metadata parsing', () => { - assert.deepStrictEqual(parse('filename dGVzdC5tcDQ='), { - filename: 'test.mp4', - }); - assert.deepStrictEqual(parse('size OTYwMjQ0'), { size: '960244' }); - assert.deepStrictEqual(parse('type dmlkZW8vbXA0'), { - type: 'video/mp4', - }); - assert.deepStrictEqual(parse('video'), { video: null }); - assert.deepStrictEqual(parse('video '), { video: null }); - assert.deepStrictEqual(parse('withWhitespace'), { - withWhitespace: null, - }); - assert.deepStrictEqual(parse('withWhitespace '), { - withWhitespace: null, - }); - }); - it('cyclic test', () => { - const obj = { - filename: 'world_domination_plan.pdf', - is_confidential: null, - }; - // Object -> string -> object - assert.deepStrictEqual(parse(stringify(obj)), obj); - }); - describe('verify invalid metadata string', () => { - it('duplicate keys', () => { - assert.throws(() => { - parse('filename dGVzdC5tcDQ=, filename cGFja2FnZS5qc29u'); - }); - assert.throws(() => { - parse('video ,video dHJ1ZQ=='); - }); - assert.throws(() => { - parse('size,size '); - }); - assert.throws(() => { - parse(''); - }); - assert.throws(() => { - parse('\t\n'); - }); - }); - it('invalid key', () => { - assert.throws(() => { - parse('🦁 ZW1vamk='); - }); - assert.throws(() => { - parse('€¢ß'); - }); - assert.throws(() => { - parse('test, te st '); - }); - assert.throws(() => { - parse('test,,test'); - }); - }); - it('invalid base64 value', () => { - assert.throws(() => { - parse('key ZW1vamk'); - }); // Value is not a multiple of 4 characters - assert.throws(() => { - parse('key invalid-base64=='); - }); - assert.throws(() => { - parse('key =ZW1vamk'); - }); // Padding can not be at the beginning - assert.throws(() => { - parse('key '); - }); // Only single whitespace is allowed - }); - }); -}); -//# sourceMappingURL=Metadata.test.js.map \ No newline at end of file diff --git a/packages/utils/dist/test/Metadata.test.js.map b/packages/utils/dist/test/Metadata.test.js.map deleted file mode 100644 index f253fc7b..00000000 --- a/packages/utils/dist/test/Metadata.test.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Metadata.test.js","sourceRoot":"","sources":["../../src/test/Metadata.test.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/utils/dist/test/StreamSplitter.test.d.ts b/packages/utils/dist/test/StreamSplitter.test.d.ts deleted file mode 100644 index 02f563f2..00000000 --- a/packages/utils/dist/test/StreamSplitter.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=StreamSplitter.test.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/test/StreamSplitter.test.d.ts.map b/packages/utils/dist/test/StreamSplitter.test.d.ts.map deleted file mode 100644 index 833b2f3f..00000000 --- a/packages/utils/dist/test/StreamSplitter.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"StreamSplitter.test.d.ts","sourceRoot":"","sources":["../../src/test/StreamSplitter.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/utils/dist/test/StreamSplitter.test.js b/packages/utils/dist/test/StreamSplitter.test.js deleted file mode 100644 index 0e52514b..00000000 --- a/packages/utils/dist/test/StreamSplitter.test.js +++ /dev/null @@ -1,47 +0,0 @@ -import os from 'node:os'; -import fs from 'node:fs'; -import stream from 'node:stream/promises'; -import { strict as assert } from 'node:assert'; -import { StreamSplitter } from '../models/index.js'; -import { Readable } from 'node:stream'; -const fileSize = 20_971_520; -describe('StreamSplitter', () => { - it('should buffer chunks until optimal part size', async () => { - const readStream = fs.createReadStream('../../test/fixtures/test.pdf'); - const optimalChunkSize = 8 * 1024 * 1024; - const parts = [optimalChunkSize, optimalChunkSize, fileSize - optimalChunkSize * 2]; - let offset = 0; - let index = 0; - const splitterStream = new StreamSplitter({ - chunkSize: optimalChunkSize, - directory: os.tmpdir(), - }).on('chunkFinished', ({ size }) => { - offset += size; - assert.equal(parts[index], size); - index++; - }); - await stream.pipeline(readStream, splitterStream); - assert.equal(offset, fileSize); - }); - it('should split to multiple chunks when single buffer exceeds chunk size', async () => { - const optimalChunkSize = 1024; - const expectedChunks = 7; - const readStream = Readable.from([Buffer.alloc(expectedChunks * optimalChunkSize)]); - let chunksStarted = 0; - let chunksFinished = 0; - const splitterStream = new StreamSplitter({ - chunkSize: optimalChunkSize, - directory: os.tmpdir(), - }) - .on('chunkStarted', () => { - chunksStarted++; - }) - .on('chunkFinished', () => { - chunksFinished++; - }); - await stream.pipeline(readStream, splitterStream); - assert.equal(chunksStarted, expectedChunks); - assert.equal(chunksFinished, expectedChunks); - }); -}); -//# sourceMappingURL=StreamSplitter.test.js.map \ No newline at end of file diff --git a/packages/utils/dist/test/StreamSplitter.test.js.map b/packages/utils/dist/test/StreamSplitter.test.js.map deleted file mode 100644 index de0b6d47..00000000 --- a/packages/utils/dist/test/StreamSplitter.test.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"StreamSplitter.test.js","sourceRoot":"","sources":["../../src/test/StreamSplitter.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,MAAM,MAAM,sBAAsB,CAAA;AACzC,OAAO,EAAC,MAAM,IAAI,MAAM,EAAC,MAAM,aAAa,CAAA;AAE5C,OAAO,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAA;AAEpC,MAAM,QAAQ,GAAG,UAAU,CAAA;AAE3B,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,UAAU,GAAG,EAAE,CAAC,gBAAgB,CAAC,8BAA8B,CAAC,CAAA;QACtE,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA;QACxC,MAAM,KAAK,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,QAAQ,GAAG,gBAAgB,GAAG,CAAC,CAAC,CAAA;QACnF,IAAI,MAAM,GAAG,CAAC,CAAA;QACd,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC;YACxC,SAAS,EAAE,gBAAgB;YAC3B,SAAS,EAAE,EAAE,CAAC,MAAM,EAAE;SACvB,CAAC,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,EAAC,IAAI,EAAC,EAAE,EAAE;YAChC,MAAM,IAAI,IAAI,CAAA;YACd,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAA;YAChC,KAAK,EAAE,CAAA;QACT,CAAC,CAAC,CAAA;QACF,MAAM,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;QACjD,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAChC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,gBAAgB,GAAG,IAAI,CAAA;QAC7B,MAAM,cAAc,GAAG,CAAC,CAAA;QAExB,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAA;QAEnF,IAAI,aAAa,GAAG,CAAC,CAAA;QACrB,IAAI,cAAc,GAAG,CAAC,CAAA;QACtB,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC;YACxC,SAAS,EAAE,gBAAgB;YAC3B,SAAS,EAAE,EAAE,CAAC,MAAM,EAAE;SACvB,CAAC;aACC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;YACvB,aAAa,EAAE,CAAA;QACjB,CAAC,CAAC;aACD,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACxB,cAAc,EAAE,CAAA;QAClB,CAAC,CAAC,CAAA;QAEJ,MAAM,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;QAEjD,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,cAAc,CAAC,CAAA;QAC3C,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,cAAc,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/test/Uid.test.d.ts b/packages/utils/dist/test/Uid.test.d.ts deleted file mode 100644 index 6d5eceac..00000000 --- a/packages/utils/dist/test/Uid.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=Uid.test.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/test/Uid.test.d.ts.map b/packages/utils/dist/test/Uid.test.d.ts.map deleted file mode 100644 index 9978e438..00000000 --- a/packages/utils/dist/test/Uid.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Uid.test.d.ts","sourceRoot":"","sources":["../../src/test/Uid.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/packages/utils/dist/test/Uid.test.js b/packages/utils/dist/test/Uid.test.js deleted file mode 100644 index f90ee5c7..00000000 --- a/packages/utils/dist/test/Uid.test.js +++ /dev/null @@ -1,20 +0,0 @@ -import { strict as assert } from 'node:assert'; -import { Uid } from '../models/index.js'; -describe('Uid', () => { - it('returns a 32 char string', (done) => { - const id = Uid.rand(); - assert.equal(typeof id, 'string'); - assert.equal(id.length, 32); - done(); - }); - it('returns a different string every time', (done) => { - const ids = {}; - for (let i = 0; i < 16; i++) { - const id = Uid.rand(); - assert(!ids[id], 'id was encountered multiple times'); - ids[id] = true; - } - done(); - }); -}); -//# sourceMappingURL=Uid.test.js.map \ No newline at end of file diff --git a/packages/utils/dist/test/Uid.test.js.map b/packages/utils/dist/test/Uid.test.js.map deleted file mode 100644 index deeae000..00000000 --- a/packages/utils/dist/test/Uid.test.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Uid.test.js","sourceRoot":"","sources":["../../src/test/Uid.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,IAAI,MAAM,EAAC,MAAM,aAAa,CAAA;AAE5C,OAAO,EAAC,GAAG,EAAC,MAAM,oBAAoB,CAAA;AAEtC,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE;IACnB,EAAE,CAAC,0BAA0B,EAAE,CAAC,IAAI,EAAE,EAAE;QACtC,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;QACrB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAA;QACjC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;QAC3B,IAAI,EAAE,CAAA;IACR,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uCAAuC,EAAE,CAAC,IAAI,EAAE,EAAE;QACnD,MAAM,GAAG,GAA4B,EAAE,CAAA;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;YACrB,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,mCAAmC,CAAC,CAAA;YACrD,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAA;QAChB,CAAC;QAED,IAAI,EAAE,CAAA;IACR,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/test/Upload.test.d.ts b/packages/utils/dist/test/Upload.test.d.ts deleted file mode 100644 index 0e059028..00000000 --- a/packages/utils/dist/test/Upload.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import 'should'; -//# sourceMappingURL=Upload.test.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/test/Upload.test.d.ts.map b/packages/utils/dist/test/Upload.test.d.ts.map deleted file mode 100644 index d4e30c89..00000000 --- a/packages/utils/dist/test/Upload.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Upload.test.d.ts","sourceRoot":"","sources":["../../src/test/Upload.test.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/test/Upload.test.js b/packages/utils/dist/test/Upload.test.js deleted file mode 100644 index 4b6de604..00000000 --- a/packages/utils/dist/test/Upload.test.js +++ /dev/null @@ -1,27 +0,0 @@ -import 'should'; -import { strict as assert } from 'node:assert'; -import { Upload } from '../models/Upload.js'; -import { Uid } from '../models/Uid.js'; -describe('Upload', () => { - describe('constructor', () => { - it('must require a file_name', () => { - assert.throws(() => { - // @ts-expect-error TS(2554): Expected 4 arguments, but got 0. - new Upload(); - }, Error); - }); - it('should set properties given', () => { - const id = Uid.rand(); - const size = 1234; - const offset = 0; - const metadata = { foo: 'bar' }; - const upload = new Upload({ id, size, offset, metadata }); - assert.equal(upload.id, id); - assert.equal(upload.size, size); - assert.equal(upload.offset, offset); - assert.equal(upload.sizeIsDeferred, false); - assert.equal(upload.metadata, metadata); - }); - }); -}); -//# sourceMappingURL=Upload.test.js.map \ No newline at end of file diff --git a/packages/utils/dist/test/Upload.test.js.map b/packages/utils/dist/test/Upload.test.js.map deleted file mode 100644 index 7aa4e6eb..00000000 --- a/packages/utils/dist/test/Upload.test.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Upload.test.js","sourceRoot":"","sources":["../../src/test/Upload.test.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAA;AACf,OAAO,EAAC,MAAM,IAAI,MAAM,EAAC,MAAM,aAAa,CAAA;AAE5C,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAC1C,OAAO,EAAC,GAAG,EAAC,MAAM,kBAAkB,CAAA;AAEpC,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;YAClC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE;gBACjB,8DAA8D;gBAC9D,IAAI,MAAM,EAAE,CAAA;YACd,CAAC,EAAE,KAAK,CAAC,CAAA;QACX,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;YACrB,MAAM,IAAI,GAAG,IAAI,CAAA;YACjB,MAAM,MAAM,GAAG,CAAC,CAAA;YAChB,MAAM,QAAQ,GAAG,EAAC,GAAG,EAAE,KAAK,EAAC,CAAA;YAC7B,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAC,CAAC,CAAA;YACvD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;YAC3B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YAC/B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;YACnC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;YAC1C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QACzC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/test/stores.d.ts b/packages/utils/dist/test/stores.d.ts deleted file mode 100644 index 59305e6d..00000000 --- a/packages/utils/dist/test/stores.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import 'should'; -export declare function testId(id: string): string; -export declare const shouldHaveStoreMethods: () => void; -export declare const shouldCreateUploads: () => void; -export declare const shouldExpireUploads: () => void; -export declare const shouldRemoveUploads: () => void; -export declare const shouldWriteUploads: () => void; -export declare const shouldHandleOffset: () => void; -export declare const shouldDeclareUploadLength: () => void; -//# sourceMappingURL=stores.d.ts.map \ No newline at end of file diff --git a/packages/utils/dist/test/stores.d.ts.map b/packages/utils/dist/test/stores.d.ts.map deleted file mode 100644 index 13cdd4dd..00000000 --- a/packages/utils/dist/test/stores.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"stores.d.ts","sourceRoot":"","sources":["../../src/test/stores.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAA;AAQf,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,UAEhC;AAED,eAAO,MAAM,sBAAsB,YAYlC,CAAA;AAED,eAAO,MAAM,mBAAmB,YA4D/B,CAAA;AAED,eAAO,MAAM,mBAAmB,YAuB/B,CAAA;AAED,eAAO,MAAM,mBAAmB,YAkD/B,CAAA;AAED,eAAO,MAAM,kBAAkB,YA2C9B,CAAA;AAED,eAAO,MAAM,kBAAkB,YAwB9B,CAAA;AAED,eAAO,MAAM,yBAAyB,YAuBrC,CAAA"} \ No newline at end of file diff --git a/packages/utils/dist/test/stores.js b/packages/utils/dist/test/stores.js deleted file mode 100644 index 14f84054..00000000 --- a/packages/utils/dist/test/stores.js +++ /dev/null @@ -1,225 +0,0 @@ -import 'should'; -import { strict as assert } from 'node:assert'; -import fs from 'node:fs'; -import stream from 'node:stream'; -import { setTimeout as promSetTimeout } from 'node:timers/promises'; -import { Upload, Uid } from '@tus/utils'; -export function testId(id) { - return `${id}-${Uid.rand()}`; -} -export const shouldHaveStoreMethods = () => { - describe('the class', () => { - it('must have a write method', function (done) { - this.datastore.should.have.property('write'); - done(); - }); - it('must have a getUpload method', function (done) { - this.datastore.should.have.property('getUpload'); - done(); - }); - }); -}; -export const shouldCreateUploads = () => { - describe('create', () => { - const file = new Upload({ - id: testId('create-test'), - size: 1000, - offset: 0, - metadata: { filename: 'world_domination_plan.pdf', is_confidential: null }, - }); - const file_defered = new Upload({ - id: testId('create-test-deferred'), - offset: 0, - }); - it('should resolve to file', async function () { - const newFile = await this.datastore.create(file); - assert.ok(newFile.storage.path); - assert.ok(newFile.storage.type); - assert.equal(newFile instanceof Upload, true); - }); - it("should report 'creation' extension", function () { - assert.equal(this.datastore.hasExtension('creation'), true); - }); - it('should create new upload resource', async function () { - await this.datastore.create(file); - const upload = await this.datastore.getUpload(file.id); - assert.equal(upload.offset, 0); - }); - it('should store `upload_length` when creating new resource', async function () { - await this.datastore.create(file); - const upload = await this.datastore.getUpload(file.id); - assert.strictEqual(upload.size, file.size); - }); - it('should store `upload_defer_length` when creating new resource', async function () { - await this.datastore.create(file_defered); - const upload = await this.datastore.getUpload(file_defered.id); - assert.strictEqual(upload.sizeIsDeferred, file_defered.sizeIsDeferred); - }); - it('should store `upload_metadata` when creating new resource', async function () { - await this.datastore.create(file); - const upload = await this.datastore.getUpload(file.id); - assert.deepStrictEqual(upload.metadata, file.metadata); - }); - it('should store `upload_metadata` with non-ASCII characters', async function () { - const file = new Upload({ - id: testId('create-test-non-ascii'), - size: 1000, - offset: 0, - metadata: { filename: '世界_domination_plan.pdf', is_confidential: null }, - }); - await this.datastore.create(file); - const upload = await this.datastore.getUpload(file.id); - assert.deepStrictEqual(upload.metadata, file.metadata); - }); - }); -}; -export const shouldExpireUploads = () => { - describe('expiration extension', () => { - it("should report 'expiration' extension", function () { - assert.equal(this.datastore.hasExtension('expiration'), true); - }); - it('should expire upload', async function () { - const file = new Upload({ - id: testId('expiration-test'), - size: this.testFileSize, - offset: 0, - metadata: { filename: 'world_domination_plan.pdf', is_confidential: null }, - }); - this.datastore.expirationPeriodInMilliseconds = 100; - await this.datastore.create(file); - const readable = fs.createReadStream(this.testFilePath); - const offset = await this.datastore.write(readable, file.id, 0); - await promSetTimeout(100); - const n = await this.datastore.deleteExpired(); - assert.equal(offset, this.testFileSize); - assert.equal(n, 1); - }); - }); -}; -export const shouldRemoveUploads = () => { - const file = new Upload({ id: testId('remove-test'), size: 1000, offset: 0 }); - describe('remove (termination extension)', () => { - it("should report 'termination' extension", function () { - assert.equal(this.datastore.hasExtension('termination'), true); - }); - it('should reject when the file does not exist', function () { - return this.datastore.remove('doesnt_exist').should.be.rejected(); - }); - it('should delete the file when it does exist', async function () { - await this.datastore.create(file); - return this.datastore.remove(file.id); - }); - it('should delete the file during upload', async function () { - const file = new Upload({ - id: testId('termination-test'), - size: this.testFileSize, - offset: 0, - metadata: { filename: 'terminate_during_upload.pdf', is_confidential: null }, - }); - await this.datastore.create(file); - const readable = fs.createReadStream(this.testFilePath, { - highWaterMark: 100 * 1024, - }); - // Pause between chunks read to make sure that file is still uploading when terminate function is invoked - readable.on('data', () => { - readable.pause(); - setTimeout(() => readable.resume(), 1000); - }); - await Promise.allSettled([ - this.datastore.write(readable, file.id, 0), - this.datastore.remove(file.id), - ]); - try { - await this.datastore.getUpload(file.id); - assert.fail('getUpload should have thrown an error'); - } - catch (error) { - assert.equal([404, 410].includes(error?.status_code), true); - } - readable.destroy(); - }); - }); -}; -export const shouldWriteUploads = () => { - describe('write', () => { - it('should reject write streams that can not be open', async function () { - const stream = fs.createReadStream(this.testFilePath); - return this.datastore.write(stream, 'doesnt_exist', 0).should.be.rejected(); - }); - it('should reject when readable stream has an error', async function () { - const stream = fs.createReadStream(this.testFilePath); - return this.datastore.write(stream, 'doesnt_exist', 0).should.be.rejected(); - }); - it('should write a stream and resolve the new offset', async function () { - const file = new Upload({ - id: testId('write-test'), - size: this.testFileSize, - offset: 0, - metadata: { filename: 'world_domination_plan.pdf', is_confidential: null }, - }); - await this.datastore.create(file); - const readable = fs.createReadStream(this.testFilePath); - const offset = await this.datastore.write(readable, file.id, 0); - assert.equal(offset, this.testFileSize); - }); - it('should reject when stream is destroyed', async function () { - const file = new Upload({ - id: testId('write-test-reject'), - size: this.testFileSize, - offset: 0, - metadata: { filename: 'world_domination_plan.pdf', is_confidential: null }, - }); - await this.datastore.create(file); - const readable = new stream.Readable({ - read() { - this.push('some data'); - this.destroy(); - }, - }); - const offset = this.datastore.write(readable, file.id, 0); - return offset.should.be.rejected(); - }); - }); -}; -export const shouldHandleOffset = () => { - describe('getUpload', () => { - it('should reject non-existant files', function () { - return this.datastore.getUpload('doesnt_exist').should.be.rejected(); - }); - it('should resolve the stats for existing files', async function () { - const file = new Upload({ - id: testId('offset-test'), - size: this.testFileSize, - offset: 0, - metadata: { filename: 'world_domination_plan.pdf', is_confidential: null }, - }); - await this.datastore.create(file); - const offset = await this.datastore.write(fs.createReadStream(this.testFilePath), file.id, file.offset); - const upload = await this.datastore.getUpload(file.id); - assert.equal(upload.offset, offset); - }); - }); -}; -export const shouldDeclareUploadLength = () => { - describe('declareUploadLength', () => { - it('should reject non-existant files', function () { - return this.datastore.declareUploadLength('doesnt_exist', '10').should.be.rejected(); - }); - it('should update upload_length after declaring upload length', async function () { - const file = new Upload({ - id: testId('declare-length-test'), - offset: 0, - metadata: { filename: 'world_domination_plan.pdf', is_confidential: null }, - }); - await this.datastore.create(file); - let upload = await this.datastore.getUpload(file.id); - assert.equal(upload.size, undefined); - assert.equal(upload.sizeIsDeferred, true); - await this.datastore.declareUploadLength(file.id, 10); - upload = await this.datastore.getUpload(file.id); - assert.equal(upload.size, 10); - assert.equal(upload.sizeIsDeferred, false); - }); - }); -}; -//# sourceMappingURL=stores.js.map \ No newline at end of file diff --git a/packages/utils/dist/test/stores.js.map b/packages/utils/dist/test/stores.js.map deleted file mode 100644 index 62f0b815..00000000 --- a/packages/utils/dist/test/stores.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"stores.js","sourceRoot":"","sources":["../../src/test/stores.ts"],"names":[],"mappings":"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"} \ No newline at end of file From b7e02ce3e5f8be240480c923efc1532657a3401d Mon Sep 17 00:00:00 2001 From: Samuel Adeoye Date: Sat, 14 Feb 2026 05:13:29 -0330 Subject: [PATCH 04/11] Revert package json and lock --- package-lock.json | 139 +++++++++++++++++++++++++++++++--------------- package.json | 44 +++++++++------ 2 files changed, 123 insertions(+), 60 deletions(-) diff --git a/package-lock.json b/package-lock.json index daf9f7a6..52ec8c41 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "tus-node-server-1", + "name": "tus-node-server", "version": "0.0.0", "lockfileVersion": 3, "requires": true, @@ -869,17 +869,17 @@ } }, "node_modules/@azure/core-auth": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.1.tgz", - "integrity": "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.7.2.tgz", + "integrity": "sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.1.2", - "@azure/core-util": "^1.13.0", + "@azure/abort-controller": "^2.0.0", + "@azure/core-util": "^1.1.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=20.0.0" + "node": ">=18.0.0" } }, "node_modules/@azure/core-auth/node_modules/@azure/abort-controller": { @@ -1046,17 +1046,16 @@ } }, "node_modules/@azure/core-util": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.1.tgz", - "integrity": "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.2.tgz", + "integrity": "sha512-l1Qrqhi4x1aekkV+OlcqsJa4AnAkj5p0JV8omgwjaV9OAbP41lvrMvs+CptfetKkeEaGRGSzby7sjPZEX7+kkQ==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.1.2", - "@typespec/ts-http-runtime": "^0.3.0", + "@azure/abort-controller": "^2.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=20.0.0" + "node": ">=18.0.0" } }, "node_modules/@azure/core-util/node_modules/@azure/abort-controller": { @@ -2716,6 +2715,16 @@ "resolved": "packages/utils", "link": true }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, "node_modules/@types/caseless": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", @@ -2723,6 +2732,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/connect": { + "version": "3.4.38", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/cookiejar": { "version": "2.1.2", "dev": true, @@ -2736,6 +2754,18 @@ "@types/ms": "*" } }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.41", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, "node_modules/@types/glob": { "version": "8.1.0", "dev": true, @@ -2745,6 +2775,12 @@ "@types/node": "*" } }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/@types/lodash": { "version": "4.17.0", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", @@ -2760,6 +2796,12 @@ "@types/lodash": "*" } }, + "node_modules/@types/mime": { + "version": "1.3.5", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/@types/minimatch": { "version": "5.1.2", "dev": true, @@ -2793,6 +2835,18 @@ "undici-types": "~6.20.0" } }, + "node_modules/@types/qs": { + "version": "6.9.11", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/@types/request": { "version": "2.48.12", "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", @@ -2832,6 +2886,33 @@ "@types/node": "*" } }, + "node_modules/@types/send": { + "version": "0.17.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static/node_modules/@types/mime": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/@types/set-cookie-parser": { "version": "2.4.10", "resolved": "https://registry.npmjs.org/@types/set-cookie-parser/-/set-cookie-parser-2.4.10.tgz", @@ -2888,33 +2969,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@typespec/ts-http-runtime": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.3.tgz", - "integrity": "sha512-91fp6CAAJSRtH5ja95T1FHSKa8aPW9/Zw6cta81jlZTUw/+Vq8jM/AfF/14h2b71wwR84JUTW/3Y8QPhDAawFA==", - "license": "MIT", - "dependencies": { - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@typespec/ts-http-runtime/node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/abort-controller": { "version": "3.0.0", "dev": true, @@ -3494,7 +3548,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "iconv-lite": "^0.6.2" } @@ -3504,7 +3557,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -6141,7 +6193,6 @@ "version": "2.0.0", "license": "MIT", "dependencies": { - "@azure/core-auth": "^1.9.0", "@azure/storage-blob": "^12.24.0", "@tus/utils": "^0.6.0", "debug": "^4.3.4" @@ -6315,4 +6366,4 @@ } } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 6ff1b7b3..1b422660 100644 --- a/package.json +++ b/package.json @@ -1,26 +1,38 @@ { "$schema": "https://json.schemastore.org/package.json", - "private": true, + "name": "@tus/azure-store", + "version": "2.0.0", + "description": "Azure blob storage for @tus/server", + "main": "./dist/index.js", + "exports": "./dist/index.js", "type": "module", - "workspaces": [ - "packages/*", - "test" + "homepage": "https://github.com/tus/tus-node-server#readme", + "bugs": "https://github.com/tus/tus-node-server/issues", + "repository": "tus/tus-node-server", + "files": [ + "dist", + "src", + "!test*" ], + "license": "MIT", "scripts": { "build": "tsc --build", - "lint": "biome lint --write .", - "format": "biome format --write .", - "format:check": "biome format --error-on-warnings .", "pretest": "tsc --build", - "test": "npm test -w ./packages", - "version": "changeset version && npm install", - "release": "gh workflow run release", - "release:local": "npm run build && changeset publish" + "test": "mocha './dist/test/*.js' --exit" + }, + "dependencies": { + "@tus/utils": "^0.6.0", + "@azure/storage-blob": "^12.24.0", + "debug": "^4.3.4" }, "devDependencies": { - "@biomejs/biome": "1.9.4", - "@changesets/changelog-github": "^0.5.0", - "@changesets/cli": "^2.29.2", - "typescript": "^5.8.2" + "@types/debug": "^4.1.12", + "@types/mocha": "^10.0.6", + "@types/node": "^22.13.7", + "mocha": "^11.0.1", + "should": "^13.2.3" + }, + "engines": { + "node": ">=20.19.0" } -} +} \ No newline at end of file From b7623cfcaf9dbc796eda6a135597734a4ac53f00 Mon Sep 17 00:00:00 2001 From: Samuel Adeoye Date: Sat, 14 Feb 2026 05:17:54 -0330 Subject: [PATCH 05/11] Revert package.json --- package.json | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index 1b422660..01d71dd2 100644 --- a/package.json +++ b/package.json @@ -1,38 +1,26 @@ { "$schema": "https://json.schemastore.org/package.json", - "name": "@tus/azure-store", - "version": "2.0.0", - "description": "Azure blob storage for @tus/server", - "main": "./dist/index.js", - "exports": "./dist/index.js", + "private": true, "type": "module", - "homepage": "https://github.com/tus/tus-node-server#readme", - "bugs": "https://github.com/tus/tus-node-server/issues", - "repository": "tus/tus-node-server", - "files": [ - "dist", - "src", - "!test*" + "workspaces": [ + "packages/*", + "test" ], - "license": "MIT", "scripts": { "build": "tsc --build", + "lint": "biome lint --write .", + "format": "biome format --write .", + "format:check": "biome format --error-on-warnings .", "pretest": "tsc --build", - "test": "mocha './dist/test/*.js' --exit" - }, - "dependencies": { - "@tus/utils": "^0.6.0", - "@azure/storage-blob": "^12.24.0", - "debug": "^4.3.4" + "test": "npm test -w ./packages", + "version": "changeset version && npm install", + "release": "gh workflow run release", + "release:local": "npm run build && changeset publish" }, "devDependencies": { - "@types/debug": "^4.1.12", - "@types/mocha": "^10.0.6", - "@types/node": "^22.13.7", - "mocha": "^11.0.1", - "should": "^13.2.3" - }, - "engines": { - "node": ">=20.19.0" + "@biomejs/biome": "1.9.4", + "@changesets/changelog-github": "^0.5.0", + "@changesets/cli": "^2.29.2", + "typescript": "^5.8.2" } } \ No newline at end of file From 9a301b26eb31304e4a64f282225f0e9771d91bc7 Mon Sep 17 00:00:00 2001 From: Samuel Adeoye Date: Sat, 14 Feb 2026 05:37:30 -0330 Subject: [PATCH 06/11] Add tests --- packages/azure-store/src/test/index.ts | 120 ++++++++++++++++++------- 1 file changed, 88 insertions(+), 32 deletions(-) diff --git a/packages/azure-store/src/test/index.ts b/packages/azure-store/src/test/index.ts index b2f19026..80ef7a70 100644 --- a/packages/azure-store/src/test/index.ts +++ b/packages/azure-store/src/test/index.ts @@ -1,32 +1,88 @@ -import 'should' -import path from 'node:path' -import {AzureStore} from '@tus/azure-store' -import * as shared from '../../../utils/dist/test/stores.js' - -const fixturesPath = path.resolve('../', '../', 'test', 'fixtures') -const storePath = path.resolve('../', '../', 'test', 'output', 'azure-store') - -describe('AzureStore', () => { - before(function () { - this.testFileSize = 960_244 - this.testFileName = 'test.mp4' - this.storePath = storePath - this.testFilePath = path.resolve(fixturesPath, this.testFileName) - }) - - beforeEach(function () { - this.datastore = new AzureStore({ - account: process.env.AZURE_ACCOUNT_ID as string, - accountKey: process.env.AZURE_ACCOUNT_KEY as string, - containerName: process.env.AZURE_CONTAINER_NAME as string, - }) - }) - - shared.shouldHaveStoreMethods() - shared.shouldCreateUploads() - // shared.shouldRemoveUploads() // Not implemented yet - // shared.shouldExpireUploads() // Not implemented yet - shared.shouldWriteUploads() - shared.shouldHandleOffset() - shared.shouldDeclareUploadLength() // Creation-defer-length extension -}) +import "should"; +import { strict as assert } from "node:assert"; +import path from "node:path"; +import { AzureStore } from "@tus/azure-store"; +import type { TokenCredential } from "@azure/core-auth"; +import * as shared from "../../../utils/dist/test/stores.js"; + +const fixturesPath = path.resolve("../", "../", "test", "fixtures"); +const storePath = path.resolve("../", "../", "test", "output", "azure-store"); + +describe("AzureStore", () => { + describe("with Azure credentials", function () { + before(function () { + this.testFileSize = 960_244; + this.testFileName = "test.mp4"; + this.storePath = storePath; + this.testFilePath = path.resolve(fixturesPath, this.testFileName); + }); + + beforeEach(function () { + this.datastore = new AzureStore({ + account: process.env.AZURE_ACCOUNT_ID as string, + accountKey: process.env.AZURE_ACCOUNT_KEY as string, + containerName: process.env.AZURE_CONTAINER_NAME as string, + }); + }); + + shared.shouldHaveStoreMethods(); + shared.shouldCreateUploads(); + // shared.shouldRemoveUploads() // Not implemented yet + // shared.shouldExpireUploads() // Not implemented yet + shared.shouldWriteUploads(); + shared.shouldHandleOffset(); + shared.shouldDeclareUploadLength(); // Creation-defer-length extension + }); + + describe("constructor", () => { + it("should accept a TokenCredential instead of accountKey", function () { + const mockCredential: TokenCredential = { + getToken: async () => ({ + token: "mock-token", + expiresOnTimestamp: Date.now() + 3600_000, + }), + }; + const store = new AzureStore({ + account: "testaccount", + containerName: "testcontainer", + credential: mockCredential, + }); + assert.ok(store); + }); + + it("should throw when neither accountKey nor credential is provided", function () { + assert.throws( + () => + new AzureStore({ + account: "testaccount", + containerName: "testcontainer", + }), + /accountKey or credential/ + ); + }); + + it("should throw when account is missing", function () { + assert.throws( + () => + new AzureStore({ + account: "", + containerName: "test", + accountKey: "key", + }), + /account/ + ); + }); + + it("should throw when containerName is missing", function () { + assert.throws( + () => + new AzureStore({ + account: "test", + containerName: "", + accountKey: "key", + }), + /container name/ + ); + }); + }); +}); From 345d892ef52618b006a357e280fae6435cf716d2 Mon Sep 17 00:00:00 2001 From: Samuel Adeoye Date: Sat, 14 Feb 2026 05:39:00 -0330 Subject: [PATCH 07/11] Biome format code --- packages/azure-store/src/index.ts | 5 +- packages/azure-store/src/test/index.ts | 102 ++++++++++++------------- 2 files changed, 52 insertions(+), 55 deletions(-) diff --git a/packages/azure-store/src/index.ts b/packages/azure-store/src/index.ts index 29f61840..a7baaab3 100644 --- a/packages/azure-store/src/index.ts +++ b/packages/azure-store/src/index.ts @@ -58,10 +58,7 @@ export class AzureStore extends DataStore { ? options.credential : new StorageSharedKeyCredential(options.account, options.accountKey!) - this.blobServiceClient = new BlobServiceClient( - storageAccountBaseUrl, - credential - ) + this.blobServiceClient = new BlobServiceClient(storageAccountBaseUrl, credential) this.containerClient = this.blobServiceClient.getContainerClient( options.containerName ) diff --git a/packages/azure-store/src/test/index.ts b/packages/azure-store/src/test/index.ts index 80ef7a70..af59f87a 100644 --- a/packages/azure-store/src/test/index.ts +++ b/packages/azure-store/src/test/index.ts @@ -1,88 +1,88 @@ -import "should"; -import { strict as assert } from "node:assert"; -import path from "node:path"; -import { AzureStore } from "@tus/azure-store"; -import type { TokenCredential } from "@azure/core-auth"; -import * as shared from "../../../utils/dist/test/stores.js"; +import 'should' +import {strict as assert} from 'node:assert' +import path from 'node:path' +import {AzureStore} from '@tus/azure-store' +import type {TokenCredential} from '@azure/core-auth' +import * as shared from '../../../utils/dist/test/stores.js' -const fixturesPath = path.resolve("../", "../", "test", "fixtures"); -const storePath = path.resolve("../", "../", "test", "output", "azure-store"); +const fixturesPath = path.resolve('../', '../', 'test', 'fixtures') +const storePath = path.resolve('../', '../', 'test', 'output', 'azure-store') -describe("AzureStore", () => { - describe("with Azure credentials", function () { +describe('AzureStore', () => { + describe('with Azure credentials', function () { before(function () { - this.testFileSize = 960_244; - this.testFileName = "test.mp4"; - this.storePath = storePath; - this.testFilePath = path.resolve(fixturesPath, this.testFileName); - }); + this.testFileSize = 960_244 + this.testFileName = 'test.mp4' + this.storePath = storePath + this.testFilePath = path.resolve(fixturesPath, this.testFileName) + }) beforeEach(function () { this.datastore = new AzureStore({ account: process.env.AZURE_ACCOUNT_ID as string, accountKey: process.env.AZURE_ACCOUNT_KEY as string, containerName: process.env.AZURE_CONTAINER_NAME as string, - }); - }); + }) + }) - shared.shouldHaveStoreMethods(); - shared.shouldCreateUploads(); + shared.shouldHaveStoreMethods() + shared.shouldCreateUploads() // shared.shouldRemoveUploads() // Not implemented yet // shared.shouldExpireUploads() // Not implemented yet - shared.shouldWriteUploads(); - shared.shouldHandleOffset(); - shared.shouldDeclareUploadLength(); // Creation-defer-length extension - }); + shared.shouldWriteUploads() + shared.shouldHandleOffset() + shared.shouldDeclareUploadLength() // Creation-defer-length extension + }) - describe("constructor", () => { - it("should accept a TokenCredential instead of accountKey", function () { + describe('constructor', () => { + it('should accept a TokenCredential instead of accountKey', function () { const mockCredential: TokenCredential = { getToken: async () => ({ - token: "mock-token", + token: 'mock-token', expiresOnTimestamp: Date.now() + 3600_000, }), - }; + } const store = new AzureStore({ - account: "testaccount", - containerName: "testcontainer", + account: 'testaccount', + containerName: 'testcontainer', credential: mockCredential, - }); - assert.ok(store); - }); + }) + assert.ok(store) + }) - it("should throw when neither accountKey nor credential is provided", function () { + it('should throw when neither accountKey nor credential is provided', function () { assert.throws( () => new AzureStore({ - account: "testaccount", - containerName: "testcontainer", + account: 'testaccount', + containerName: 'testcontainer', }), /accountKey or credential/ - ); - }); + ) + }) - it("should throw when account is missing", function () { + it('should throw when account is missing', function () { assert.throws( () => new AzureStore({ - account: "", - containerName: "test", - accountKey: "key", + account: '', + containerName: 'test', + accountKey: 'key', }), /account/ - ); - }); + ) + }) - it("should throw when containerName is missing", function () { + it('should throw when containerName is missing', function () { assert.throws( () => new AzureStore({ - account: "test", - containerName: "", - accountKey: "key", + account: 'test', + containerName: '', + accountKey: 'key', }), /container name/ - ); - }); - }); -}); + ) + }) + }) +}) From 378eb7b9fa2d57aef75a6ba094a151a75220c2a2 Mon Sep 17 00:00:00 2001 From: Samuel Adeoye Date: Sat, 14 Feb 2026 05:44:26 -0330 Subject: [PATCH 08/11] Fix lint error --- packages/azure-store/src/index.ts | 190 +++++++++++++------------ packages/azure-store/src/test/index.ts | 102 ++++++------- 2 files changed, 151 insertions(+), 141 deletions(-) diff --git a/packages/azure-store/src/index.ts b/packages/azure-store/src/index.ts index a7baaab3..0a329513 100644 --- a/packages/azure-store/src/index.ts +++ b/packages/azure-store/src/index.ts @@ -1,5 +1,5 @@ -import type stream from 'node:stream' -import debug from 'debug' +import type stream from "node:stream"; +import debug from "debug"; import { DataStore, Upload, @@ -8,71 +8,77 @@ import { MemoryKvStore, TUS_RESUMABLE, Metadata, -} from '@tus/utils' +} from "@tus/utils"; import { type AppendBlobClient, type BlobGetPropertiesResponse, BlobServiceClient, type ContainerClient, StorageSharedKeyCredential, -} from '@azure/storage-blob' -import type {TokenCredential} from '@azure/core-auth' +} from "@azure/storage-blob"; +import type { TokenCredential } from "@azure/core-auth"; type Options = { - cache?: KvStore - account: string - containerName: string - accountKey?: string - credential?: TokenCredential -} + cache?: KvStore; + account: string; + containerName: string; + accountKey?: string; + credential?: TokenCredential; +}; -const log = debug('tus-node-server:stores:azurestore') +const log = debug("tus-node-server:stores:azurestore"); /** * Store using the Azure Storage SDK * @author Bharath Battaje */ export class AzureStore extends DataStore { - private cache: KvStore - private blobServiceClient: BlobServiceClient - private containerClient: ContainerClient - private containerName: string + private cache: KvStore; + private blobServiceClient: BlobServiceClient; + private containerClient: ContainerClient; + private containerName: string; constructor(options: Options) { - super() - this.cache = options.cache ?? new MemoryKvStore() - this.extensions = ['creation', 'creation-defer-length'] + super(); + this.cache = options.cache ?? new MemoryKvStore(); + this.extensions = ["creation", "creation-defer-length"]; if (!options.account) { - throw new Error('Azure store must have a account') + throw new Error("Azure store must have a account"); } if (!options.containerName) { - throw new Error('Azure store must have a container name') + throw new Error("Azure store must have a container name"); } if (!options.accountKey && !options.credential) { - throw new Error('Azure store requires either accountKey or credential') + throw new Error("Azure store requires either accountKey or credential"); } - const storageAccountBaseUrl = `https://${options.account}.blob.core.windows.net` + const storageAccountBaseUrl = `https://${options.account}.blob.core.windows.net`; const credential = options.credential ? options.credential - : new StorageSharedKeyCredential(options.account, options.accountKey!) + : new StorageSharedKeyCredential(options.account, options.accountKey as string); - this.blobServiceClient = new BlobServiceClient(storageAccountBaseUrl, credential) + this.blobServiceClient = new BlobServiceClient( + storageAccountBaseUrl, + credential + ); this.containerClient = this.blobServiceClient.getContainerClient( options.containerName - ) - this.containerName = options.containerName + ); + this.containerName = options.containerName; } /** * Saves upload metadata to blob metada. Also upload metadata * gets saved in local cache as well to avoid calling azure server everytime. */ - private async saveMetadata(appendBlobClient: AppendBlobClient, upload: Upload) { - log(`[${upload.id}] saving metadata`) + private async saveMetadata( + appendBlobClient: AppendBlobClient, + upload: Upload + ) { + log(`[${upload.id}] saving metadata`); - await this.cache.set(appendBlobClient.url, upload) + await this.cache.set(appendBlobClient.url, upload); await appendBlobClient.setMetadata( { @@ -84,77 +90,81 @@ export class AzureStore extends DataStore { }), }, {} - ) + ); - log(`[${upload.id}] metadata saved`) + log(`[${upload.id}] metadata saved`); } /** * Retrieves upload metadata previously saved. * It tries to get from local cache, else get from the blob metadata. */ - private async getMetadata(appendBlobClient: AppendBlobClient): Promise { - const cached = await this.cache.get(appendBlobClient.url) + private async getMetadata( + appendBlobClient: AppendBlobClient + ): Promise { + const cached = await this.cache.get(appendBlobClient.url); if (cached) { - log(`[${cached.id}] metadata returned from cache`) - return cached + log(`[${cached.id}] metadata returned from cache`); + return cached; } - let propertyData: BlobGetPropertiesResponse + let propertyData: BlobGetPropertiesResponse; try { - propertyData = await appendBlobClient.getProperties() + propertyData = await appendBlobClient.getProperties(); } catch (error) { - log('Error while fetching the metadata.', error) - throw ERRORS.UNKNOWN_ERROR + log("Error while fetching the metadata.", error); + throw ERRORS.UNKNOWN_ERROR; } if (!propertyData.metadata) { - throw ERRORS.FILE_NOT_FOUND + throw ERRORS.FILE_NOT_FOUND; } - const upload = JSON.parse(propertyData.metadata.upload) as Upload + const upload = JSON.parse(propertyData.metadata.upload) as Upload; // Metadata is base64 encoded to avoid errors for non-ASCII characters // so we need to decode it separately - upload.metadata = Metadata.parse(JSON.stringify(upload.metadata ?? {})) + upload.metadata = Metadata.parse(JSON.stringify(upload.metadata ?? {})); - await this.cache.set(appendBlobClient.url, upload) + await this.cache.set(appendBlobClient.url, upload); - log('metadata returned from blob get properties') + log("metadata returned from blob get properties"); - return upload + return upload; } /** * provides the readable stream for the previously uploaded file */ public async read(file_id: string) { - const appendBlobClient = this.containerClient.getAppendBlobClient(file_id) - const downloadResponse = await appendBlobClient.download() + const appendBlobClient = this.containerClient.getAppendBlobClient(file_id); + const downloadResponse = await appendBlobClient.download(); - return downloadResponse.readableStreamBody + return downloadResponse.readableStreamBody; } /** * Creates a empty append blob on Azure storage and attaches the metadata to it. */ public async create(upload: Upload) { - log(`[${upload.id}] initializing azure storage file upload`) + log(`[${upload.id}] initializing azure storage file upload`); try { - const appendBlobClient = this.containerClient.getAppendBlobClient(upload.id) - await appendBlobClient.createIfNotExists() + const appendBlobClient = this.containerClient.getAppendBlobClient( + upload.id + ); + await appendBlobClient.createIfNotExists(); upload.storage = { - type: 'AzureBlobStore', + type: "AzureBlobStore", path: upload.id, bucket: this.containerName, - } + }; - await this.saveMetadata(appendBlobClient, upload) + await this.saveMetadata(appendBlobClient, upload); - return upload + return upload; } catch (err) { - throw ERRORS.UNKNOWN_ERROR + throw ERRORS.UNKNOWN_ERROR; } } @@ -162,11 +172,11 @@ export class AzureStore extends DataStore { * Gets the current file upload status */ public async getUpload(id: string): Promise { - const appendBlobClient = this.containerClient.getAppendBlobClient(id) - const upload = await this.getMetadata(appendBlobClient) + const appendBlobClient = this.containerClient.getAppendBlobClient(id); + const upload = await this.getMetadata(appendBlobClient); if (!upload) { - throw ERRORS.FILE_NOT_FOUND + throw ERRORS.FILE_NOT_FOUND; } return new Upload({ @@ -176,7 +186,7 @@ export class AzureStore extends DataStore { offset: upload.offset, storage: upload.storage, creation_date: upload.creation_date, - }) + }); } /** @@ -189,68 +199,68 @@ export class AzureStore extends DataStore { id: string, offset: number ): Promise { - log(`started writing the file offset [${offset}]`) + log(`started writing the file offset [${offset}]`); - const appendBlobClient = this.containerClient.getAppendBlobClient(id) - const upload = await this.getMetadata(appendBlobClient) + const appendBlobClient = this.containerClient.getAppendBlobClient(id); + const upload = await this.getMetadata(appendBlobClient); // biome-ignore lint/suspicious/noAsyncPromiseExecutor: return new Promise(async (resolve, reject) => { if (offset < upload.offset) { //duplicate request scenario, dont want to write the same data - return resolve(upload.offset) + return resolve(upload.offset); } try { - const bufs: Buffer[] = [] + const bufs: Buffer[] = []; - stream.on('data', async (chunk: Buffer) => { + stream.on("data", async (chunk: Buffer) => { if (stream.destroyed) { - return reject(ERRORS.ABORTED) + return reject(ERRORS.ABORTED); } - bufs.push(chunk) - }) + bufs.push(chunk); + }); - stream.on('end', async () => { - const buf = Buffer.concat(bufs) + stream.on("end", async () => { + const buf = Buffer.concat(bufs); if (buf.length > 0) { - await appendBlobClient.appendBlock(buf, buf.length) + await appendBlobClient.appendBlock(buf, buf.length); } - upload.offset = upload.offset + buf.length - log(`saved offset is [${upload.offset}]`) + upload.offset = upload.offset + buf.length; + log(`saved offset is [${upload.offset}]`); - await this.saveMetadata(appendBlobClient, upload) + await this.saveMetadata(appendBlobClient, upload); if (upload.offset === upload.size) { - await this.cache.delete(appendBlobClient.url) - log(`file upload completed successfully [${id}]`) + await this.cache.delete(appendBlobClient.url); + log(`file upload completed successfully [${id}]`); } - return resolve(upload.offset) - }) + return resolve(upload.offset); + }); - stream.on('error', async () => { - return reject(ERRORS.UNKNOWN_ERROR) - }) + stream.on("error", async () => { + return reject(ERRORS.UNKNOWN_ERROR); + }); } catch (err) { - return reject('something went wrong while writing the file.') + return reject("something went wrong while writing the file."); } - }) + }); } public async declareUploadLength(id: string, upload_length: number) { - const appendBlobClient = this.containerClient.getAppendBlobClient(id) - const upload = await this.getMetadata(appendBlobClient) + const appendBlobClient = this.containerClient.getAppendBlobClient(id); + const upload = await this.getMetadata(appendBlobClient); if (!upload) { - throw ERRORS.FILE_NOT_FOUND + throw ERRORS.FILE_NOT_FOUND; } - upload.size = upload_length + upload.size = upload_length; - await this.saveMetadata(appendBlobClient, upload) + await this.saveMetadata(appendBlobClient, upload); } } diff --git a/packages/azure-store/src/test/index.ts b/packages/azure-store/src/test/index.ts index af59f87a..4df68e4c 100644 --- a/packages/azure-store/src/test/index.ts +++ b/packages/azure-store/src/test/index.ts @@ -1,88 +1,88 @@ -import 'should' -import {strict as assert} from 'node:assert' -import path from 'node:path' -import {AzureStore} from '@tus/azure-store' -import type {TokenCredential} from '@azure/core-auth' -import * as shared from '../../../utils/dist/test/stores.js' +import "should"; +import { strict as assert } from "node:assert"; +import path from "node:path"; +import { AzureStore } from "@tus/azure-store"; +import type { TokenCredential } from "@azure/core-auth"; +import * as shared from "../../../utils/dist/test/stores.js"; -const fixturesPath = path.resolve('../', '../', 'test', 'fixtures') -const storePath = path.resolve('../', '../', 'test', 'output', 'azure-store') +const fixturesPath = path.resolve("../", "../", "test", "fixtures"); +const storePath = path.resolve("../", "../", "test", "output", "azure-store"); -describe('AzureStore', () => { - describe('with Azure credentials', function () { +describe("AzureStore", () => { + describe("with Account key", () => { before(function () { - this.testFileSize = 960_244 - this.testFileName = 'test.mp4' - this.storePath = storePath - this.testFilePath = path.resolve(fixturesPath, this.testFileName) - }) + this.testFileSize = 960_244; + this.testFileName = "test.mp4"; + this.storePath = storePath; + this.testFilePath = path.resolve(fixturesPath, this.testFileName); + }); beforeEach(function () { this.datastore = new AzureStore({ account: process.env.AZURE_ACCOUNT_ID as string, accountKey: process.env.AZURE_ACCOUNT_KEY as string, containerName: process.env.AZURE_CONTAINER_NAME as string, - }) - }) + }); + }); - shared.shouldHaveStoreMethods() - shared.shouldCreateUploads() + shared.shouldHaveStoreMethods(); + shared.shouldCreateUploads(); // shared.shouldRemoveUploads() // Not implemented yet // shared.shouldExpireUploads() // Not implemented yet - shared.shouldWriteUploads() - shared.shouldHandleOffset() - shared.shouldDeclareUploadLength() // Creation-defer-length extension - }) + shared.shouldWriteUploads(); + shared.shouldHandleOffset(); + shared.shouldDeclareUploadLength(); // Creation-defer-length extension + }); - describe('constructor', () => { - it('should accept a TokenCredential instead of accountKey', function () { + describe("constructor", () => { + it("should accept a TokenCredential instead of accountKey", () => { const mockCredential: TokenCredential = { getToken: async () => ({ - token: 'mock-token', + token: "mock-token", expiresOnTimestamp: Date.now() + 3600_000, }), - } + }; const store = new AzureStore({ - account: 'testaccount', - containerName: 'testcontainer', + account: "testaccount", + containerName: "testcontainer", credential: mockCredential, - }) - assert.ok(store) - }) + }); + assert.ok(store); + }); - it('should throw when neither accountKey nor credential is provided', function () { + it("should throw when neither accountKey nor credential is provided", () => { assert.throws( () => new AzureStore({ - account: 'testaccount', - containerName: 'testcontainer', + account: "testaccount", + containerName: "testcontainer", }), /accountKey or credential/ - ) - }) + ); + }); - it('should throw when account is missing', function () { + it("should throw when account is missing", () => { assert.throws( () => new AzureStore({ - account: '', - containerName: 'test', - accountKey: 'key', + account: "", + containerName: "test", + accountKey: "key", }), /account/ - ) - }) + ); + }); - it('should throw when containerName is missing', function () { + it("should throw when containerName is missing", () => { assert.throws( () => new AzureStore({ - account: 'test', - containerName: '', - accountKey: 'key', + account: "test", + containerName: "", + accountKey: "key", }), /container name/ - ) - }) - }) -}) + ); + }); + }); +}); From dbc843bc9f5532a89a37be1d4e36a98b95c36622 Mon Sep 17 00:00:00 2001 From: Samuel Adeoye Date: Sat, 14 Feb 2026 05:45:15 -0330 Subject: [PATCH 09/11] Biome fix --- packages/azure-store/src/index.ts | 190 ++++++++++++------------- packages/azure-store/src/test/index.ts | 102 ++++++------- 2 files changed, 141 insertions(+), 151 deletions(-) diff --git a/packages/azure-store/src/index.ts b/packages/azure-store/src/index.ts index 0a329513..7dc325c4 100644 --- a/packages/azure-store/src/index.ts +++ b/packages/azure-store/src/index.ts @@ -1,5 +1,5 @@ -import type stream from "node:stream"; -import debug from "debug"; +import type stream from 'node:stream' +import debug from 'debug' import { DataStore, Upload, @@ -8,77 +8,71 @@ import { MemoryKvStore, TUS_RESUMABLE, Metadata, -} from "@tus/utils"; +} from '@tus/utils' import { type AppendBlobClient, type BlobGetPropertiesResponse, BlobServiceClient, type ContainerClient, StorageSharedKeyCredential, -} from "@azure/storage-blob"; -import type { TokenCredential } from "@azure/core-auth"; +} from '@azure/storage-blob' +import type {TokenCredential} from '@azure/core-auth' type Options = { - cache?: KvStore; - account: string; - containerName: string; - accountKey?: string; - credential?: TokenCredential; -}; + cache?: KvStore + account: string + containerName: string + accountKey?: string + credential?: TokenCredential +} -const log = debug("tus-node-server:stores:azurestore"); +const log = debug('tus-node-server:stores:azurestore') /** * Store using the Azure Storage SDK * @author Bharath Battaje */ export class AzureStore extends DataStore { - private cache: KvStore; - private blobServiceClient: BlobServiceClient; - private containerClient: ContainerClient; - private containerName: string; + private cache: KvStore + private blobServiceClient: BlobServiceClient + private containerClient: ContainerClient + private containerName: string constructor(options: Options) { - super(); - this.cache = options.cache ?? new MemoryKvStore(); - this.extensions = ["creation", "creation-defer-length"]; + super() + this.cache = options.cache ?? new MemoryKvStore() + this.extensions = ['creation', 'creation-defer-length'] if (!options.account) { - throw new Error("Azure store must have a account"); + throw new Error('Azure store must have a account') } if (!options.containerName) { - throw new Error("Azure store must have a container name"); + throw new Error('Azure store must have a container name') } if (!options.accountKey && !options.credential) { - throw new Error("Azure store requires either accountKey or credential"); + throw new Error('Azure store requires either accountKey or credential') } - const storageAccountBaseUrl = `https://${options.account}.blob.core.windows.net`; + const storageAccountBaseUrl = `https://${options.account}.blob.core.windows.net` const credential = options.credential ? options.credential - : new StorageSharedKeyCredential(options.account, options.accountKey as string); + : new StorageSharedKeyCredential(options.account, options.accountKey as string) - this.blobServiceClient = new BlobServiceClient( - storageAccountBaseUrl, - credential - ); + this.blobServiceClient = new BlobServiceClient(storageAccountBaseUrl, credential) this.containerClient = this.blobServiceClient.getContainerClient( options.containerName - ); - this.containerName = options.containerName; + ) + this.containerName = options.containerName } /** * Saves upload metadata to blob metada. Also upload metadata * gets saved in local cache as well to avoid calling azure server everytime. */ - private async saveMetadata( - appendBlobClient: AppendBlobClient, - upload: Upload - ) { - log(`[${upload.id}] saving metadata`); + private async saveMetadata(appendBlobClient: AppendBlobClient, upload: Upload) { + log(`[${upload.id}] saving metadata`) - await this.cache.set(appendBlobClient.url, upload); + await this.cache.set(appendBlobClient.url, upload) await appendBlobClient.setMetadata( { @@ -90,81 +84,77 @@ export class AzureStore extends DataStore { }), }, {} - ); + ) - log(`[${upload.id}] metadata saved`); + log(`[${upload.id}] metadata saved`) } /** * Retrieves upload metadata previously saved. * It tries to get from local cache, else get from the blob metadata. */ - private async getMetadata( - appendBlobClient: AppendBlobClient - ): Promise { - const cached = await this.cache.get(appendBlobClient.url); + private async getMetadata(appendBlobClient: AppendBlobClient): Promise { + const cached = await this.cache.get(appendBlobClient.url) if (cached) { - log(`[${cached.id}] metadata returned from cache`); - return cached; + log(`[${cached.id}] metadata returned from cache`) + return cached } - let propertyData: BlobGetPropertiesResponse; + let propertyData: BlobGetPropertiesResponse try { - propertyData = await appendBlobClient.getProperties(); + propertyData = await appendBlobClient.getProperties() } catch (error) { - log("Error while fetching the metadata.", error); - throw ERRORS.UNKNOWN_ERROR; + log('Error while fetching the metadata.', error) + throw ERRORS.UNKNOWN_ERROR } if (!propertyData.metadata) { - throw ERRORS.FILE_NOT_FOUND; + throw ERRORS.FILE_NOT_FOUND } - const upload = JSON.parse(propertyData.metadata.upload) as Upload; + const upload = JSON.parse(propertyData.metadata.upload) as Upload // Metadata is base64 encoded to avoid errors for non-ASCII characters // so we need to decode it separately - upload.metadata = Metadata.parse(JSON.stringify(upload.metadata ?? {})); + upload.metadata = Metadata.parse(JSON.stringify(upload.metadata ?? {})) - await this.cache.set(appendBlobClient.url, upload); + await this.cache.set(appendBlobClient.url, upload) - log("metadata returned from blob get properties"); + log('metadata returned from blob get properties') - return upload; + return upload } /** * provides the readable stream for the previously uploaded file */ public async read(file_id: string) { - const appendBlobClient = this.containerClient.getAppendBlobClient(file_id); - const downloadResponse = await appendBlobClient.download(); + const appendBlobClient = this.containerClient.getAppendBlobClient(file_id) + const downloadResponse = await appendBlobClient.download() - return downloadResponse.readableStreamBody; + return downloadResponse.readableStreamBody } /** * Creates a empty append blob on Azure storage and attaches the metadata to it. */ public async create(upload: Upload) { - log(`[${upload.id}] initializing azure storage file upload`); + log(`[${upload.id}] initializing azure storage file upload`) try { - const appendBlobClient = this.containerClient.getAppendBlobClient( - upload.id - ); - await appendBlobClient.createIfNotExists(); + const appendBlobClient = this.containerClient.getAppendBlobClient(upload.id) + await appendBlobClient.createIfNotExists() upload.storage = { - type: "AzureBlobStore", + type: 'AzureBlobStore', path: upload.id, bucket: this.containerName, - }; + } - await this.saveMetadata(appendBlobClient, upload); + await this.saveMetadata(appendBlobClient, upload) - return upload; + return upload } catch (err) { - throw ERRORS.UNKNOWN_ERROR; + throw ERRORS.UNKNOWN_ERROR } } @@ -172,11 +162,11 @@ export class AzureStore extends DataStore { * Gets the current file upload status */ public async getUpload(id: string): Promise { - const appendBlobClient = this.containerClient.getAppendBlobClient(id); - const upload = await this.getMetadata(appendBlobClient); + const appendBlobClient = this.containerClient.getAppendBlobClient(id) + const upload = await this.getMetadata(appendBlobClient) if (!upload) { - throw ERRORS.FILE_NOT_FOUND; + throw ERRORS.FILE_NOT_FOUND } return new Upload({ @@ -186,7 +176,7 @@ export class AzureStore extends DataStore { offset: upload.offset, storage: upload.storage, creation_date: upload.creation_date, - }); + }) } /** @@ -199,68 +189,68 @@ export class AzureStore extends DataStore { id: string, offset: number ): Promise { - log(`started writing the file offset [${offset}]`); + log(`started writing the file offset [${offset}]`) - const appendBlobClient = this.containerClient.getAppendBlobClient(id); - const upload = await this.getMetadata(appendBlobClient); + const appendBlobClient = this.containerClient.getAppendBlobClient(id) + const upload = await this.getMetadata(appendBlobClient) // biome-ignore lint/suspicious/noAsyncPromiseExecutor: return new Promise(async (resolve, reject) => { if (offset < upload.offset) { //duplicate request scenario, dont want to write the same data - return resolve(upload.offset); + return resolve(upload.offset) } try { - const bufs: Buffer[] = []; + const bufs: Buffer[] = [] - stream.on("data", async (chunk: Buffer) => { + stream.on('data', async (chunk: Buffer) => { if (stream.destroyed) { - return reject(ERRORS.ABORTED); + return reject(ERRORS.ABORTED) } - bufs.push(chunk); - }); + bufs.push(chunk) + }) - stream.on("end", async () => { - const buf = Buffer.concat(bufs); + stream.on('end', async () => { + const buf = Buffer.concat(bufs) if (buf.length > 0) { - await appendBlobClient.appendBlock(buf, buf.length); + await appendBlobClient.appendBlock(buf, buf.length) } - upload.offset = upload.offset + buf.length; - log(`saved offset is [${upload.offset}]`); + upload.offset = upload.offset + buf.length + log(`saved offset is [${upload.offset}]`) - await this.saveMetadata(appendBlobClient, upload); + await this.saveMetadata(appendBlobClient, upload) if (upload.offset === upload.size) { - await this.cache.delete(appendBlobClient.url); - log(`file upload completed successfully [${id}]`); + await this.cache.delete(appendBlobClient.url) + log(`file upload completed successfully [${id}]`) } - return resolve(upload.offset); - }); + return resolve(upload.offset) + }) - stream.on("error", async () => { - return reject(ERRORS.UNKNOWN_ERROR); - }); + stream.on('error', async () => { + return reject(ERRORS.UNKNOWN_ERROR) + }) } catch (err) { - return reject("something went wrong while writing the file."); + return reject('something went wrong while writing the file.') } - }); + }) } public async declareUploadLength(id: string, upload_length: number) { - const appendBlobClient = this.containerClient.getAppendBlobClient(id); - const upload = await this.getMetadata(appendBlobClient); + const appendBlobClient = this.containerClient.getAppendBlobClient(id) + const upload = await this.getMetadata(appendBlobClient) if (!upload) { - throw ERRORS.FILE_NOT_FOUND; + throw ERRORS.FILE_NOT_FOUND } - upload.size = upload_length; + upload.size = upload_length - await this.saveMetadata(appendBlobClient, upload); + await this.saveMetadata(appendBlobClient, upload) } } diff --git a/packages/azure-store/src/test/index.ts b/packages/azure-store/src/test/index.ts index 4df68e4c..358df6b5 100644 --- a/packages/azure-store/src/test/index.ts +++ b/packages/azure-store/src/test/index.ts @@ -1,88 +1,88 @@ -import "should"; -import { strict as assert } from "node:assert"; -import path from "node:path"; -import { AzureStore } from "@tus/azure-store"; -import type { TokenCredential } from "@azure/core-auth"; -import * as shared from "../../../utils/dist/test/stores.js"; +import 'should' +import {strict as assert} from 'node:assert' +import path from 'node:path' +import {AzureStore} from '@tus/azure-store' +import type {TokenCredential} from '@azure/core-auth' +import * as shared from '../../../utils/dist/test/stores.js' -const fixturesPath = path.resolve("../", "../", "test", "fixtures"); -const storePath = path.resolve("../", "../", "test", "output", "azure-store"); +const fixturesPath = path.resolve('../', '../', 'test', 'fixtures') +const storePath = path.resolve('../', '../', 'test', 'output', 'azure-store') -describe("AzureStore", () => { - describe("with Account key", () => { +describe('AzureStore', () => { + describe('with Account key', () => { before(function () { - this.testFileSize = 960_244; - this.testFileName = "test.mp4"; - this.storePath = storePath; - this.testFilePath = path.resolve(fixturesPath, this.testFileName); - }); + this.testFileSize = 960_244 + this.testFileName = 'test.mp4' + this.storePath = storePath + this.testFilePath = path.resolve(fixturesPath, this.testFileName) + }) beforeEach(function () { this.datastore = new AzureStore({ account: process.env.AZURE_ACCOUNT_ID as string, accountKey: process.env.AZURE_ACCOUNT_KEY as string, containerName: process.env.AZURE_CONTAINER_NAME as string, - }); - }); + }) + }) - shared.shouldHaveStoreMethods(); - shared.shouldCreateUploads(); + shared.shouldHaveStoreMethods() + shared.shouldCreateUploads() // shared.shouldRemoveUploads() // Not implemented yet // shared.shouldExpireUploads() // Not implemented yet - shared.shouldWriteUploads(); - shared.shouldHandleOffset(); - shared.shouldDeclareUploadLength(); // Creation-defer-length extension - }); + shared.shouldWriteUploads() + shared.shouldHandleOffset() + shared.shouldDeclareUploadLength() // Creation-defer-length extension + }) - describe("constructor", () => { - it("should accept a TokenCredential instead of accountKey", () => { + describe('constructor', () => { + it('should accept a TokenCredential instead of accountKey', () => { const mockCredential: TokenCredential = { getToken: async () => ({ - token: "mock-token", + token: 'mock-token', expiresOnTimestamp: Date.now() + 3600_000, }), - }; + } const store = new AzureStore({ - account: "testaccount", - containerName: "testcontainer", + account: 'testaccount', + containerName: 'testcontainer', credential: mockCredential, - }); - assert.ok(store); - }); + }) + assert.ok(store) + }) - it("should throw when neither accountKey nor credential is provided", () => { + it('should throw when neither accountKey nor credential is provided', () => { assert.throws( () => new AzureStore({ - account: "testaccount", - containerName: "testcontainer", + account: 'testaccount', + containerName: 'testcontainer', }), /accountKey or credential/ - ); - }); + ) + }) - it("should throw when account is missing", () => { + it('should throw when account is missing', () => { assert.throws( () => new AzureStore({ - account: "", - containerName: "test", - accountKey: "key", + account: '', + containerName: 'test', + accountKey: 'key', }), /account/ - ); - }); + ) + }) - it("should throw when containerName is missing", () => { + it('should throw when containerName is missing', () => { assert.throws( () => new AzureStore({ - account: "test", - containerName: "", - accountKey: "key", + account: 'test', + containerName: '', + accountKey: 'key', }), /container name/ - ); - }); - }); -}); + ) + }) + }) +}) From d72e0706ece826d46d61a4c2aa6c87be273d5526 Mon Sep 17 00:00:00 2001 From: Samuel Adeoye Date: Sat, 14 Feb 2026 13:18:16 -0330 Subject: [PATCH 10/11] Add package lock changes --- package-lock.json | 135 +++++++++++++++------------------------------- 1 file changed, 42 insertions(+), 93 deletions(-) diff --git a/package-lock.json b/package-lock.json index 52ec8c41..b5515ed9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -869,17 +869,17 @@ } }, "node_modules/@azure/core-auth": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.7.2.tgz", - "integrity": "sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.1.tgz", + "integrity": "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.0.0", - "@azure/core-util": "^1.1.0", + "@azure/abort-controller": "^2.1.2", + "@azure/core-util": "^1.13.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@azure/core-auth/node_modules/@azure/abort-controller": { @@ -1046,16 +1046,17 @@ } }, "node_modules/@azure/core-util": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.2.tgz", - "integrity": "sha512-l1Qrqhi4x1aekkV+OlcqsJa4AnAkj5p0JV8omgwjaV9OAbP41lvrMvs+CptfetKkeEaGRGSzby7sjPZEX7+kkQ==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.1.tgz", + "integrity": "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.0.0", + "@azure/abort-controller": "^2.1.2", + "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@azure/core-util/node_modules/@azure/abort-controller": { @@ -2715,16 +2716,6 @@ "resolved": "packages/utils", "link": true }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, "node_modules/@types/caseless": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", @@ -2732,15 +2723,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/connect": { - "version": "3.4.38", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/cookiejar": { "version": "2.1.2", "dev": true, @@ -2754,18 +2736,6 @@ "@types/ms": "*" } }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.41", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, "node_modules/@types/glob": { "version": "8.1.0", "dev": true, @@ -2775,12 +2745,6 @@ "@types/node": "*" } }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/@types/lodash": { "version": "4.17.0", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", @@ -2796,12 +2760,6 @@ "@types/lodash": "*" } }, - "node_modules/@types/mime": { - "version": "1.3.5", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/@types/minimatch": { "version": "5.1.2", "dev": true, @@ -2835,18 +2793,6 @@ "undici-types": "~6.20.0" } }, - "node_modules/@types/qs": { - "version": "6.9.11", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/@types/request": { "version": "2.48.12", "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", @@ -2886,33 +2832,6 @@ "@types/node": "*" } }, - "node_modules/@types/send": { - "version": "0.17.4", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.5", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static/node_modules/@types/mime": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/@types/set-cookie-parser": { "version": "2.4.10", "resolved": "https://registry.npmjs.org/@types/set-cookie-parser/-/set-cookie-parser-2.4.10.tgz", @@ -2969,6 +2888,33 @@ "dev": true, "license": "MIT" }, + "node_modules/@typespec/ts-http-runtime": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.3.tgz", + "integrity": "sha512-91fp6CAAJSRtH5ja95T1FHSKa8aPW9/Zw6cta81jlZTUw/+Vq8jM/AfF/14h2b71wwR84JUTW/3Y8QPhDAawFA==", + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@typespec/ts-http-runtime/node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/abort-controller": { "version": "3.0.0", "dev": true, @@ -3548,6 +3494,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "iconv-lite": "^0.6.2" } @@ -3557,6 +3504,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -6193,6 +6141,7 @@ "version": "2.0.0", "license": "MIT", "dependencies": { + "@azure/core-auth": "^1.9.0", "@azure/storage-blob": "^12.24.0", "@tus/utils": "^0.6.0", "debug": "^4.3.4" From 669215903b73760a28d4a016f15af1366553d59f Mon Sep 17 00:00:00 2001 From: Samuel Adeoye Date: Tue, 24 Feb 2026 10:07:15 -0500 Subject: [PATCH 11/11] Fix comments --- packages/azure-store/src/index.ts | 30 +++++++------ packages/azure-store/src/test/index.ts | 60 +++++++++++++++----------- 2 files changed, 52 insertions(+), 38 deletions(-) diff --git a/packages/azure-store/src/index.ts b/packages/azure-store/src/index.ts index 7dc325c4..8307dfb0 100644 --- a/packages/azure-store/src/index.ts +++ b/packages/azure-store/src/index.ts @@ -18,13 +18,19 @@ import { } from '@azure/storage-blob' import type {TokenCredential} from '@azure/core-auth' -type Options = { - cache?: KvStore - account: string - containerName: string - accountKey?: string - credential?: TokenCredential -} +type Options = + | { + cache?: KvStore + account: string + containerName: string + accountKey: string + } + | { + cache?: KvStore + account: string + containerName: string + credential: TokenCredential + } const log = debug('tus-node-server:stores:azurestore') @@ -49,14 +55,12 @@ export class AzureStore extends DataStore { if (!options.containerName) { throw new Error('Azure store must have a container name') } - if (!options.accountKey && !options.credential) { - throw new Error('Azure store requires either accountKey or credential') - } const storageAccountBaseUrl = `https://${options.account}.blob.core.windows.net` - const credential = options.credential - ? options.credential - : new StorageSharedKeyCredential(options.account, options.accountKey as string) + const credential = + 'credential' in options + ? options.credential + : new StorageSharedKeyCredential(options.account, options.accountKey) this.blobServiceClient = new BlobServiceClient(storageAccountBaseUrl, credential) this.containerClient = this.blobServiceClient.getContainerClient( diff --git a/packages/azure-store/src/test/index.ts b/packages/azure-store/src/test/index.ts index 358df6b5..c3e1026f 100644 --- a/packages/azure-store/src/test/index.ts +++ b/packages/azure-store/src/test/index.ts @@ -9,30 +9,51 @@ const fixturesPath = path.resolve('../', '../', 'test', 'fixtures') const storePath = path.resolve('../', '../', 'test', 'output', 'azure-store') describe('AzureStore', () => { - describe('with Account key', () => { - before(function () { - this.testFileSize = 960_244 - this.testFileName = 'test.mp4' - this.storePath = storePath - this.testFilePath = path.resolve(fixturesPath, this.testFileName) - }) + before(function () { + this.testFileSize = 960_244 + this.testFileName = 'test.mp4' + this.storePath = storePath + this.testFilePath = path.resolve(fixturesPath, this.testFileName) + }) + + beforeEach(function () { + const hasCredentials = + process.env.AZURE_ACCOUNT_ID && + process.env.AZURE_ACCOUNT_KEY && + process.env.AZURE_CONTAINER_NAME - beforeEach(function () { + if (hasCredentials) { this.datastore = new AzureStore({ account: process.env.AZURE_ACCOUNT_ID as string, accountKey: process.env.AZURE_ACCOUNT_KEY as string, containerName: process.env.AZURE_CONTAINER_NAME as string, }) - }) + } else { + const mockCredential: TokenCredential = { + getToken: async () => ({ + token: 'mock-token', + expiresOnTimestamp: Date.now() + 3600_000, + }), + } + this.datastore = new AzureStore({ + account: 'testaccount', + containerName: 'testcontainer', + credential: mockCredential, + }) + } + }) - shared.shouldHaveStoreMethods() + shared.shouldHaveStoreMethods() + if ( + process.env.AZURE_ACCOUNT_ID && + process.env.AZURE_ACCOUNT_KEY && + process.env.AZURE_CONTAINER_NAME + ) { shared.shouldCreateUploads() - // shared.shouldRemoveUploads() // Not implemented yet - // shared.shouldExpireUploads() // Not implemented yet shared.shouldWriteUploads() shared.shouldHandleOffset() - shared.shouldDeclareUploadLength() // Creation-defer-length extension - }) + shared.shouldDeclareUploadLength() + } describe('constructor', () => { it('should accept a TokenCredential instead of accountKey', () => { @@ -50,17 +71,6 @@ describe('AzureStore', () => { assert.ok(store) }) - it('should throw when neither accountKey nor credential is provided', () => { - assert.throws( - () => - new AzureStore({ - account: 'testaccount', - containerName: 'testcontainer', - }), - /accountKey or credential/ - ) - }) - it('should throw when account is missing', () => { assert.throws( () =>