diff --git a/.changeset/config.json b/.changeset/config.json index e0322447..7886c74f 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -7,5 +7,5 @@ "access": "public", "baseBranch": "main", "updateInternalDependencies": "patch", - "ignore": ["demo", "test"] + "ignore": ["test"] } diff --git a/.changeset/gold-adults-warn.md b/.changeset/gold-adults-warn.md new file mode 100644 index 00000000..4c9681aa --- /dev/null +++ b/.changeset/gold-adults-warn.md @@ -0,0 +1,5 @@ +--- +"@tus/s3-store": patch +--- + +Fix zero byte files only storing a .info file. Now correctly stores an empty file. diff --git a/.changeset/proud-terms-swim.md b/.changeset/proud-terms-swim.md new file mode 100644 index 00000000..9d20b0ad --- /dev/null +++ b/.changeset/proud-terms-swim.md @@ -0,0 +1,5 @@ +--- +"@tus/gcs-store": patch +--- + +Correctly pass the content type from upload.metadata to GCS. diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 622efd38..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - root: true, - // This tells ESLint to load the config from the package `eslint-config-custom` - extends: ['custom'], -} diff --git a/.github/contributing.md b/.github/contributing.md index 43d86979..83848764 100644 --- a/.github/contributing.md +++ b/.github/contributing.md @@ -1,9 +1,5 @@ # Contributing -`tus-node-server` is a mono-repository managed by [Turborepo](https://turbo.build/repo). -This means running `npm run build` in the root will build all packages in parallel. The -same goes for `lint` and `format`. - ## Changesets We use [changesets](https://github.com/changesets/changesets) to manage versioning, diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 15f90b60..d4d5178f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,11 +1,12 @@ -name: main +name: CI on: push: branches: [main] pull_request_target: types: [opened, synchronize, reopened] paths-ignore: - - '**.md' + - "**.md" + - ".changeset/**" pull_request: types: [opened, synchronize, reopened] paths: @@ -15,15 +16,8 @@ concurrency: ${{ github.workflow }}--${{ github.ref }} jobs: main: - name: ${{matrix.node}} + name: Node.js LTS runs-on: ubuntu-latest - strategy: - # We do not want to run CRUD tests in parallel - max-parallel: 1 - matrix: - node: - - lts/hydrogen - - node steps: - name: Checkout sources @@ -39,7 +33,7 @@ jobs: - name: Install Node.js uses: actions/setup-node@v3 with: - node-version: ${{matrix.node-version}} + node-version: lts/* - name: Install dependencies run: npm ci --no-fund --no-audit @@ -47,6 +41,9 @@ jobs: - name: Build run: npm run build + - name: Check formatting + run: npm run format:check + - name: Run linters run: npm run lint @@ -56,4 +53,7 @@ jobs: AWS_BUCKET: ${{secrets.AWS_BUCKET}} AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}} AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}} + AZURE_ACCOUNT_ID: ${{secrets.AZURE_ACCOUNT_ID}} + AZURE_ACCOUNT_KEY: ${{secrets.AZURE_ACCOUNT_KEY}} + AZURE_CONTAINER_NAME: ${{secrets.AZURE_CONTAINER_NAME}} AWS_REGION: ${{secrets.AWS_REGION}} diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 1866d7ff..00000000 --- a/.prettierrc.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/prettierrc", - "semi": false, - "singleQuote": true, - "printWidth": 90, - "useTabs": false, - "tabWidth": 2, - "bracketSpacing": false, - "trailingComma": "es5", - "proseWrap": "always" -} diff --git a/.well-known/funding-manifest-urls b/.well-known/funding-manifest-urls new file mode 100644 index 00000000..b46f7405 --- /dev/null +++ b/.well-known/funding-manifest-urls @@ -0,0 +1 @@ +https://tus.io/funding.json diff --git a/README.md b/README.md index e6dc240b..d181d493 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,6 @@ easily be added to tus-node-server - [Quick start](#quick-start) - [Packages](#packages) - [Extensions](#extensions) -- [Demos](#demos) - [Types](#types) - [Compatibility](#compatibility) - [Contribute](#contribute) @@ -49,6 +48,9 @@ integrate it into your existing one. There are also other mature servers, like A standalone server which stores files on disk. +> [!TIP] +> Try it yourself in [StackBlitz](https://stackblitz.com/edit/stackblitz-starters-zg6mgnuf?file=index.js) + ```js const {Server} = require('@tus/server') const {FileStore} = require('@tus/file-store') @@ -100,45 +102,21 @@ fastify.listen(3000, (err) => { - [`@tus/file-store`][]. Store files on disk. - [`@tus/s3-store`][]. Store files on AWS S3. - [`@tus/gcs-store`][]. Store files on Google Cloud Storage. +- [`@tus/azure-store`][]. Store files on Azure. ## Extensions The tus protocol supports optional [extensions][]. Below is a table of the supported extensions. -| Extension | [`file-store`][`@tus/file-store`] | [`s3-store`][`@tus/s3-store`] | [`gcs-store`][`@tus/gcs-store`] | -| ------------------------ | --------------------------------- | ----------------------------- | ------------------------------- | -| [Creation][] | ✅ | ✅ | ✅ | -| [Creation With Upload][] | ✅ | ✅ | ✅ | -| [Expiration][] | ✅ | ✅ | ❌ | -| [Checksum][] | ❌ | ❌ | ❌ | -| [Termination][] | ✅ | ✅ | ❌ | -| [Concatenation][] | ❌ | ❌ | ❌ | - -## Demos - -Start the demo server using Local File Storage - -```bash -npm run build && npm run demo -``` - -Start up the demo server using AWS S3. The environment variables `AWS_BUCKET`, -`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_REGION` need to be present. - -```bash -npm run build && npm run demo:s3 -``` - -Start up the demo server using Google Cloud Storage. A `keyfile.json` needs to be present -in the root of the repository. - -```bash -npm run build && npm run demo:gcs -``` - -Then navigate to the demo ([localhost:1080](http://localhost:1080)) which uses -[`tus-js-client`](https://github.com/tus/tus-js-client). +| Extension | [`file-store`][`@tus/file-store`] | [`s3-store`][`@tus/s3-store`] | [`gcs-store`][`@tus/gcs-store`] | [`azure-store`][`@tus/azure-store`] | +| ------------------------ | --------------------------------- | ----------------------------- | ------------------------------- | ----------------------------------- | +| [Creation][] | ✅ | ✅ | ✅ | ✅ | +| [Creation With Upload][] | ✅ | ✅ | ✅ | ✅ | +| [Expiration][] | ✅ | ✅ | ❌ | ❌ | +| [Checksum][] | ❌ | ❌ | ❌ | ❌ | +| [Termination][] | ✅ | ✅ | ❌ | ❌ | +| [Concatenation][] | ❌ | ❌ | ❌ | ❌ | ## Types @@ -163,6 +141,7 @@ See [`@tus/file-store`]: https://github.com/tus/tus-node-server/tree/main/packages/file-store [`@tus/s3-store`]: https://github.com/tus/tus-node-server/tree/main/packages/s3-store [`@tus/gcs-store`]: https://github.com/tus/tus-node-server/tree/main/packages/gcs-store +[`@tus/azure-store`]: https://github.com/tus/tus-node-server/tree/main/packages/azure-store [extensions]: https://tus.io/protocols/resumable-upload.html#protocol-extensions [creation]: https://tus.io/protocols/resumable-upload.html#creation [creation with upload]: diff --git a/biome.json b/biome.json new file mode 100644 index 00000000..d78b0720 --- /dev/null +++ b/biome.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json", + "organizeImports": { + "enabled": true + }, + "files": { + "ignore": ["./**/dist/**/*"] + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "style": { + "noParameterAssign": "off" + } + } + }, + "formatter": { + "enabled": true, + "formatWithErrors": false, + "indentStyle": "space", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 90 + }, + "json": { + "linter": { + "enabled": false + }, + "formatter": { + "enabled": false + } + }, + "javascript": { + "formatter": { + "trailingCommas": "es5", + "semicolons": "asNeeded", + "bracketSpacing": false, + "quoteStyle": "single" + } + } +} diff --git a/demo/package.json b/demo/package.json deleted file mode 100644 index 832cdacd..00000000 --- a/demo/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/package.json", - "name": "demo", - "private": true, - "scripts": { - "start": "node server.js", - "start:gcs": "cross-env DATA_STORE=GCSDataStore node server.js", - "start:s3": "cross-env DATA_STORE=S3Store node server.js" - }, - "dependencies": { - "@tus/file-store": "^1.4.0", - "@tus/gcs-store": "^1.3.0", - "@tus/s3-store": "^1.5.0", - "@tus/server": "^1.7.0", - "tus-js-client": "^2.3.2" - }, - "devDependencies": { - "cross-env": "^7.0.3" - } -} diff --git a/demo/server.js b/demo/server.js deleted file mode 100644 index 75c97f7c..00000000 --- a/demo/server.js +++ /dev/null @@ -1,117 +0,0 @@ -'use strict' - -const path = require('path') -const fs = require('fs') -const assert = require('assert') - -const {Server, EVENTS} = require('@tus/server') -const {GCSDataStore} = require('@tus/gcs-store') -const {S3Store} = require('@tus/s3-store') -const {FileStore} = require('@tus/file-store') - -const stores = { - GCSDataStore: () => - new GCSDataStore({ - projectId: 'vimeo-open-source', - keyFilename: path.resolve(__dirname, '../keyfile.json'), - bucket: 'tus-node-server', - }), - S3Store: () => { - assert.ok( - process.env.AWS_ACCESS_KEY_ID, - 'environment variable `AWS_ACCESS_KEY_ID` must be set' - ) - assert.ok( - process.env.AWS_SECRET_ACCESS_KEY, - 'environment variable `AWS_SECRET_ACCESS_KEY` must be set' - ) - assert.ok(process.env.AWS_BUCKET, 'environment variable `AWS_BUCKET` must be set') - assert.ok(process.env.AWS_REGION, 'environment variable `AWS_REGION` must be set') - - return new S3Store({ - partSize: 8 * 1024 * 1024, // each uploaded part will have ~8MiB, - s3ClientConfig: { - bucket: process.env.AWS_BUCKET, - accessKeyId: process.env.AWS_ACCESS_KEY_ID, - secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, - region: process.env.AWS_REGION, - }, - }) - }, - FileStore: () => new FileStore({directory: './files'}), -} -const storeName = process.env.DATA_STORE || 'FileStore' -const store = stores[storeName] -const server = new Server({path: '/files', datastore: store()}) - -/** - * Basic GET handler to serve the demo html/js - * - * @param {object} req http.incomingMessage - * @param {object} res http.ServerResponse - */ -const writeFile = (req, res) => { - // Determine file to serve - let filename = req.url - if (filename == '/') { - filename = '/index.html' - } - if (!filename.startsWith('/dist/')) { - filename = '/demos/browser' + filename - } - filename = path.join(process.cwd(), '../node_modules/tus-js-client', filename) - fs.readFile(filename, 'binary', (err, file) => { - if (err) { - res.writeHead(500, {'Content-Type': 'text/plain'}) - res.write(err) - res.end() - return - } - - // Update demo URL to point to our local server - file = file.replace( - 'https://tusd.tusdemo.net/files/', - `http://${host}:${port}/files/` - ) - - res.writeHead(200) - res.write(file) - res.end() - }) -} - -// Define routes to serve the demo html/js files. -server.get('/', writeFile) -server.get('/index.html', writeFile) -server.get('/demo.js', writeFile) -server.get('/demo.css', writeFile) -server.get('/video.html', writeFile) -server.get('/video.js', writeFile) -server.get('/dist/tus.js', writeFile) -server.get('/dist/tus.js.map', writeFile) -server.get('/dist/tus.min.js', writeFile) -server.get('/dist/tus.min.js.map', writeFile) - -server.on(EVENTS.EVENT_UPLOAD_COMPLETE, (event) => { - console.log( - `[${new Date().toLocaleTimeString()}] [EVENT HOOK] Upload complete for file ${ - event.file.id - }` - ) -}) - -// // this is the express stile ;) -// const express = require('express'); -// const app = express(); -// const uploadApp = express(); -// uploadApp.all('*', server.handle.bind(server)); -// app.use('/uploads', uploadApp); -// app.get('*', writeFile); - -const host = '127.0.0.1' -const port = 1080 -server.listen({host, port}, () => { - console.log( - `[${new Date().toLocaleTimeString()}] tus server listening at http://${host}:${port} using ${storeName}` - ) -}) diff --git a/package-lock.json b/package-lock.json index 0ca04ba0..be97665c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,898 +1,816 @@ { "name": "tus-node-server", - "version": "0.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "version": "0.0.0", "workspaces": [ "packages/*", - "demo", "test" ], "devDependencies": { + "@biomejs/biome": "1.9.4", "@changesets/changelog-github": "^0.5.0", - "@changesets/cli": "^2.27.1", - "eslint": "^8.57.0", - "eslint-config-custom": "^0.0.0", - "eslint-plugin-prettier": "^4.2.1", - "prettier": "^2.8.8", - "turbo": "^1.13.0", - "typescript": "^5.5.4" - } - }, - "demo": { - "dependencies": { - "@tus/file-store": "^1.4.0", - "@tus/gcs-store": "^1.3.0", - "@tus/s3-store": "^1.5.0", - "@tus/server": "^1.7.0", - "tus-js-client": "^2.3.2" - }, - "devDependencies": { - "cross-env": "^7.0.3" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "@changesets/cli": "^2.27.10", + "typescript": "^5.6.2" } }, "node_modules/@aws-crypto/crc32": { - "version": "3.0.0", + "version": "5.2.0", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/util": "^3.0.0", + "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/crc32/node_modules/@aws-sdk/types": { - "version": "3.370.0", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/crc32/node_modules/@aws-sdk/types/node_modules/tslib": { - "version": "2.6.0", - "license": "0BSD" - }, - "node_modules/@aws-crypto/crc32/node_modules/@smithy/types": { - "version": "1.1.1", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-crypto/crc32/node_modules/@smithy/types/node_modules/tslib": { - "version": "2.6.0", - "license": "0BSD" - }, - "node_modules/@aws-crypto/crc32/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" - }, "node_modules/@aws-crypto/crc32c": { - "version": "3.0.0", + "version": "5.2.0", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/util": "^3.0.0", + "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" + "tslib": "^2.6.2" } }, - "node_modules/@aws-crypto/crc32c/node_modules/@aws-sdk/types": { - "version": "3.370.0", + "node_modules/@aws-crypto/sha1-browser": { + "version": "5.2.0", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" } }, - "node_modules/@aws-crypto/crc32c/node_modules/@aws-sdk/types/node_modules/tslib": { - "version": "2.6.0", - "license": "0BSD" - }, - "node_modules/@aws-crypto/crc32c/node_modules/@smithy/types": { - "version": "1.1.1", + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-crypto/crc32c/node_modules/@smithy/types/node_modules/tslib": { - "version": "2.6.0", - "license": "0BSD" - }, - "node_modules/@aws-crypto/crc32c/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" - }, - "node_modules/@aws-crypto/ie11-detection": { - "version": "3.0.0", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" - }, - "node_modules/@aws-crypto/sha1-browser": { - "version": "3.0.0", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/ie11-detection": "^3.0.0", - "@aws-crypto/supports-web-crypto": "^3.0.0", - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@aws-sdk/types": { - "version": "3.370.0", + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@aws-sdk/types/node_modules/tslib": { - "version": "2.6.0", - "license": "0BSD" - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/types": { - "version": "1.1.1", + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/types/node_modules/tslib": { - "version": "2.6.0", - "license": "0BSD" - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" - }, "node_modules/@aws-crypto/sha256-browser": { - "version": "3.0.0", + "version": "5.2.0", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/ie11-detection": "^3.0.0", - "@aws-crypto/sha256-js": "^3.0.0", - "@aws-crypto/supports-web-crypto": "^3.0.0", - "@aws-crypto/util": "^3.0.0", + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-locate-window": "^3.0.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" } }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@aws-sdk/types": { - "version": "3.370.0", + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@aws-sdk/types/node_modules/tslib": { - "version": "2.6.0", - "license": "0BSD" - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/types": { - "version": "1.1.1", + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/types/node_modules/tslib": { - "version": "2.6.0", - "license": "0BSD" - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" - }, - "node_modules/@aws-crypto/sha256-js": { - "version": "3.0.0", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/util": "^3.0.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@aws-crypto/sha256-js/node_modules/@aws-sdk/types": { - "version": "3.370.0", + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-crypto/sha256-js/node_modules/@aws-sdk/types/node_modules/tslib": { - "version": "2.6.0", - "license": "0BSD" - }, - "node_modules/@aws-crypto/sha256-js/node_modules/@smithy/types": { - "version": "1.1.1", + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-crypto/sha256-js/node_modules/@smithy/types/node_modules/tslib": { - "version": "2.6.0", - "license": "0BSD" - }, - "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" - }, "node_modules/@aws-crypto/supports-web-crypto": { - "version": "3.0.0", + "version": "5.2.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^1.11.1" + "tslib": "^2.6.2" } }, - "node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" - }, "node_modules/@aws-crypto/util": { - "version": "3.0.0", + "version": "5.2.0", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" } }, - "node_modules/@aws-crypto/util/node_modules/@aws-sdk/types": { - "version": "3.370.0", + "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^1.1.0", - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-crypto/util/node_modules/@aws-sdk/types/node_modules/tslib": { - "version": "2.6.0", - "license": "0BSD" - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/types": { - "version": "1.1.1", + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-crypto/util/node_modules/@smithy/types/node_modules/tslib": { - "version": "2.6.0", - "license": "0BSD" - }, - "node_modules/@aws-crypto/util/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" - }, - "node_modules/@aws-sdk/client-s3": { - "version": "3.490.0", + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/sha1-browser": "3.0.0", - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.490.0", - "@aws-sdk/core": "3.490.0", - "@aws-sdk/credential-provider-node": "3.490.0", - "@aws-sdk/middleware-bucket-endpoint": "3.489.0", - "@aws-sdk/middleware-expect-continue": "3.489.0", - "@aws-sdk/middleware-flexible-checksums": "3.489.0", - "@aws-sdk/middleware-host-header": "3.489.0", - "@aws-sdk/middleware-location-constraint": "3.489.0", - "@aws-sdk/middleware-logger": "3.489.0", - "@aws-sdk/middleware-recursion-detection": "3.489.0", - "@aws-sdk/middleware-sdk-s3": "3.489.0", - "@aws-sdk/middleware-signing": "3.489.0", - "@aws-sdk/middleware-ssec": "3.489.0", - "@aws-sdk/middleware-user-agent": "3.489.0", - "@aws-sdk/region-config-resolver": "3.489.0", - "@aws-sdk/signature-v4-multi-region": "3.489.0", - "@aws-sdk/types": "3.489.0", - "@aws-sdk/util-endpoints": "3.489.0", - "@aws-sdk/util-user-agent-browser": "3.489.0", - "@aws-sdk/util-user-agent-node": "3.489.0", - "@aws-sdk/xml-builder": "3.485.0", - "@smithy/config-resolver": "^2.0.23", - "@smithy/core": "^1.2.2", - "@smithy/eventstream-serde-browser": "^2.0.16", - "@smithy/eventstream-serde-config-resolver": "^2.0.16", - "@smithy/eventstream-serde-node": "^2.0.16", - "@smithy/fetch-http-handler": "^2.3.2", - "@smithy/hash-blob-browser": "^2.0.17", - "@smithy/hash-node": "^2.0.18", - "@smithy/hash-stream-node": "^2.0.18", - "@smithy/invalid-dependency": "^2.0.16", - "@smithy/md5-js": "^2.0.18", - "@smithy/middleware-content-length": "^2.0.18", - "@smithy/middleware-endpoint": "^2.3.0", - "@smithy/middleware-retry": "^2.0.26", - "@smithy/middleware-serde": "^2.0.16", - "@smithy/middleware-stack": "^2.0.10", - "@smithy/node-config-provider": "^2.1.9", - "@smithy/node-http-handler": "^2.2.2", - "@smithy/protocol-http": "^3.0.12", - "@smithy/smithy-client": "^2.2.1", - "@smithy/types": "^2.8.0", - "@smithy/url-parser": "^2.0.16", - "@smithy/util-base64": "^2.0.1", - "@smithy/util-body-length-browser": "^2.0.1", - "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.24", - "@smithy/util-defaults-mode-node": "^2.0.32", - "@smithy/util-endpoints": "^1.0.8", - "@smithy/util-retry": "^2.0.9", - "@smithy/util-stream": "^2.0.24", - "@smithy/util-utf8": "^2.0.2", - "@smithy/util-waiter": "^2.0.16", - "fast-xml-parser": "4.2.5", - "tslib": "^2.5.0" + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=14.0.0" } }, + "node_modules/@aws-sdk/client-s3": { + "version": "3.717.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha1-browser": "5.2.0", + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.716.0", + "@aws-sdk/client-sts": "3.716.0", + "@aws-sdk/core": "3.716.0", + "@aws-sdk/credential-provider-node": "3.716.0", + "@aws-sdk/middleware-bucket-endpoint": "3.714.0", + "@aws-sdk/middleware-expect-continue": "3.714.0", + "@aws-sdk/middleware-flexible-checksums": "3.717.0", + "@aws-sdk/middleware-host-header": "3.714.0", + "@aws-sdk/middleware-location-constraint": "3.714.0", + "@aws-sdk/middleware-logger": "3.714.0", + "@aws-sdk/middleware-recursion-detection": "3.714.0", + "@aws-sdk/middleware-sdk-s3": "3.716.0", + "@aws-sdk/middleware-ssec": "3.714.0", + "@aws-sdk/middleware-user-agent": "3.716.0", + "@aws-sdk/region-config-resolver": "3.714.0", + "@aws-sdk/signature-v4-multi-region": "3.716.0", + "@aws-sdk/types": "3.714.0", + "@aws-sdk/util-endpoints": "3.714.0", + "@aws-sdk/util-user-agent-browser": "3.714.0", + "@aws-sdk/util-user-agent-node": "3.716.0", + "@aws-sdk/xml-builder": "3.709.0", + "@smithy/config-resolver": "^3.0.13", + "@smithy/core": "^2.5.5", + "@smithy/eventstream-serde-browser": "^3.0.14", + "@smithy/eventstream-serde-config-resolver": "^3.0.11", + "@smithy/eventstream-serde-node": "^3.0.13", + "@smithy/fetch-http-handler": "^4.1.2", + "@smithy/hash-blob-browser": "^3.1.10", + "@smithy/hash-node": "^3.0.11", + "@smithy/hash-stream-node": "^3.1.10", + "@smithy/invalid-dependency": "^3.0.11", + "@smithy/md5-js": "^3.0.11", + "@smithy/middleware-content-length": "^3.0.13", + "@smithy/middleware-endpoint": "^3.2.6", + "@smithy/middleware-retry": "^3.0.31", + "@smithy/middleware-serde": "^3.0.11", + "@smithy/middleware-stack": "^3.0.11", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/node-http-handler": "^3.3.2", + "@smithy/protocol-http": "^4.1.8", + "@smithy/smithy-client": "^3.5.1", + "@smithy/types": "^3.7.2", + "@smithy/url-parser": "^3.0.11", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.31", + "@smithy/util-defaults-mode-node": "^3.0.31", + "@smithy/util-endpoints": "^2.1.7", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-retry": "^3.0.11", + "@smithy/util-stream": "^3.3.2", + "@smithy/util-utf8": "^3.0.0", + "@smithy/util-waiter": "^3.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/@aws-sdk/client-sso": { - "version": "3.490.0", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/core": "3.490.0", - "@aws-sdk/middleware-host-header": "3.489.0", - "@aws-sdk/middleware-logger": "3.489.0", - "@aws-sdk/middleware-recursion-detection": "3.489.0", - "@aws-sdk/middleware-user-agent": "3.489.0", - "@aws-sdk/region-config-resolver": "3.489.0", - "@aws-sdk/types": "3.489.0", - "@aws-sdk/util-endpoints": "3.489.0", - "@aws-sdk/util-user-agent-browser": "3.489.0", - "@aws-sdk/util-user-agent-node": "3.489.0", - "@smithy/config-resolver": "^2.0.23", - "@smithy/core": "^1.2.2", - "@smithy/fetch-http-handler": "^2.3.2", - "@smithy/hash-node": "^2.0.18", - "@smithy/invalid-dependency": "^2.0.16", - "@smithy/middleware-content-length": "^2.0.18", - "@smithy/middleware-endpoint": "^2.3.0", - "@smithy/middleware-retry": "^2.0.26", - "@smithy/middleware-serde": "^2.0.16", - "@smithy/middleware-stack": "^2.0.10", - "@smithy/node-config-provider": "^2.1.9", - "@smithy/node-http-handler": "^2.2.2", - "@smithy/protocol-http": "^3.0.12", - "@smithy/smithy-client": "^2.2.1", - "@smithy/types": "^2.8.0", - "@smithy/url-parser": "^2.0.16", - "@smithy/util-base64": "^2.0.1", - "@smithy/util-body-length-browser": "^2.0.1", - "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.24", - "@smithy/util-defaults-mode-node": "^2.0.32", - "@smithy/util-endpoints": "^1.0.8", - "@smithy/util-retry": "^2.0.9", - "@smithy/util-utf8": "^2.0.2", - "tslib": "^2.5.0" + "version": "3.716.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.716.0", + "@aws-sdk/middleware-host-header": "3.714.0", + "@aws-sdk/middleware-logger": "3.714.0", + "@aws-sdk/middleware-recursion-detection": "3.714.0", + "@aws-sdk/middleware-user-agent": "3.716.0", + "@aws-sdk/region-config-resolver": "3.714.0", + "@aws-sdk/types": "3.714.0", + "@aws-sdk/util-endpoints": "3.714.0", + "@aws-sdk/util-user-agent-browser": "3.714.0", + "@aws-sdk/util-user-agent-node": "3.716.0", + "@smithy/config-resolver": "^3.0.13", + "@smithy/core": "^2.5.5", + "@smithy/fetch-http-handler": "^4.1.2", + "@smithy/hash-node": "^3.0.11", + "@smithy/invalid-dependency": "^3.0.11", + "@smithy/middleware-content-length": "^3.0.13", + "@smithy/middleware-endpoint": "^3.2.6", + "@smithy/middleware-retry": "^3.0.31", + "@smithy/middleware-serde": "^3.0.11", + "@smithy/middleware-stack": "^3.0.11", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/node-http-handler": "^3.3.2", + "@smithy/protocol-http": "^4.1.8", + "@smithy/smithy-client": "^3.5.1", + "@smithy/types": "^3.7.2", + "@smithy/url-parser": "^3.0.11", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.31", + "@smithy/util-defaults-mode-node": "^3.0.31", + "@smithy/util-endpoints": "^2.1.7", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-retry": "^3.0.11", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/client-sso-oidc": { + "version": "3.716.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.716.0", + "@aws-sdk/credential-provider-node": "3.716.0", + "@aws-sdk/middleware-host-header": "3.714.0", + "@aws-sdk/middleware-logger": "3.714.0", + "@aws-sdk/middleware-recursion-detection": "3.714.0", + "@aws-sdk/middleware-user-agent": "3.716.0", + "@aws-sdk/region-config-resolver": "3.714.0", + "@aws-sdk/types": "3.714.0", + "@aws-sdk/util-endpoints": "3.714.0", + "@aws-sdk/util-user-agent-browser": "3.714.0", + "@aws-sdk/util-user-agent-node": "3.716.0", + "@smithy/config-resolver": "^3.0.13", + "@smithy/core": "^2.5.5", + "@smithy/fetch-http-handler": "^4.1.2", + "@smithy/hash-node": "^3.0.11", + "@smithy/invalid-dependency": "^3.0.11", + "@smithy/middleware-content-length": "^3.0.13", + "@smithy/middleware-endpoint": "^3.2.6", + "@smithy/middleware-retry": "^3.0.31", + "@smithy/middleware-serde": "^3.0.11", + "@smithy/middleware-stack": "^3.0.11", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/node-http-handler": "^3.3.2", + "@smithy/protocol-http": "^4.1.8", + "@smithy/smithy-client": "^3.5.1", + "@smithy/types": "^3.7.2", + "@smithy/url-parser": "^3.0.11", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.31", + "@smithy/util-defaults-mode-node": "^3.0.31", + "@smithy/util-endpoints": "^2.1.7", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-retry": "^3.0.11", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" }, - "engines": { - "node": ">=14.0.0" + "peerDependencies": { + "@aws-sdk/client-sts": "^3.716.0" } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.490.0", + "version": "3.716.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/client-sso-oidc": "3.716.0", + "@aws-sdk/core": "3.716.0", + "@aws-sdk/credential-provider-node": "3.716.0", + "@aws-sdk/middleware-host-header": "3.714.0", + "@aws-sdk/middleware-logger": "3.714.0", + "@aws-sdk/middleware-recursion-detection": "3.714.0", + "@aws-sdk/middleware-user-agent": "3.716.0", + "@aws-sdk/region-config-resolver": "3.714.0", + "@aws-sdk/types": "3.714.0", + "@aws-sdk/util-endpoints": "3.714.0", + "@aws-sdk/util-user-agent-browser": "3.714.0", + "@aws-sdk/util-user-agent-node": "3.716.0", + "@smithy/config-resolver": "^3.0.13", + "@smithy/core": "^2.5.5", + "@smithy/fetch-http-handler": "^4.1.2", + "@smithy/hash-node": "^3.0.11", + "@smithy/invalid-dependency": "^3.0.11", + "@smithy/middleware-content-length": "^3.0.13", + "@smithy/middleware-endpoint": "^3.2.6", + "@smithy/middleware-retry": "^3.0.31", + "@smithy/middleware-serde": "^3.0.11", + "@smithy/middleware-stack": "^3.0.11", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/node-http-handler": "^3.3.2", + "@smithy/protocol-http": "^4.1.8", + "@smithy/smithy-client": "^3.5.1", + "@smithy/types": "^3.7.2", + "@smithy/url-parser": "^3.0.11", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-body-length-node": "^3.0.0", + "@smithy/util-defaults-mode-browser": "^3.0.31", + "@smithy/util-defaults-mode-node": "^3.0.31", + "@smithy/util-endpoints": "^2.1.7", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-retry": "^3.0.11", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.716.0", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/core": "3.490.0", - "@aws-sdk/credential-provider-node": "3.490.0", - "@aws-sdk/middleware-host-header": "3.489.0", - "@aws-sdk/middleware-logger": "3.489.0", - "@aws-sdk/middleware-recursion-detection": "3.489.0", - "@aws-sdk/middleware-user-agent": "3.489.0", - "@aws-sdk/region-config-resolver": "3.489.0", - "@aws-sdk/types": "3.489.0", - "@aws-sdk/util-endpoints": "3.489.0", - "@aws-sdk/util-user-agent-browser": "3.489.0", - "@aws-sdk/util-user-agent-node": "3.489.0", - "@smithy/config-resolver": "^2.0.23", - "@smithy/core": "^1.2.2", - "@smithy/fetch-http-handler": "^2.3.2", - "@smithy/hash-node": "^2.0.18", - "@smithy/invalid-dependency": "^2.0.16", - "@smithy/middleware-content-length": "^2.0.18", - "@smithy/middleware-endpoint": "^2.3.0", - "@smithy/middleware-retry": "^2.0.26", - "@smithy/middleware-serde": "^2.0.16", - "@smithy/middleware-stack": "^2.0.10", - "@smithy/node-config-provider": "^2.1.9", - "@smithy/node-http-handler": "^2.2.2", - "@smithy/protocol-http": "^3.0.12", - "@smithy/smithy-client": "^2.2.1", - "@smithy/types": "^2.8.0", - "@smithy/url-parser": "^2.0.16", - "@smithy/util-base64": "^2.0.1", - "@smithy/util-body-length-browser": "^2.0.1", - "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.24", - "@smithy/util-defaults-mode-node": "^2.0.32", - "@smithy/util-endpoints": "^1.0.8", - "@smithy/util-middleware": "^2.0.9", - "@smithy/util-retry": "^2.0.9", - "@smithy/util-utf8": "^2.0.2", - "fast-xml-parser": "4.2.5", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.714.0", + "@smithy/core": "^2.5.5", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/property-provider": "^3.1.11", + "@smithy/protocol-http": "^4.1.8", + "@smithy/signature-v4": "^4.2.4", + "@smithy/smithy-client": "^3.5.1", + "@smithy/types": "^3.7.2", + "@smithy/util-middleware": "^3.0.11", + "fast-xml-parser": "4.4.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/core": { - "version": "3.490.0", + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.716.0", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^1.2.2", - "@smithy/protocol-http": "^3.0.12", - "@smithy/signature-v4": "^2.0.0", - "@smithy/smithy-client": "^2.2.1", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/core": "3.716.0", + "@aws-sdk/types": "3.714.0", + "@smithy/property-provider": "^3.1.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.489.0", + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.716.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/core": "3.716.0", + "@aws-sdk/types": "3.714.0", + "@smithy/fetch-http-handler": "^4.1.2", + "@smithy/node-http-handler": "^3.3.2", + "@smithy/property-provider": "^3.1.11", + "@smithy/protocol-http": "^4.1.8", + "@smithy/smithy-client": "^3.5.1", + "@smithy/types": "^3.7.2", + "@smithy/util-stream": "^3.3.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.490.0", + "version": "3.716.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.489.0", - "@aws-sdk/credential-provider-process": "3.489.0", - "@aws-sdk/credential-provider-sso": "3.490.0", - "@aws-sdk/credential-provider-web-identity": "3.489.0", - "@aws-sdk/types": "3.489.0", - "@smithy/credential-provider-imds": "^2.0.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/core": "3.716.0", + "@aws-sdk/credential-provider-env": "3.716.0", + "@aws-sdk/credential-provider-http": "3.716.0", + "@aws-sdk/credential-provider-process": "3.716.0", + "@aws-sdk/credential-provider-sso": "3.716.0", + "@aws-sdk/credential-provider-web-identity": "3.716.0", + "@aws-sdk/types": "3.714.0", + "@smithy/credential-provider-imds": "^3.2.8", + "@smithy/property-provider": "^3.1.11", + "@smithy/shared-ini-file-loader": "^3.1.12", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.716.0" } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.490.0", + "version": "3.716.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.489.0", - "@aws-sdk/credential-provider-ini": "3.490.0", - "@aws-sdk/credential-provider-process": "3.489.0", - "@aws-sdk/credential-provider-sso": "3.490.0", - "@aws-sdk/credential-provider-web-identity": "3.489.0", - "@aws-sdk/types": "3.489.0", - "@smithy/credential-provider-imds": "^2.0.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/credential-provider-env": "3.716.0", + "@aws-sdk/credential-provider-http": "3.716.0", + "@aws-sdk/credential-provider-ini": "3.716.0", + "@aws-sdk/credential-provider-process": "3.716.0", + "@aws-sdk/credential-provider-sso": "3.716.0", + "@aws-sdk/credential-provider-web-identity": "3.716.0", + "@aws-sdk/types": "3.714.0", + "@smithy/credential-provider-imds": "^3.2.8", + "@smithy/property-provider": "^3.1.11", + "@smithy/shared-ini-file-loader": "^3.1.12", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.489.0", + "version": "3.716.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/core": "3.716.0", + "@aws-sdk/types": "3.714.0", + "@smithy/property-provider": "^3.1.11", + "@smithy/shared-ini-file-loader": "^3.1.12", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.490.0", + "version": "3.716.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.490.0", - "@aws-sdk/token-providers": "3.489.0", - "@aws-sdk/types": "3.489.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/client-sso": "3.716.0", + "@aws-sdk/core": "3.716.0", + "@aws-sdk/token-providers": "3.714.0", + "@aws-sdk/types": "3.714.0", + "@smithy/property-provider": "^3.1.11", + "@smithy/shared-ini-file-loader": "^3.1.12", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.489.0", + "version": "3.716.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/core": "3.716.0", + "@aws-sdk/types": "3.714.0", + "@smithy/property-provider": "^3.1.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.716.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.489.0", + "version": "3.714.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@aws-sdk/util-arn-parser": "3.465.0", - "@smithy/node-config-provider": "^2.1.9", - "@smithy/protocol-http": "^3.0.12", - "@smithy/types": "^2.8.0", - "@smithy/util-config-provider": "^2.1.0", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.714.0", + "@aws-sdk/util-arn-parser": "3.693.0", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "@smithy/util-config-provider": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.489.0", + "version": "3.714.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@smithy/protocol-http": "^3.0.12", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.714.0", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.489.0", + "version": "3.717.0", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/crc32": "3.0.0", - "@aws-crypto/crc32c": "3.0.0", - "@aws-sdk/types": "3.489.0", - "@smithy/is-array-buffer": "^2.0.0", - "@smithy/protocol-http": "^3.0.12", - "@smithy/types": "^2.8.0", - "@smithy/util-utf8": "^2.0.2", - "tslib": "^2.5.0" + "@aws-crypto/crc32": "5.2.0", + "@aws-crypto/crc32c": "5.2.0", + "@aws-crypto/util": "5.2.0", + "@aws-sdk/core": "3.716.0", + "@aws-sdk/types": "3.714.0", + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-stream": "^3.3.2", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.489.0", + "version": "3.714.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@smithy/protocol-http": "^3.0.12", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.714.0", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.489.0", + "version": "3.714.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.714.0", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.489.0", + "version": "3.714.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.714.0", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.489.0", + "version": "3.714.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@smithy/protocol-http": "^3.0.12", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.714.0", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.489.0", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.489.0", - "@aws-sdk/util-arn-parser": "3.465.0", - "@smithy/node-config-provider": "^2.1.9", - "@smithy/protocol-http": "^3.0.12", - "@smithy/signature-v4": "^2.0.0", - "@smithy/smithy-client": "^2.2.1", - "@smithy/types": "^2.8.0", - "@smithy/util-config-provider": "^2.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/middleware-signing": { - "version": "3.489.0", + "version": "3.716.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@smithy/property-provider": "^2.0.0", - "@smithy/protocol-http": "^3.0.12", - "@smithy/signature-v4": "^2.0.0", - "@smithy/types": "^2.8.0", - "@smithy/util-middleware": "^2.0.9", - "tslib": "^2.5.0" + "@aws-sdk/core": "3.716.0", + "@aws-sdk/types": "3.714.0", + "@aws-sdk/util-arn-parser": "3.693.0", + "@smithy/core": "^2.5.5", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/protocol-http": "^4.1.8", + "@smithy/signature-v4": "^4.2.4", + "@smithy/smithy-client": "^3.5.1", + "@smithy/types": "^3.7.2", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-stream": "^3.3.2", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.489.0", + "version": "3.714.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.714.0", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.489.0", + "version": "3.716.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@aws-sdk/util-endpoints": "3.489.0", - "@smithy/protocol-http": "^3.0.12", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/core": "3.716.0", + "@aws-sdk/types": "3.714.0", + "@aws-sdk/util-endpoints": "3.714.0", + "@smithy/core": "^2.5.5", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.489.0", + "version": "3.714.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@smithy/node-config-provider": "^2.1.9", - "@smithy/types": "^2.8.0", - "@smithy/util-config-provider": "^2.1.0", - "@smithy/util-middleware": "^2.0.9", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.714.0", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/types": "^3.7.2", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.11", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.489.0", + "version": "3.716.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.489.0", - "@aws-sdk/types": "3.489.0", - "@smithy/protocol-http": "^3.0.12", - "@smithy/signature-v4": "^2.0.0", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/middleware-sdk-s3": "3.716.0", + "@aws-sdk/types": "3.714.0", + "@smithy/protocol-http": "^4.1.8", + "@smithy/signature-v4": "^4.2.4", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.489.0", + "version": "3.714.0", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/middleware-host-header": "3.489.0", - "@aws-sdk/middleware-logger": "3.489.0", - "@aws-sdk/middleware-recursion-detection": "3.489.0", - "@aws-sdk/middleware-user-agent": "3.489.0", - "@aws-sdk/region-config-resolver": "3.489.0", - "@aws-sdk/types": "3.489.0", - "@aws-sdk/util-endpoints": "3.489.0", - "@aws-sdk/util-user-agent-browser": "3.489.0", - "@aws-sdk/util-user-agent-node": "3.489.0", - "@smithy/config-resolver": "^2.0.23", - "@smithy/fetch-http-handler": "^2.3.2", - "@smithy/hash-node": "^2.0.18", - "@smithy/invalid-dependency": "^2.0.16", - "@smithy/middleware-content-length": "^2.0.18", - "@smithy/middleware-endpoint": "^2.3.0", - "@smithy/middleware-retry": "^2.0.26", - "@smithy/middleware-serde": "^2.0.16", - "@smithy/middleware-stack": "^2.0.10", - "@smithy/node-config-provider": "^2.1.9", - "@smithy/node-http-handler": "^2.2.2", - "@smithy/property-provider": "^2.0.0", - "@smithy/protocol-http": "^3.0.12", - "@smithy/shared-ini-file-loader": "^2.0.6", - "@smithy/smithy-client": "^2.2.1", - "@smithy/types": "^2.8.0", - "@smithy/url-parser": "^2.0.16", - "@smithy/util-base64": "^2.0.1", - "@smithy/util-body-length-browser": "^2.0.1", - "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.24", - "@smithy/util-defaults-mode-node": "^2.0.32", - "@smithy/util-endpoints": "^1.0.8", - "@smithy/util-retry": "^2.0.9", - "@smithy/util-utf8": "^2.0.2", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.714.0", + "@smithy/property-provider": "^3.1.11", + "@smithy/shared-ini-file-loader": "^3.1.12", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sso-oidc": "^3.714.0" } }, "node_modules/@aws-sdk/types": { - "version": "3.489.0", + "version": "3.714.0", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/util-arn-parser": { - "version": "3.465.0", + "version": "3.693.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.489.0", + "version": "3.714.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@smithy/types": "^2.8.0", - "@smithy/util-endpoints": "^1.0.8", - "tslib": "^2.5.0" + "@aws-sdk/types": "3.714.0", + "@smithy/types": "^3.7.2", + "@smithy/util-endpoints": "^2.1.7", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/util-locate-window": { - "version": "3.310.0", + "version": "3.568.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.489.0", + "version": "3.714.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@smithy/types": "^2.8.0", + "@aws-sdk/types": "3.714.0", + "@smithy/types": "^3.7.2", "bowser": "^2.11.0", - "tslib": "^2.5.0" + "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.489.0", + "version": "3.716.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.489.0", - "@smithy/node-config-provider": "^2.1.9", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@aws-sdk/middleware-user-agent": "3.716.0", + "@aws-sdk/types": "3.714.0", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" }, "peerDependencies": { "aws-crt": ">=1.0.0" @@ -903,183 +821,423 @@ } } }, - "node_modules/@aws-sdk/util-utf8-browser": { - "version": "3.259.0", + "node_modules/@aws-sdk/xml-builder": { + "version": "3.709.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.3.1" + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@aws-sdk/xml-builder": { - "version": "3.485.0", - "license": "Apache-2.0", + "node_modules/@azure/abort-controller": { + "version": "1.1.0", + "license": "MIT", "dependencies": { - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "tslib": "^2.2.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=12.0.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.23.5", - "dev": true, + "node_modules/@azure/core-auth": { + "version": "1.7.2", "license": "MIT", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@azure/abort-controller": "^2.0.0", + "@azure/core-util": "^1.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=18.0.0" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "dev": true, + "node_modules/@azure/core-auth/node_modules/@azure/abort-controller": { + "version": "2.1.2", "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, "engines": { - "node": ">=6.9.0" + "node": ">=18.0.0" } }, - "node_modules/@babel/highlight": { - "version": "7.23.4", - "dev": true, + "node_modules/@azure/core-client": { + "version": "1.9.2", "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "^1.9.1", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.6.1", + "@azure/logger": "^1.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=18.0.0" } }, - "node_modules/@babel/runtime": { - "version": "7.23.8", - "dev": true, + "node_modules/@azure/core-client/node_modules/@azure/abort-controller": { + "version": "2.1.2", "license": "MIT", "dependencies": { - "regenerator-runtime": "^0.14.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=18.0.0" } }, - "node_modules/@changesets/apply-release-plan": { - "version": "7.0.0", - "dev": true, + "node_modules/@azure/core-http-compat": { + "version": "2.1.2", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/config": "^3.0.0", - "@changesets/get-version-range-type": "^0.4.0", - "@changesets/git": "^3.0.0", - "@changesets/types": "^6.0.0", - "@manypkg/get-packages": "^1.1.3", - "detect-indent": "^6.0.0", - "fs-extra": "^7.0.1", - "lodash.startcase": "^4.4.0", - "outdent": "^0.5.0", - "prettier": "^2.7.1", - "resolve-from": "^5.0.0", - "semver": "^7.5.3" + "@azure/abort-controller": "^2.0.0", + "@azure/core-client": "^1.3.0", + "@azure/core-rest-pipeline": "^1.3.0" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@changesets/assemble-release-plan": { - "version": "6.0.0", - "dev": true, + "node_modules/@azure/core-http-compat/node_modules/@azure/abort-controller": { + "version": "2.1.2", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/errors": "^0.2.0", - "@changesets/get-dependents-graph": "^2.0.0", - "@changesets/types": "^6.0.0", - "@manypkg/get-packages": "^1.1.3", - "semver": "^7.5.3" + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@changesets/changelog-git": { - "version": "0.2.0", - "dev": true, + "node_modules/@azure/core-lro": { + "version": "2.7.2", "license": "MIT", "dependencies": { - "@changesets/types": "^6.0.0" + "@azure/abort-controller": "^2.0.0", + "@azure/core-util": "^1.2.0", + "@azure/logger": "^1.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@changesets/changelog-github": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@changesets/changelog-github/-/changelog-github-0.5.0.tgz", - "integrity": "sha512-zoeq2LJJVcPJcIotHRJEEA2qCqX0AQIeFE+L21L8sRLPVqDhSXY8ZWAt2sohtBpFZkBwu+LUwMSKRr2lMy3LJA==", - "dev": true, + "node_modules/@azure/core-lro/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "license": "MIT", "dependencies": { - "@changesets/get-github-info": "^0.6.0", - "@changesets/types": "^6.0.0", - "dotenv": "^8.1.0" + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@changesets/changelog-github/node_modules/dotenv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", - "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", - "dev": true, - "engines": { + "node_modules/@azure/core-paging": { + "version": "1.6.2", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline": { + "version": "1.16.3", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-tracing": "^1.0.1", + "@azure/core-util": "^1.9.0", + "@azure/logger": "^1.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/http-proxy-agent": { + "version": "7.0.2", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@azure/core-tracing": { + "version": "1.1.2", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-util": { + "version": "1.9.2", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-util/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-xml": { + "version": "1.4.3", + "license": "MIT", + "dependencies": { + "fast-xml-parser": "^4.3.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-xml/node_modules/fast-xml-parser": { + "version": "4.5.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/@azure/logger": { + "version": "1.1.4", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/storage-blob": { + "version": "12.24.0", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.4.0", + "@azure/core-client": "^1.6.2", + "@azure/core-http-compat": "^2.0.0", + "@azure/core-lro": "^2.2.0", + "@azure/core-paging": "^1.1.1", + "@azure/core-rest-pipeline": "^1.10.1", + "@azure/core-tracing": "^1.1.2", + "@azure/core-util": "^1.6.1", + "@azure/core-xml": "^1.3.2", + "@azure/logger": "^1.0.0", + "events": "^3.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@biomejs/biome": { + "version": "1.9.4", + "dev": true, + "hasInstallScript": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "1.9.4", + "@biomejs/cli-darwin-x64": "1.9.4", + "@biomejs/cli-linux-arm64": "1.9.4", + "@biomejs/cli-linux-arm64-musl": "1.9.4", + "@biomejs/cli-linux-x64": "1.9.4", + "@biomejs/cli-linux-x64-musl": "1.9.4", + "@biomejs/cli-win32-arm64": "1.9.4", + "@biomejs/cli-win32-x64": "1.9.4" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "1.9.4", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@changesets/apply-release-plan": { + "version": "7.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/config": "^3.0.4", + "@changesets/get-version-range-type": "^0.4.0", + "@changesets/git": "^3.0.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "detect-indent": "^6.0.0", + "fs-extra": "^7.0.1", + "lodash.startcase": "^4.4.0", + "outdent": "^0.5.0", + "prettier": "^2.7.1", + "resolve-from": "^5.0.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/assemble-release-plan": { + "version": "6.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/changelog-git": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0" + } + }, + "node_modules/@changesets/changelog-github": { + "version": "0.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/get-github-info": "^0.6.0", + "@changesets/types": "^6.0.0", + "dotenv": "^8.1.0" + } + }, + "node_modules/@changesets/changelog-github/node_modules/dotenv": { + "version": "8.6.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { "node": ">=10" } }, "node_modules/@changesets/cli": { - "version": "2.27.1", + "version": "2.27.10", "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/apply-release-plan": "^7.0.0", - "@changesets/assemble-release-plan": "^6.0.0", + "@changesets/apply-release-plan": "^7.0.6", + "@changesets/assemble-release-plan": "^6.0.5", "@changesets/changelog-git": "^0.2.0", - "@changesets/config": "^3.0.0", + "@changesets/config": "^3.0.4", "@changesets/errors": "^0.2.0", - "@changesets/get-dependents-graph": "^2.0.0", - "@changesets/get-release-plan": "^4.0.0", - "@changesets/git": "^3.0.0", - "@changesets/logger": "^0.1.0", - "@changesets/pre": "^2.0.0", - "@changesets/read": "^0.6.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/get-release-plan": "^4.0.5", + "@changesets/git": "^3.0.2", + "@changesets/logger": "^0.1.1", + "@changesets/pre": "^2.0.1", + "@changesets/read": "^0.6.2", + "@changesets/should-skip-package": "^0.1.1", "@changesets/types": "^6.0.0", - "@changesets/write": "^0.3.0", + "@changesets/write": "^0.3.2", "@manypkg/get-packages": "^1.1.3", - "@types/semver": "^7.5.0", "ansi-colors": "^4.1.3", - "chalk": "^2.1.0", "ci-info": "^3.7.0", "enquirer": "^2.3.0", "external-editor": "^3.1.0", "fs-extra": "^7.0.1", - "human-id": "^1.0.2", - "meow": "^6.0.0", - "outdent": "^0.5.0", + "mri": "^1.2.0", "p-limit": "^2.2.0", - "preferred-pm": "^3.0.0", + "package-manager-detector": "^0.2.0", + "picocolors": "^1.1.0", "resolve-from": "^5.0.0", "semver": "^7.5.3", - "spawndamnit": "^2.0.0", - "term-size": "^2.1.0", - "tty-table": "^4.1.5" + "spawndamnit": "^3.0.1", + "term-size": "^2.1.0" }, "bin": { "changeset": "bin.js" } }, "node_modules/@changesets/config": { - "version": "3.0.0", + "version": "3.0.4", "dev": true, "license": "MIT", "dependencies": { "@changesets/errors": "^0.2.0", - "@changesets/get-dependents-graph": "^2.0.0", - "@changesets/logger": "^0.1.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/logger": "^0.1.1", "@changesets/types": "^6.0.0", "@manypkg/get-packages": "^1.1.3", "fs-extra": "^7.0.1", - "micromatch": "^4.0.2" + "micromatch": "^4.0.8" } }, "node_modules/@changesets/errors": { @@ -1091,37 +1249,34 @@ } }, "node_modules/@changesets/get-dependents-graph": { - "version": "2.0.0", + "version": "2.1.2", "dev": true, "license": "MIT", "dependencies": { "@changesets/types": "^6.0.0", "@manypkg/get-packages": "^1.1.3", - "chalk": "^2.1.0", - "fs-extra": "^7.0.1", + "picocolors": "^1.1.0", "semver": "^7.5.3" } }, "node_modules/@changesets/get-github-info": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-0.6.0.tgz", - "integrity": "sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==", "dev": true, + "license": "MIT", "dependencies": { "dataloader": "^1.4.0", "node-fetch": "^2.5.0" } }, "node_modules/@changesets/get-release-plan": { - "version": "4.0.0", + "version": "4.0.5", "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/assemble-release-plan": "^6.0.0", - "@changesets/config": "^3.0.0", - "@changesets/pre": "^2.0.0", - "@changesets/read": "^0.6.0", + "@changesets/assemble-release-plan": "^6.0.5", + "@changesets/config": "^3.0.4", + "@changesets/pre": "^2.0.1", + "@changesets/read": "^0.6.2", "@changesets/types": "^6.0.0", "@manypkg/get-packages": "^1.1.3" } @@ -1132,25 +1287,23 @@ "license": "MIT" }, "node_modules/@changesets/git": { - "version": "3.0.0", + "version": "3.0.2", "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.1", "@changesets/errors": "^0.2.0", - "@changesets/types": "^6.0.0", "@manypkg/get-packages": "^1.1.3", "is-subdir": "^1.1.1", - "micromatch": "^4.0.2", - "spawndamnit": "^2.0.0" + "micromatch": "^4.0.8", + "spawndamnit": "^3.0.1" } }, "node_modules/@changesets/logger": { - "version": "0.1.0", + "version": "0.1.1", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^2.1.0" + "picocolors": "^1.1.0" } }, "node_modules/@changesets/parse": { @@ -1163,11 +1316,10 @@ } }, "node_modules/@changesets/pre": { - "version": "2.0.0", + "version": "2.0.1", "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.1", "@changesets/errors": "^0.2.0", "@changesets/types": "^6.0.0", "@manypkg/get-packages": "^1.1.3", @@ -1175,18 +1327,26 @@ } }, "node_modules/@changesets/read": { - "version": "0.6.0", + "version": "0.6.2", "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.1", - "@changesets/git": "^3.0.0", - "@changesets/logger": "^0.1.0", + "@changesets/git": "^3.0.2", + "@changesets/logger": "^0.1.1", "@changesets/parse": "^0.4.0", "@changesets/types": "^6.0.0", - "chalk": "^2.1.0", "fs-extra": "^7.0.1", - "p-filter": "^2.1.0" + "p-filter": "^2.1.0", + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/should-skip-package": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.0.0", + "@manypkg/get-packages": "^1.1.3" } }, "node_modules/@changesets/types": { @@ -1195,11 +1355,10 @@ "license": "MIT" }, "node_modules/@changesets/write": { - "version": "0.3.0", + "version": "0.3.2", "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.1", "@changesets/types": "^6.0.0", "fs-extra": "^7.0.1", "human-id": "^1.0.2", @@ -1217,69 +1376,6 @@ "node": ">=12" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.8.0", - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "license": "Python-2.0" - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, "node_modules/@google-cloud/paginator": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", @@ -1312,9 +1408,9 @@ } }, "node_modules/@google-cloud/storage": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.12.0.tgz", - "integrity": "sha512-122Ui67bhnf8MkRnxQAC5lf7wPGkPP5hL3+J5s9HHDw2J9RpaMmnV8iahn+RUn9BH70W6uRe6nMZLXiRaJM/3g==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.15.0.tgz", + "integrity": "sha512-/j/+8DFuEOo33fbdX0V5wjooOoFahEaMEdImHBmM2tH9MPHJYNtmXOf2sGUmZmiufSukmBEvdlzYgDkkgeBiVQ==", "license": "Apache-2.0", "dependencies": { "@google-cloud/paginator": "^5.0.0", @@ -1323,7 +1419,7 @@ "abort-controller": "^3.0.0", "async-retry": "^1.3.3", "duplexify": "^4.1.3", - "fast-xml-parser": "^4.3.0", + "fast-xml-parser": "^4.4.1", "gaxios": "^6.0.2", "google-auth-library": "^9.6.3", "html-entities": "^2.5.2", @@ -1337,32 +1433,8 @@ "node": ">=14" } }, - "node_modules/@google-cloud/storage/node_modules/fast-xml-parser": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", - "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - }, - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - } - ], - "license": "MIT", - "dependencies": { - "strnum": "^1.0.5" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, "node_modules/@google-cloud/storage/node_modules/mime": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", "license": "MIT", "bin": { "mime": "cli.js" @@ -1373,8 +1445,6 @@ }, "node_modules/@google-cloud/storage/node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" @@ -1386,32 +1456,99 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "devOptional": true, + "license": "MIT" }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "license": "Apache-2.0", + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "dev": true, + "license": "MIT", "engines": { - "node": ">=12.22" + "node": ">=12" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "license": "BSD-3-Clause" + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.1", @@ -1497,6 +1634,7 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", + "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -1508,6 +1646,7 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", + "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -1515,6 +1654,7 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", + "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -1524,8 +1664,17 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@redis/client": { - "version": "1.5.13", + "version": "1.6.0", "license": "MIT", "optional": true, "dependencies": { @@ -1539,28 +1688,25 @@ }, "node_modules/@shopify/semaphore": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@shopify/semaphore/-/semaphore-3.1.0.tgz", - "integrity": "sha512-LxonkiWEu12FbZhuOMhsdocpxCqm7By8C/2U9QgNuEoXUx2iMrlXjJv3p93RwfNC6TrdlNRo17gRer1z1309VQ==", + "license": "MIT", "engines": { "node": ">=18.12.0" } }, "node_modules/@sinonjs/commons": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "version": "11.3.1", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0" + "@sinonjs/commons": "^3.0.1" } }, "node_modules/@sinonjs/samsam": { @@ -1582,764 +1728,616 @@ } }, "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true + "version": "0.7.3", + "dev": true, + "license": "(Unlicense OR Apache-2.0)" }, "node_modules/@smithy/abort-controller": { - "version": "2.0.16", + "version": "3.1.9", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/chunked-blob-reader": { - "version": "2.0.0", + "version": "4.0.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" } }, "node_modules/@smithy/chunked-blob-reader-native": { - "version": "2.0.1", + "version": "3.0.1", "license": "Apache-2.0", "dependencies": { - "@smithy/util-base64": "^2.0.1", - "tslib": "^2.5.0" + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/config-resolver": { - "version": "2.0.23", + "version": "3.0.13", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^2.1.9", - "@smithy/types": "^2.8.0", - "@smithy/util-config-provider": "^2.1.0", - "@smithy/util-middleware": "^2.0.9", - "tslib": "^2.5.0" + "@smithy/node-config-provider": "^3.1.12", + "@smithy/types": "^3.7.2", + "@smithy/util-config-provider": "^3.0.0", + "@smithy/util-middleware": "^3.0.11", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/core": { - "version": "1.2.2", + "version": "2.5.6", "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-endpoint": "^2.3.0", - "@smithy/middleware-retry": "^2.0.26", - "@smithy/middleware-serde": "^2.0.16", - "@smithy/protocol-http": "^3.0.12", - "@smithy/smithy-client": "^2.2.1", - "@smithy/types": "^2.8.0", - "@smithy/util-middleware": "^2.0.9", - "tslib": "^2.5.0" + "@smithy/middleware-serde": "^3.0.11", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "@smithy/util-body-length-browser": "^3.0.0", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-stream": "^3.3.3", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/credential-provider-imds": { - "version": "2.0.5", - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^2.0.5", - "@smithy/property-provider": "^2.0.5", - "@smithy/types": "^2.2.2", - "@smithy/url-parser": "^2.0.5", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds/node_modules/@smithy/node-config-provider": { - "version": "2.0.5", - "license": "Apache-2.0", - "dependencies": { - "@smithy/property-provider": "^2.0.5", - "@smithy/shared-ini-file-loader": "^2.0.5", - "@smithy/types": "^2.2.2", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds/node_modules/@smithy/querystring-parser": { - "version": "2.0.5", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^2.2.2", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds/node_modules/@smithy/shared-ini-file-loader": { - "version": "2.0.5", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^2.2.2", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds/node_modules/@smithy/types": { - "version": "2.2.2", + "version": "3.2.8", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "@smithy/node-config-provider": "^3.1.12", + "@smithy/property-provider": "^3.1.11", + "@smithy/types": "^3.7.2", + "@smithy/url-parser": "^3.0.11", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds/node_modules/@smithy/url-parser": { - "version": "2.0.5", - "license": "Apache-2.0", - "dependencies": { - "@smithy/querystring-parser": "^2.0.5", - "@smithy/types": "^2.2.2", - "tslib": "^2.5.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/eventstream-codec": { - "version": "2.0.5", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/crc32": "3.0.0", - "@smithy/types": "^2.2.2", - "@smithy/util-hex-encoding": "^2.0.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@smithy/eventstream-codec/node_modules/@smithy/types": { - "version": "2.2.2", + "version": "3.1.10", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^3.7.2", + "@smithy/util-hex-encoding": "^3.0.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/eventstream-serde-browser": { - "version": "2.0.16", + "version": "3.0.14", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^2.0.16", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/eventstream-serde-universal": "^3.0.13", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "2.0.16", + "version": "3.0.11", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/eventstream-serde-node": { - "version": "2.0.16", + "version": "3.0.13", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^2.0.16", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/eventstream-serde-universal": "^3.0.13", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/eventstream-serde-universal": { - "version": "2.0.16", + "version": "3.0.13", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-codec": "^2.0.16", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/eventstream-codec": "^3.1.10", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-universal/node_modules/@smithy/eventstream-codec": { - "version": "2.0.16", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/crc32": "3.0.0", - "@smithy/types": "^2.8.0", - "@smithy/util-hex-encoding": "^2.0.0", - "tslib": "^2.5.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/fetch-http-handler": { - "version": "2.3.2", + "version": "4.1.2", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^3.0.12", - "@smithy/querystring-builder": "^2.0.16", - "@smithy/types": "^2.8.0", - "@smithy/util-base64": "^2.0.1", - "tslib": "^2.5.0" + "@smithy/protocol-http": "^4.1.8", + "@smithy/querystring-builder": "^3.0.11", + "@smithy/types": "^3.7.2", + "@smithy/util-base64": "^3.0.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/hash-blob-browser": { - "version": "2.0.17", + "version": "3.1.10", "license": "Apache-2.0", "dependencies": { - "@smithy/chunked-blob-reader": "^2.0.0", - "@smithy/chunked-blob-reader-native": "^2.0.1", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/chunked-blob-reader": "^4.0.0", + "@smithy/chunked-blob-reader-native": "^3.0.1", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" } }, "node_modules/@smithy/hash-node": { - "version": "2.0.18", + "version": "3.0.11", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "@smithy/util-buffer-from": "^2.0.0", - "@smithy/util-utf8": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/hash-stream-node": { - "version": "2.0.18", + "version": "3.1.10", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "@smithy/util-utf8": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/invalid-dependency": { - "version": "2.0.16", + "version": "3.0.11", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" } }, "node_modules/@smithy/is-array-buffer": { - "version": "2.0.0", + "version": "3.0.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/md5-js": { - "version": "2.0.18", + "version": "3.0.11", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "@smithy/util-utf8": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" } }, "node_modules/@smithy/middleware-content-length": { - "version": "2.0.18", + "version": "3.0.13", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^3.0.12", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/middleware-endpoint": { - "version": "2.3.0", + "version": "3.2.7", "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^2.0.16", - "@smithy/node-config-provider": "^2.1.9", - "@smithy/shared-ini-file-loader": "^2.2.8", - "@smithy/types": "^2.8.0", - "@smithy/url-parser": "^2.0.16", - "@smithy/util-middleware": "^2.0.9", - "tslib": "^2.5.0" + "@smithy/core": "^2.5.6", + "@smithy/middleware-serde": "^3.0.11", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/shared-ini-file-loader": "^3.1.12", + "@smithy/types": "^3.7.2", + "@smithy/url-parser": "^3.0.11", + "@smithy/util-middleware": "^3.0.11", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/middleware-retry": { - "version": "2.0.26", + "version": "3.0.32", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^2.1.9", - "@smithy/protocol-http": "^3.0.12", - "@smithy/service-error-classification": "^2.0.9", - "@smithy/smithy-client": "^2.2.1", - "@smithy/types": "^2.8.0", - "@smithy/util-middleware": "^2.0.9", - "@smithy/util-retry": "^2.0.9", - "tslib": "^2.5.0", - "uuid": "^8.3.2" + "@smithy/node-config-provider": "^3.1.12", + "@smithy/protocol-http": "^4.1.8", + "@smithy/service-error-classification": "^3.0.11", + "@smithy/smithy-client": "^3.5.2", + "@smithy/types": "^3.7.2", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-retry": "^3.0.11", + "tslib": "^2.6.2", + "uuid": "^9.0.1" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/middleware-retry/node_modules/uuid": { + "version": "9.0.1", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" } }, "node_modules/@smithy/middleware-serde": { - "version": "2.0.16", + "version": "3.0.11", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/middleware-stack": { - "version": "2.0.10", + "version": "3.0.11", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/node-config-provider": { - "version": "2.1.9", - "license": "Apache-2.0", - "dependencies": { - "@smithy/property-provider": "^2.0.17", - "@smithy/shared-ini-file-loader": "^2.2.8", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/node-config-provider/node_modules/@smithy/property-provider": { - "version": "2.0.17", + "version": "3.1.12", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/property-provider": "^3.1.11", + "@smithy/shared-ini-file-loader": "^3.1.12", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/node-http-handler": { - "version": "2.2.2", + "version": "3.3.3", "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^2.0.16", - "@smithy/protocol-http": "^3.0.12", - "@smithy/querystring-builder": "^2.0.16", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/abort-controller": "^3.1.9", + "@smithy/protocol-http": "^4.1.8", + "@smithy/querystring-builder": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/property-provider": { - "version": "2.0.5", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^2.2.2", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/property-provider/node_modules/@smithy/types": { - "version": "2.2.2", + "version": "3.1.11", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/protocol-http": { - "version": "3.0.12", + "version": "4.1.8", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/querystring-builder": { - "version": "2.0.16", + "version": "3.0.11", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "@smithy/util-uri-escape": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "@smithy/util-uri-escape": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/querystring-parser": { - "version": "2.0.16", + "version": "3.0.11", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/service-error-classification": { - "version": "2.0.9", + "version": "3.0.11", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0" + "@smithy/types": "^3.7.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "2.2.8", + "version": "3.1.12", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/signature-v4": { - "version": "2.0.5", - "license": "Apache-2.0", - "dependencies": { - "@smithy/eventstream-codec": "^2.0.5", - "@smithy/is-array-buffer": "^2.0.0", - "@smithy/types": "^2.2.2", - "@smithy/util-hex-encoding": "^2.0.0", - "@smithy/util-middleware": "^2.0.0", - "@smithy/util-uri-escape": "^2.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/signature-v4/node_modules/@smithy/types": { - "version": "2.2.2", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/signature-v4/node_modules/@smithy/util-middleware": { - "version": "2.0.0", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/signature-v4/node_modules/@smithy/util-utf8": { - "version": "2.0.0", + "version": "4.2.4", "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-uri-escape": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/smithy-client": { - "version": "2.2.1", + "version": "3.5.2", "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-endpoint": "^2.3.0", - "@smithy/middleware-stack": "^2.0.10", - "@smithy/protocol-http": "^3.0.12", - "@smithy/types": "^2.8.0", - "@smithy/util-stream": "^2.0.24", - "tslib": "^2.5.0" + "@smithy/core": "^2.5.6", + "@smithy/middleware-endpoint": "^3.2.7", + "@smithy/middleware-stack": "^3.0.11", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "@smithy/util-stream": "^3.3.3", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/types": { - "version": "2.8.0", + "version": "3.7.2", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/url-parser": { - "version": "2.0.16", + "version": "3.0.11", "license": "Apache-2.0", "dependencies": { - "@smithy/querystring-parser": "^2.0.16", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/querystring-parser": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" } }, "node_modules/@smithy/util-base64": { - "version": "2.0.1", + "version": "3.0.0", "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-body-length-browser": { - "version": "2.0.1", + "version": "3.0.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" } }, "node_modules/@smithy/util-body-length-node": { - "version": "2.1.0", + "version": "3.0.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-buffer-from": { - "version": "2.0.0", + "version": "3.0.0", "license": "Apache-2.0", "dependencies": { - "@smithy/is-array-buffer": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/is-array-buffer": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-config-provider": { - "version": "2.1.0", + "version": "3.0.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "2.0.24", + "version": "3.0.32", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^2.0.17", - "@smithy/smithy-client": "^2.2.1", - "@smithy/types": "^2.8.0", + "@smithy/property-provider": "^3.1.11", + "@smithy/smithy-client": "^3.5.2", + "@smithy/types": "^3.7.2", "bowser": "^2.11.0", - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { "node": ">= 10.0.0" } }, - "node_modules/@smithy/util-defaults-mode-browser/node_modules/@smithy/property-provider": { - "version": "2.0.17", + "node_modules/@smithy/util-defaults-mode-node": { + "version": "3.0.32", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/config-resolver": "^3.0.13", + "@smithy/credential-provider-imds": "^3.2.8", + "@smithy/node-config-provider": "^3.1.12", + "@smithy/property-provider": "^3.1.11", + "@smithy/smithy-client": "^3.5.2", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">= 10.0.0" } }, - "node_modules/@smithy/util-defaults-mode-node": { - "version": "2.0.32", + "node_modules/@smithy/util-endpoints": { + "version": "2.1.7", "license": "Apache-2.0", "dependencies": { - "@smithy/config-resolver": "^2.0.23", - "@smithy/credential-provider-imds": "^2.1.5", - "@smithy/node-config-provider": "^2.1.9", - "@smithy/property-provider": "^2.0.17", - "@smithy/smithy-client": "^2.2.1", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/node-config-provider": "^3.1.12", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">= 10.0.0" + "node": ">=16.0.0" } }, - "node_modules/@smithy/util-defaults-mode-node/node_modules/@smithy/credential-provider-imds": { - "version": "2.1.5", + "node_modules/@smithy/util-hex-encoding": { + "version": "3.0.0", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^2.1.9", - "@smithy/property-provider": "^2.0.17", - "@smithy/types": "^2.8.0", - "@smithy/url-parser": "^2.0.16", - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, - "node_modules/@smithy/util-defaults-mode-node/node_modules/@smithy/property-provider": { - "version": "2.0.17", + "node_modules/@smithy/util-middleware": { + "version": "3.0.11", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/util-endpoints": { - "version": "1.0.8", - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^2.1.9", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@smithy/util-hex-encoding": { - "version": "2.0.0", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/util-middleware": { - "version": "2.0.9", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-retry": { - "version": "2.0.9", + "version": "3.0.11", "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^2.0.9", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/service-error-classification": "^3.0.11", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">= 14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-stream": { - "version": "2.0.24", + "version": "3.3.3", "license": "Apache-2.0", "dependencies": { - "@smithy/fetch-http-handler": "^2.3.2", - "@smithy/node-http-handler": "^2.2.2", - "@smithy/types": "^2.8.0", - "@smithy/util-base64": "^2.0.1", - "@smithy/util-buffer-from": "^2.0.0", - "@smithy/util-hex-encoding": "^2.0.0", - "@smithy/util-utf8": "^2.0.2", - "tslib": "^2.5.0" + "@smithy/fetch-http-handler": "^4.1.2", + "@smithy/node-http-handler": "^3.3.3", + "@smithy/types": "^3.7.2", + "@smithy/util-base64": "^3.0.0", + "@smithy/util-buffer-from": "^3.0.0", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-uri-escape": { - "version": "2.0.0", + "version": "3.0.0", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-utf8": { - "version": "2.0.2", + "version": "3.0.0", "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^2.0.0", - "tslib": "^2.5.0" + "@smithy/util-buffer-from": "^3.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@smithy/util-waiter": { - "version": "2.0.16", + "version": "3.2.0", "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^2.0.16", - "@smithy/types": "^2.8.0", - "tslib": "^2.5.0" + "@smithy/abort-controller": "^3.1.9", + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "license": "MIT", "engines": { "node": ">= 10" } @@ -2364,6 +2362,10 @@ "dev": true, "license": "MIT" }, + "node_modules/@tus/azure-store": { + "resolved": "packages/azure-store", + "link": true + }, "node_modules/@tus/file-store": { "resolved": "packages/file-store", "link": true @@ -2388,16 +2390,13 @@ "version": "1.19.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/connect": "*", "@types/node": "*" } }, - "node_modules/@types/body-parser/node_modules/@types/node": { - "version": "20.4.2", - "dev": true, - "license": "MIT" - }, "node_modules/@types/caseless": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", @@ -2408,15 +2407,12 @@ "version": "3.4.38", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "*" } }, - "node_modules/@types/connect/node_modules/@types/node": { - "version": "20.4.2", - "dev": true, - "license": "MIT" - }, "node_modules/@types/cookiejar": { "version": "2.1.2", "dev": true, @@ -2430,25 +2426,12 @@ "@types/ms": "*" } }, - "node_modules/@types/eslint": { - "version": "8.56.5", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.5.tgz", - "integrity": "sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, "node_modules/@types/express": { "version": "4.17.21", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -2460,6 +2443,8 @@ "version": "4.17.41", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -2467,11 +2452,6 @@ "@types/send": "*" } }, - "node_modules/@types/express-serve-static-core/node_modules/@types/node": { - "version": "20.4.2", - "dev": true, - "license": "MIT" - }, "node_modules/@types/glob": { "version": "8.1.0", "dev": true, @@ -2481,31 +2461,22 @@ "@types/node": "*" } }, - "node_modules/@types/glob/node_modules/@types/node": { - "version": "20.4.2", - "dev": true, - "license": "MIT" - }, "node_modules/@types/http-errors": { "version": "2.0.4", "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.12", - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/@types/lodash": { "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", - "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/lodash.throttle": { "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/lodash.throttle/-/lodash.throttle-4.1.9.tgz", - "integrity": "sha512-PCPVfpfueguWZQB7pJQK890F2scYKoDUL3iM522AptHWn7d5NQmeS/LTEHIcLr5PaTzl3dK2Z0xSUHHTHwaL5g==", "dev": true, + "license": "MIT", "dependencies": { "@types/lodash": "*" } @@ -2513,18 +2484,15 @@ "node_modules/@types/mime": { "version": "1.3.5", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/@types/minimatch": { "version": "5.1.2", "dev": true, "license": "MIT" }, - "node_modules/@types/minimist": { - "version": "1.2.5", - "dev": true, - "license": "MIT" - }, "node_modules/@types/mocha": { "version": "10.0.6", "dev": true, @@ -2543,37 +2511,26 @@ "@types/node": "*" } }, - "node_modules/@types/multistream/node_modules/@types/node": { - "version": "20.4.2", - "dev": true, - "license": "MIT" - }, "node_modules/@types/node": { - "version": "20.11.5", + "version": "22.10.1", "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.20.0" } }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/prettier": { - "version": "2.7.3", - "dev": true, - "license": "MIT" - }, "node_modules/@types/qs": { "version": "6.9.11", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/@types/range-parser": { "version": "1.2.7", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/@types/request": { "version": "2.48.12", @@ -2588,14 +2545,15 @@ } }, "node_modules/@types/request/node_modules/form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.2.tgz", + "integrity": "sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "mime-types": "^2.1.12", + "safe-buffer": "^5.2.1" }, "engines": { "node": ">= 0.12" @@ -2610,34 +2568,23 @@ "@types/node": "*" } }, - "node_modules/@types/rimraf/node_modules/@types/node": { - "version": "20.4.2", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/semver": { - "version": "7.5.6", - "dev": true, - "license": "MIT" - }, "node_modules/@types/send": { "version": "0.17.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, - "node_modules/@types/send/node_modules/@types/node": { - "version": "20.4.2", - "dev": true, - "license": "MIT" - }, "node_modules/@types/serve-static": { "version": "1.15.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/http-errors": "*", "@types/mime": "*", @@ -2647,18 +2594,14 @@ "node_modules/@types/serve-static/node_modules/@types/mime": { "version": "3.0.4", "dev": true, - "license": "MIT" - }, - "node_modules/@types/serve-static/node_modules/@types/node": { - "version": "20.4.2", - "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/@types/sinon": { "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", - "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", "dev": true, + "license": "MIT", "dependencies": { "@types/sinonjs__fake-timers": "*" } @@ -2677,11 +2620,6 @@ "@types/node": "*" } }, - "node_modules/@types/superagent/node_modules/@types/node": { - "version": "20.4.2", - "dev": true, - "license": "MIT" - }, "node_modules/@types/supertest": { "version": "2.0.16", "dev": true, @@ -2698,451 +2636,115 @@ "@types/node": "*" } }, - "node_modules/@types/throttle/node_modules/@types/node": { - "version": "20.4.2", - "dev": true, - "license": "MIT" - }, "node_modules/@types/tough-cookie": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", "license": "MIT" }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", + "node_modules/abort-controller": { + "version": "3.0.0", "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "event-target-shim": "^5.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=6.5" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@eslint-community/regexpp": { - "version": "4.5.1", + "node_modules/accepts": { + "version": "1.3.8", + "dev": true, "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.19.0", - "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "6.19.0", - "@typescript-eslint/types": "6.19.0", - "@typescript-eslint/typescript-estree": "6.19.0", - "@typescript-eslint/visitor-keys": "6.19.0", - "debug": "^4.3.4" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">= 0.6" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "6.19.0", + "node_modules/acorn": { + "version": "8.10.0", + "dev": true, "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "6.19.0", - "@typescript-eslint/visitor-keys": "6.19.0" + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=0.4.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "6.19.0", + "node_modules/acorn-walk": { + "version": "8.2.0", + "dev": true, "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=0.4.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.19.0", - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "6.19.0", - "@typescript-eslint/visitor-keys": "6.19.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">= 14" } }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.3", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "dev": true, + "license": "MIT", "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=6" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=8" } }, - "node_modules/@typescript-eslint/scope-manager/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=8" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", + "node_modules/ansi-styles/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" + "color-name": "~1.1.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=7.0.0" } }, - "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } + "node_modules/ansi-styles/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "license": "BSD-2-Clause", + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@types/semver": { - "version": "7.5.0", - "license": "MIT" - }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { - "version": "5.1.1", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/estraverse": { - "version": "4.3.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.19.0", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "6.19.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/@typescript-eslint/types": { - "version": "6.19.0", - "license": "MIT", - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "license": "ISC" - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.10.0", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ansi-styles/node_modules/color-convert": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ansi-styles/node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, "engines": { "node": ">= 8" @@ -3161,66 +2763,19 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/array-union": { "version": "2.1.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", "dev": true, "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, "node_modules/arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "license": "MIT", "engines": { "node": ">=8" } @@ -3248,19 +2803,9 @@ "version": "0.4.0", "license": "MIT" }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/balanced-match": { "version": "1.0.2", + "dev": true, "license": "MIT" }, "node_modules/base64-js": { @@ -3296,6 +2841,7 @@ "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "license": "MIT", "engines": { "node": "*" } @@ -3314,29 +2860,23 @@ }, "node_modules/brace-expansion": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/braces": { - "version": "3.0.2", + "version": "3.0.3", + "dev": true, "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, - "node_modules/breakword": { - "version": "1.0.6", - "dev": true, - "license": "MIT", - "dependencies": { - "wcwidth": "^1.0.1" - } - }, "node_modules/browser-stdout": { "version": "1.3.1", "dev": true, @@ -3368,111 +2908,31 @@ "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "license": "MIT" + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" }, "node_modules/call-bind": { - "version": "1.0.5", + "version": "1.0.7", "dev": true, "license": "MIT", "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/callsites": { - "version": "3.1.0", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", + "node_modules/chardet": { + "version": "0.7.0", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk/node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk/node_modules/escape-string-regexp": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/chalk/node_modules/has-flag": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "dev": true, - "license": "MIT" + "license": "MIT" }, "node_modules/chokidar": { "version": "3.5.3", @@ -3514,65 +2974,14 @@ "node": ">=8" } }, - "node_modules/cliui": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "6.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, "node_modules/cluster-key-slot": { "version": "1.1.2", + "devOptional": true, "license": "Apache-2.0", - "optional": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/combine-errors": { - "version": "3.0.3", - "dependencies": { - "custom-error-instance": "2.1.1", - "lodash.uniqby": "4.5.0" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "license": "MIT", @@ -3590,6 +2999,7 @@ }, "node_modules/concat-map": { "version": "0.0.1", + "dev": true, "license": "MIT" }, "node_modules/content-disposition": { @@ -3613,25 +3023,9 @@ "dev": true, "license": "MIT" }, - "node_modules/cross-env": { - "version": "7.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, "node_modules/cross-spawn": { - "version": "7.0.3", + "version": "7.0.6", + "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -3644,6 +3038,7 @@ }, "node_modules/cross-spawn/node_modules/shebang-command": { "version": "2.0.0", + "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -3654,55 +3049,22 @@ }, "node_modules/cross-spawn/node_modules/shebang-regex": { "version": "3.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/csv": { - "version": "5.5.3", "dev": true, "license": "MIT", - "dependencies": { - "csv-generate": "^3.4.3", - "csv-parse": "^4.16.3", - "csv-stringify": "^5.6.5", - "stream-transform": "^2.1.3" - }, "engines": { - "node": ">= 0.1.90" + "node": ">=8" } }, - "node_modules/csv-generate": { - "version": "3.4.3", - "dev": true, - "license": "MIT" - }, - "node_modules/csv-parse": { - "version": "4.16.3", - "dev": true, - "license": "MIT" - }, - "node_modules/csv-stringify": { - "version": "5.6.5", - "dev": true, - "license": "MIT" - }, - "node_modules/custom-error-instance": { - "version": "2.1.1", - "license": "ISC" - }, "node_modules/dataloader": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", - "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/debug": { - "version": "4.3.4", + "version": "4.4.0", "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -3713,77 +3075,14 @@ } } }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "license": "MIT" - }, - "node_modules/decamelize": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "license": "MIT" - }, - "node_modules/defaults": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/define-data-property": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", + "version": "1.1.4", "dev": true, "license": "MIT", "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -3799,9 +3098,13 @@ "node": ">=0.4.0" } }, - "node_modules/demo": { - "resolved": "demo", - "link": true + "node_modules/denque": { + "version": "2.1.0", + "devOptional": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } }, "node_modules/detect-indent": { "version": "6.1.0", @@ -3821,7 +3124,7 @@ } }, "node_modules/diff": { - "version": "5.0.0", + "version": "5.2.0", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -3830,6 +3133,7 @@ }, "node_modules/dir-glob": { "version": "3.0.1", + "dev": true, "license": "MIT", "dependencies": { "path-type": "^4.0.0" @@ -3838,27 +3142,11 @@ "node": ">=8" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dotenv": { - "version": "16.0.3", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, "node_modules/duplexify": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", + "license": "MIT", "dependencies": { "end-of-stream": "^1.4.1", "inherits": "^2.0.3", @@ -3866,10 +3154,16 @@ "stream-shift": "^1.0.2" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" } @@ -3904,6 +3198,7 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "license": "MIT", "dependencies": { "once": "^1.4.0" } @@ -3920,109 +3215,23 @@ "node": ">=8.6" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.22.3", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.2", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.5", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.2", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.12", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "safe-array-concat": "^1.0.1", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-abstract/node_modules/object-inspect": { - "version": "1.13.1", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.2", + "node_modules/es-define-property": { + "version": "1.0.0", "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" } }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", + "node_modules/es-errors": { + "version": "1.3.0", "dev": true, "license": "MIT", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/escalade": { @@ -4035,6 +3244,7 @@ }, "node_modules/escape-string-regexp": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -4043,263 +3253,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-custom": { - "resolved": "packages/eslint-config-custom", - "link": true - }, - "node_modules/eslint-config-prettier": { - "version": "8.10.0", - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-config-turbo": { - "version": "1.11.3", - "license": "MPL-2.0", - "dependencies": { - "eslint-plugin-turbo": "1.11.3" - }, - "peerDependencies": { - "eslint": ">6.6.0" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-turbo": { - "version": "1.11.3", - "license": "MPL-2.0", - "dependencies": { - "dotenv": "16.0.3" - }, - "peerDependencies": { - "eslint": ">6.6.0" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "license": "Python-2.0" - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/esprima": { "version": "4.0.1", "dev": true, @@ -4312,40 +3265,6 @@ "node": ">=4" } }, - "node_modules/esquery": { - "version": "1.5.0", - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/event-target-shim": { "version": "5.0.1", "license": "MIT", @@ -4355,7 +3274,6 @@ }, "node_modules/events": { "version": "3.3.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8.x" @@ -4364,7 +3282,8 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" }, "node_modules/extendable-error": { "version": "0.1.7", @@ -4384,16 +3303,9 @@ "node": ">=4" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "license": "Apache-2.0" - }, "node_modules/fast-glob": { - "version": "3.3.0", + "version": "3.3.2", + "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -4406,29 +3318,21 @@ "node": ">=8.6.0" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "license": "MIT" - }, "node_modules/fast-safe-stringify": { "version": "2.1.1", "dev": true, "license": "MIT" }, "node_modules/fast-xml-parser": { - "version": "4.2.5", + "version": "4.4.1", "funding": [ - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - }, { "type": "github", "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" } ], "license": "MIT", @@ -4440,24 +3344,16 @@ } }, "node_modules/fastq": { - "version": "1.15.0", + "version": "1.17.1", + "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, "node_modules/fill-range": { - "version": "7.0.1", + "version": "7.1.1", + "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -4478,15 +3374,6 @@ "node": ">=8" } }, - "node_modules/find-yarn-workspace-root2": { - "version": "1.2.16", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "micromatch": "^4.0.2", - "pkg-dir": "^4.2.0" - } - }, "node_modules/flat": { "version": "5.0.2", "dev": true, @@ -4495,27 +3382,19 @@ "flat": "cli.js" } }, - "node_modules/flat-cache": { - "version": "3.0.4", - "license": "MIT", + "node_modules/foreground-child": { + "version": "3.3.0", + "dev": true, + "license": "ISC", "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "license": "ISC" - }, - "node_modules/for-each": { - "version": "0.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.3" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/form-data": { @@ -4568,6 +3447,7 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", + "dev": true, "license": "ISC" }, "node_modules/fsevents": { @@ -4590,51 +3470,26 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gaxios": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.0.tgz", - "integrity": "sha512-DSrkyMTfAnAm4ks9Go20QGOcXEyW/NmZhvTYBU2rb4afBB393WIMQPWPEDMl/k8xqiNN9HYq2zao3oWXsdl2Tg==", - "license": "Apache-2.0", + "node_modules/gaxios": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9", - "uuid": "^10.0.0" + "uuid": "^9.0.1" }, "engines": { "node": ">=14" } }, "node_modules/gaxios/node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -4674,27 +3529,16 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.2", + "version": "1.2.4", "dev": true, "license": "MIT", "dependencies": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, "engines": { "node": ">= 0.4" }, @@ -4704,6 +3548,7 @@ }, "node_modules/glob": { "version": "7.2.3", + "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -4722,6 +3567,7 @@ }, "node_modules/glob-parent": { "version": "5.1.2", + "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -4730,45 +3576,9 @@ "node": ">= 6" } }, - "node_modules/globals": { - "version": "13.20.0", - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals/node_modules/type-fest": { - "version": "0.20.2", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/globby": { "version": "11.1.0", + "dev": true, "license": "MIT", "dependencies": { "array-union": "^2.1.0", @@ -4786,9 +3596,9 @@ } }, "node_modules/google-auth-library": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.13.0.tgz", - "integrity": "sha512-p9Y03Uzp/Igcs36zAaB0XTSwZ8Y0/tpYiz5KIde5By+H9DCVUSYtDWZu6aFXsWTqENMb8BD/pDT3hR8NVrPkfA==", + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.0.tgz", + "integrity": "sha512-7ccSEJFDFO7exFbO6NRyC+xH8/mZ1GZGG2xxx9iHxZWcjUjJpjWxIMw3cofAKcueZ6DATiukmmprD7yavQHOyQ==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", @@ -4815,16 +3625,8 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "license": "ISC" - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", "dev": true, - "license": "MIT" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "license": "MIT" + "license": "ISC" }, "node_modules/gtoken": { "version": "7.1.0", @@ -4839,53 +3641,27 @@ "node": ">=14.0.0" } }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/has": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", + "version": "1.0.2", "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { - "version": "1.0.1", + "version": "1.0.3", "dev": true, "license": "MIT", "engines": { @@ -4906,27 +3682,8 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has/node_modules/function-bind": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, "node_modules/hasown": { - "version": "2.0.0", + "version": "2.0.2", "dev": true, "license": "MIT", "dependencies": { @@ -4952,11 +3709,6 @@ "node": ">=8" } }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "dev": true, - "license": "ISC" - }, "node_modules/html-entities": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", @@ -4977,6 +3729,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "license": "MIT", "dependencies": { "@tootallnate/once": "2", "agent-base": "6", @@ -4990,6 +3743,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", "dependencies": { "debug": "4" }, @@ -4998,12 +3752,12 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -5046,50 +3800,16 @@ "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.2.4", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", + "version": "5.3.2", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 4" } }, "node_modules/inflight": { "version": "1.0.6", + "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -5100,46 +3820,27 @@ "version": "2.0.4", "license": "ISC" }, - "node_modules/internal-slot": { - "version": "1.0.6", - "dev": true, + "node_modules/ioredis": { + "version": "5.4.1", + "devOptional": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.2", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" }, "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "has-bigints": "^1.0.1" + "node": ">=12.22.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/ioredis" } }, "node_modules/is-binary-path": { @@ -5153,59 +3854,9 @@ "node": ">=8" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-extglob": { "version": "2.1.1", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5221,6 +3872,7 @@ }, "node_modules/is-glob": { "version": "4.0.3", + "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -5229,144 +3881,39 @@ "node": ">=0.10.0" } }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-number": { "version": "7.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "dev": true, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", + "node_modules/is-subdir": { + "version": "1.2.0", + "dev": true, "license": "MIT", + "dependencies": { + "better-path-resolve": "1.0.0" + }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-subdir": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "better-path-resolve": "1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.12", - "dev": true, - "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.11" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", + "node_modules/is-unicode-supported": { + "version": "0.1.0", "dev": true, "license": "MIT", "engines": { @@ -5376,17 +3923,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-windows": { "version": "1.0.2", "dev": true, @@ -5395,23 +3931,24 @@ "node": ">=0.10.0" } }, - "node_modules/isarray": { - "version": "2.0.5", - "dev": true, - "license": "MIT" - }, "node_modules/isexe": { "version": "2.0.0", + "dev": true, "license": "ISC" }, - "node_modules/js-base64": { - "version": "2.6.4", - "license": "BSD-3-Clause" - }, - "node_modules/js-tokens": { - "version": "4.0.0", + "node_modules/jackspeak": { + "version": "3.4.3", "dev": true, - "license": "MIT" + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } }, "node_modules/js-yaml": { "version": "3.14.1", @@ -5429,23 +3966,11 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", "dependencies": { "bignumber.js": "^9.0.0" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "license": "MIT" - }, "node_modules/jsonfile": { "version": "4.0.0", "dev": true, @@ -5456,14 +3981,14 @@ }, "node_modules/just-extend": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", - "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jwa": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "license": "MIT", "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -5474,57 +3999,12 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "license": "MIT", "dependencies": { "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "4.1.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "dev": true, - "license": "MIT" - }, - "node_modules/load-yaml-file": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.5", - "js-yaml": "^3.13.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/locate-path": { "version": "5.0.0", "dev": true, @@ -5536,47 +4016,19 @@ "node": ">=8" } }, - "node_modules/lodash._baseiteratee": { - "version": "4.7.0", - "license": "MIT", - "dependencies": { - "lodash._stringtopath": "~4.8.0" - } - }, - "node_modules/lodash._basetostring": { - "version": "4.12.0", - "license": "MIT" - }, - "node_modules/lodash._baseuniq": { - "version": "4.6.0", - "license": "MIT", - "dependencies": { - "lodash._createset": "~4.0.0", - "lodash._root": "~3.0.0" - } - }, - "node_modules/lodash._createset": { - "version": "4.0.3", - "license": "MIT" - }, - "node_modules/lodash._root": { - "version": "3.0.1", + "node_modules/lodash.defaults": { + "version": "4.2.0", + "devOptional": true, "license": "MIT" }, - "node_modules/lodash._stringtopath": { - "version": "4.8.0", - "license": "MIT", - "dependencies": { - "lodash._basetostring": "~4.12.0" - } - }, "node_modules/lodash.get": { "version": "4.4.2", "dev": true, "license": "MIT" }, - "node_modules/lodash.merge": { - "version": "4.6.2", + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "devOptional": true, "license": "MIT" }, "node_modules/lodash.startcase": { @@ -5586,16 +4038,7 @@ }, "node_modules/lodash.throttle": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" - }, - "node_modules/lodash.uniqby": { - "version": "4.5.0", - "license": "MIT", - "dependencies": { - "lodash._baseiteratee": "~4.7.0", - "lodash._baseuniq": "~4.6.0" - } + "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", @@ -5640,6 +4083,7 @@ }, "node_modules/lru-cache": { "version": "6.0.0", + "dev": true, "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -5653,17 +4097,6 @@ "dev": true, "license": "ISC" }, - "node_modules/map-obj": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/media-typer": { "version": "0.3.0", "dev": true, @@ -5672,41 +4105,6 @@ "node": ">= 0.6" } }, - "node_modules/meow": { - "version": "6.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "^4.0.2", - "normalize-package-data": "^2.5.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.13.1", - "yargs-parser": "^18.1.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/type-fest": { - "version": "0.13.1", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/merge-descriptors": { "version": "1.0.1", "dev": true, @@ -5714,6 +4112,7 @@ }, "node_modules/merge2": { "version": "1.4.1", + "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -5728,10 +4127,11 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", + "version": "4.0.8", + "dev": true, "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -5766,16 +4166,9 @@ "node": ">= 0.6" } }, - "node_modules/min-indent": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/minimatch": { "version": "3.1.2", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -5786,82 +4179,53 @@ }, "node_modules/minimatch/node_modules/brace-expansion": { "version": "1.1.11", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "node_modules/minimist-options": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/minimist-options/node_modules/arrify": { - "version": "1.0.1", + "node_modules/minipass": { + "version": "7.1.2", "dev": true, - "license": "MIT", + "license": "ISC", "engines": { - "node": ">=0.10.0" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/mixme": { - "version": "0.5.10", + "node_modules/mocha": { + "version": "11.0.1", "dev": true, "license": "MIT", - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/mocha": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", - "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", - "dev": true, - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "8.1.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^10.4.5", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/mocha/node_modules/ansi-colors": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/mocha/node_modules/argparse": { @@ -5895,19 +4259,33 @@ } }, "node_modules/mocha/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "version": "10.4.5", "dev": true, + "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=12" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -5939,7 +4317,7 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", + "version": "5.1.6", "dev": true, "license": "ISC", "dependencies": { @@ -5994,25 +4372,16 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "20.2.4", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/yargs/node_modules/yargs-parser": { - "version": "20.2.9", + "node_modules/mri": { + "version": "1.2.0", "dev": true, - "license": "ISC", + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=4" } }, "node_modules/ms": { "version": "2.1.3", - "dev": true, "license": "MIT" }, "node_modules/multistream": { @@ -6037,14 +4406,6 @@ "readable-stream": "^3.6.0" } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "license": "MIT" - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "license": "MIT" - }, "node_modules/negotiator": { "version": "0.6.3", "dev": true, @@ -6054,10 +4415,9 @@ } }, "node_modules/nise": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", - "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", + "version": "6.0.0", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0", "@sinonjs/fake-timers": "^11.2.2", @@ -6085,12 +4445,10 @@ } }, "node_modules/node-mocks-http": { - "version": "1.14.1", + "version": "1.16.1", "dev": true, "license": "MIT", "dependencies": { - "@types/express": "^4.17.21", - "@types/node": "^20.10.6", "accepts": "^1.3.7", "content-disposition": "^0.5.3", "depd": "^1.1.0", @@ -6104,6 +4462,18 @@ }, "engines": { "node": ">=14" + }, + "peerDependencies": { + "@types/express": "^4.17.21 || ^5.0.0", + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + }, + "@types/node": { + "optional": true + } } }, "node_modules/node-mocks-http/node_modules/depd": { @@ -6114,25 +4484,6 @@ "node": ">= 0.6" } }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "dev": true, @@ -6142,31 +4493,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", + "version": "1.13.2", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, "engines": { "node": ">= 0.4" }, @@ -6181,21 +4510,6 @@ "wrappy": "1" } }, - "node_modules/optionator": { - "version": "0.9.3", - "license": "MIT", - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/os-tmpdir": { "version": "1.0.2", "dev": true, @@ -6261,32 +4575,15 @@ "node": ">=6" } }, - "node_modules/parent-module": { + "node_modules/package-json-from-dist": { "version": "1.0.1", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } + "dev": true, + "license": "BlueOak-1.0.0" }, - "node_modules/parse-json": { - "version": "5.2.0", + "node_modules/package-manager-detector": { + "version": "0.2.2", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT" }, "node_modules/parseurl": { "version": "1.3.3", @@ -6298,6 +4595,7 @@ }, "node_modules/path-exists": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6305,6 +4603,7 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -6312,138 +4611,72 @@ }, "node_modules/path-key": { "version": "3.1.1", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", "dev": true, - "license": "MIT" - }, - "node_modules/path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/picomatch": { - "version": "2.3.1", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", + "node_modules/path-scurry": { + "version": "1.11.1", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "dependencies": { - "find-up": "^4.0.0" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/preferred-pm": { - "version": "3.1.2", + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^5.0.0", - "find-yarn-workspace-root2": "1.2.16", - "path-exists": "^4.0.0", - "which-pm": "2.0.0" - }, - "engines": { - "node": ">=10" - } + "license": "ISC" }, - "node_modules/preferred-pm/node_modules/find-up": { - "version": "5.0.0", + "node_modules/path-to-regexp": { + "version": "6.2.2", "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT" }, - "node_modules/preferred-pm/node_modules/locate-path": { - "version": "6.0.0", + "node_modules/path-type": { + "version": "4.0.0", "dev": true, "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/preferred-pm/node_modules/p-limit": { - "version": "3.1.0", + "node_modules/picocolors": { + "version": "1.1.1", "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "ISC" }, - "node_modules/preferred-pm/node_modules/p-locate": { - "version": "5.0.0", + "node_modules/picomatch": { + "version": "2.3.1", "dev": true, "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, "engines": { - "node": ">=10" + "node": ">=8.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", + "node_modules/pify": { + "version": "4.0.1", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.8.0" + "node": ">=6" } }, "node_modules/prettier": { "version": "2.8.8", + "dev": true, "license": "MIT", "bin": { "prettier": "bin-prettier.js" @@ -6455,16 +4688,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/process": { "version": "0.11.10", "dev": true, @@ -6473,36 +4696,6 @@ "node": ">= 0.6.0" } }, - "node_modules/proper-lockfile": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "retry": "^0.10.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/proper-lockfile/node_modules/retry": { - "version": "0.10.1", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "dev": true, - "license": "ISC" - }, - "node_modules/punycode": { - "version": "2.3.0", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/qs": { "version": "6.11.2", "dev": true, @@ -6517,12 +4710,9 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/querystringify": { - "version": "2.2.0", - "license": "MIT" - }, "node_modules/queue-microtask": { "version": "1.2.3", + "dev": true, "funding": [ { "type": "github", @@ -6539,14 +4729,6 @@ ], "license": "MIT" }, - "node_modules/quick-lru": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/randombytes": { "version": "2.1.0", "dev": true, @@ -6563,46 +4745,8 @@ "node": ">= 0.6" } }, - "node_modules/read-pkg": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/read-yaml-file": { - "version": "1.1.0", + "node_modules/read-yaml-file": { + "version": "1.1.0", "dev": true, "license": "MIT", "dependencies": { @@ -6638,16 +4782,23 @@ "node": ">=8.10.0" } }, - "node_modules/redent": { + "node_modules/redis-errors": { + "version": "1.2.0", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { "version": "3.0.0", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" + "redis-errors": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/regenerator-runtime": { @@ -6655,22 +4806,6 @@ "dev": true, "license": "MIT" }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.1", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "set-function-name": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/require-directory": { "version": "2.1.1", "dev": true, @@ -6679,31 +4814,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/requires-port": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/resolve": { - "version": "1.22.8", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/resolve-from": { "version": "5.0.0", "dev": true, @@ -6728,6 +4838,7 @@ }, "node_modules/reusify": { "version": "1.0.4", + "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -6736,6 +4847,7 @@ }, "node_modules/rimraf": { "version": "3.0.2", + "dev": true, "license": "ISC", "dependencies": { "glob": "^7.1.3" @@ -6749,6 +4861,7 @@ }, "node_modules/run-parallel": { "version": "1.2.0", + "dev": true, "funding": [ { "type": "github", @@ -6768,23 +4881,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/safe-array-concat": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "get-intrinsic": "^1.2.2", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "funding": [ @@ -6803,22 +4899,6 @@ ], "license": "MIT" }, - "node_modules/safe-regex-test": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "get-intrinsic": "^1.2.2", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/safer-buffer": { "version": "2.1.2", "devOptional": true, @@ -6826,6 +4906,7 @@ }, "node_modules/semver": { "version": "7.5.4", + "dev": true, "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" @@ -6838,65 +4919,29 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.0", + "version": "6.0.2", "dev": true, "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "dev": true, - "license": "ISC" - }, "node_modules/set-function-length": { - "version": "1.2.0", + "version": "1.2.2", "dev": true, "license": "MIT", "dependencies": { - "define-data-property": "^1.1.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" } }, - "node_modules/shebang-command": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/should": { "version": "13.2.3", "dev": true, @@ -6946,80 +4991,50 @@ "license": "MIT" }, "node_modules/side-channel": { - "version": "1.0.4", + "version": "1.0.6", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel/node_modules/call-bind": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/side-channel/node_modules/function-bind": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/side-channel/node_modules/get-intrinsic": { - "version": "1.2.1", + "node_modules/signal-exit": { + "version": "4.1.0", "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "license": "ISC", + "engines": { + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, "node_modules/sinon": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", - "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", + "version": "18.0.0", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0", + "@sinonjs/commons": "^3.0.1", "@sinonjs/fake-timers": "^11.2.2", "@sinonjs/samsam": "^8.0.0", - "diff": "^5.1.0", - "nise": "^5.1.5", - "supports-color": "^7.2.0" + "diff": "^5.2.0", + "nise": "^6.0.0", + "supports-color": "^7" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/sinon" } }, - "node_modules/sinon/node_modules/diff": { - "version": "5.1.0", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/sinon/node_modules/supports-color": { "version": "7.2.0", "dev": true, @@ -7033,111 +5048,36 @@ }, "node_modules/slash": { "version": "3.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/smartwrap": { - "version": "2.0.2", "dev": true, "license": "MIT", - "dependencies": { - "array.prototype.flat": "^1.2.3", - "breakword": "^1.0.5", - "grapheme-splitter": "^1.0.4", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1", - "yargs": "^15.1.0" - }, - "bin": { - "smartwrap": "src/terminal-adapter.js" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/spawndamnit": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "node_modules/spawndamnit/node_modules/cross-spawn": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "node_modules/spawndamnit/node_modules/lru-cache": { - "version": "4.1.5", - "dev": true, - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/spawndamnit/node_modules/which": { - "version": "1.3.1", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/spawndamnit/node_modules/yallist": { - "version": "2.1.2", - "dev": true, - "license": "ISC" - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { "version": "3.0.1", "dev": true, - "license": "MIT", + "license": "SEE LICENSE IN LICENSE", "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "cross-spawn": "^7.0.5", + "signal-exit": "^4.0.1" } }, - "node_modules/spdx-license-ids": { - "version": "3.0.16", - "dev": true, - "license": "CC0-1.0" - }, "node_modules/sprintf-js": { "version": "1.0.3", "dev": true, "license": "BSD-3-Clause" }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "devOptional": true, + "license": "MIT" + }, "node_modules/stream-events": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "license": "MIT", "dependencies": { "stubs": "^3.0.0" } @@ -7166,15 +5106,8 @@ "node_modules/stream-shift": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==" - }, - "node_modules/stream-transform": { - "version": "2.1.3", - "dev": true, - "license": "MIT", - "dependencies": { - "mixme": "^0.5.1" - } + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "license": "MIT" }, "node_modules/string_decoder": { "version": "1.3.0", @@ -7196,53 +5129,38 @@ "node": ">=8" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.8", + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/string.prototype.trimend": { - "version": "1.0.7", + "node_modules/strip-ansi": { + "version": "6.0.1", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.7", + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" @@ -7256,19 +5174,9 @@ "node": ">=4" } }, - "node_modules/strip-indent": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -7284,7 +5192,8 @@ "node_modules/stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==" + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", + "license": "MIT" }, "node_modules/superagent": { "version": "8.1.2", @@ -7343,17 +5252,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/teeny-request": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", @@ -7376,492 +5274,182 @@ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "license": "MIT", "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/teeny-request/node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/teeny-request/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/term-size": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/test": { - "resolved": "test", - "link": true - }, - "node_modules/text-table": { - "version": "0.2.0", - "license": "MIT" - }, - "node_modules/throttle": { - "version": "1.0.3", - "dev": true, - "dependencies": { - "readable-stream": ">= 0.3.0", - "stream-parser": ">= 0.0.2" - }, - "engines": { - "node": ">= v0.8.0" - } - }, - "node_modules/throttle/node_modules/readable-stream": { - "version": "4.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/tmp": { - "version": "0.0.33", - "dev": true, - "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "license": "MIT" - }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-api-utils": { - "version": "1.0.1", - "license": "MIT", - "engines": { - "node": ">=16.13.0" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-node": { - "version": "10.9.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tslib": { - "version": "2.6.0", - "license": "0BSD" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "license": "MIT", - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" - }, - "node_modules/tty-table": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.2", - "csv": "^5.5.3", - "kleur": "^4.1.5", - "smartwrap": "^2.0.2", - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.1", - "yargs": "^17.7.1" - }, - "bin": { - "tty-table": "adapters/terminal-adapter.js" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/tty-table/node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/tty-table/node_modules/cliui": { - "version": "8.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/tty-table/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tty-table/node_modules/yargs": { - "version": "17.7.2", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/tty-table/node_modules/yargs-parser": { - "version": "21.1.1", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/turbo": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/turbo/-/turbo-1.13.0.tgz", - "integrity": "sha512-r02GtNmkOPcQvUzVE6lg474QVLyU02r3yh3lUGqrFHf5h5ZEjgDGWILsAUqplVqjri1Y/oOkTssks4CObTAaiw==", - "dev": true, - "bin": { - "turbo": "bin/turbo" - }, - "optionalDependencies": { - "turbo-darwin-64": "1.13.0", - "turbo-darwin-arm64": "1.13.0", - "turbo-linux-64": "1.13.0", - "turbo-linux-arm64": "1.13.0", - "turbo-windows-64": "1.13.0", - "turbo-windows-arm64": "1.13.0" - } - }, - "node_modules/turbo-darwin-64": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-1.13.0.tgz", - "integrity": "sha512-ctHeJXtQgBcgxnCXwrJTGiq57HtwF7zWz5NTuSv//5yeU01BtQIt62ArKfjudOhRefWJbX3Z5srn88XTb9hfww==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/turbo-darwin-arm64": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-1.13.0.tgz", - "integrity": "sha512-/Q9/pNFkF9w83tNxwMpgapwLYdQ12p8mpty2YQRoUiS9ClWkcqe136jR0mtuMqzlNlpREOFZaoyIthjt6Sdo0g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/turbo-linux-64": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-1.13.0.tgz", - "integrity": "sha512-hgbT7o020BGV4L7Sd8hhFTd5zVKPKxbsr0dPfel/9NkdTmptz2aGZ0Vb2MAa18SY3XaCQpDxmdYuOzvvRpo5ZA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/turbo-linux-arm64": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-1.13.0.tgz", - "integrity": "sha512-WK01i2wDZARrV+HEs495A3hNeGMwQR5suYk7G+ceqqW7b+dOTlQdvUjnI3sg7wAnZPgjafFs/hoBaZdJjVa/nw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/turbo-windows-64": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-1.13.0.tgz", - "integrity": "sha512-hJgSZJZwlWHNwLEthaqJqJWGm4NqF5X/I7vE0sPE4i/jeDl8f0n1hcOkgJkJiNXVxhj+qy/9+4dzbPLKT9imaQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/turbo-windows-arm64": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-1.13.0.tgz", - "integrity": "sha512-L/ErxYoXeq8tmjU/AIGicC9VyBN1zdYw8JlM4yPmMI0pJdY8E4GaYK1IiIazqq7M72lmQhU/WW7fV9FqEktwrw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/tus-js-client": { - "version": "2.3.2", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.1.2", - "combine-errors": "^3.0.3", - "is-stream": "^2.0.0", - "js-base64": "^2.6.1", - "lodash.throttle": "^4.1.1", - "proper-lockfile": "^2.0.1", - "url-parse": "^1.5.7" + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" } }, - "node_modules/type-check": { - "version": "0.4.0", + "node_modules/teeny-request/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "license": "MIT", "dependencies": { - "prelude-ls": "^1.2.1" + "agent-base": "6", + "debug": "4" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 6" } }, - "node_modules/type-detect": { - "version": "4.0.8", + "node_modules/teeny-request/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/term-size": { + "version": "2.2.1", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/type-fest": { - "version": "0.6.0", + "node_modules/test": { + "resolved": "test", + "link": true + }, + "node_modules/throttle": { + "version": "1.0.3", "dev": true, - "license": "(MIT OR CC0-1.0)", + "dependencies": { + "readable-stream": ">= 0.3.0", + "stream-parser": ">= 0.0.2" + }, "engines": { - "node": ">=8" + "node": ">= v0.8.0" } }, - "node_modules/type-is": { - "version": "1.6.18", + "node_modules/throttle/node_modules/readable-stream": { + "version": "4.4.2", "dev": true, "license": "MIT", "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { - "node": ">= 0.6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/typed-array-buffer": { - "version": "1.0.0", + "node_modules/tmp": { + "version": "0.0.33", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" + "os-tmpdir": "~1.0.2" }, "engines": { - "node": ">= 0.4" + "node": ">=0.6.0" } }, - "node_modules/typed-array-byte-length": { - "version": "1.0.0", + "node_modules/to-regex-range": { + "version": "5.0.1", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "is-number": "^7.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8.0" } }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.0", + "node_modules/tr46": { + "version": "0.0.3", + "license": "MIT" + }, + "node_modules/ts-node": { + "version": "10.9.2", "dev": true, "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" }, - "engines": { - "node": ">= 0.4" + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } } }, - "node_modules/typed-array-length": { - "version": "1.0.4", + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslib": { + "version": "2.7.0", + "license": "0BSD" + }, + "node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-is": { + "version": "1.6.18", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "media-typer": "0.3.0", + "mime-types": "~2.1.24" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 0.6" } }, "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.6.2", + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -7871,22 +5459,8 @@ "node": ">=14.17" } }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/undici-types": { - "version": "5.26.5", + "version": "6.20.0", "license": "MIT" }, "node_modules/universalify": { @@ -7897,21 +5471,6 @@ "node": ">= 4.0.0" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "license": "MIT", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "license": "MIT" @@ -7928,23 +5487,6 @@ "dev": true, "license": "MIT" }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, "node_modules/webidl-conversions": { "version": "3.0.1", "license": "BSD-2-Clause" @@ -7959,6 +5501,7 @@ }, "node_modules/which": { "version": "2.0.2", + "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -7970,62 +5513,29 @@ "node": ">= 8" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-module": { - "version": "2.0.1", - "dev": true, - "license": "ISC" - }, - "node_modules/which-pm": { - "version": "2.0.0", + "node_modules/workerpool": { + "version": "6.5.1", "dev": true, - "license": "MIT", - "dependencies": { - "load-yaml-file": "^0.2.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8.15" - } + "license": "Apache-2.0" }, - "node_modules/which-typed-array": { - "version": "1.1.13", + "node_modules/wrap-ansi": { + "version": "7.0.0", "dev": true, "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/workerpool": { - "version": "6.2.1", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/wrap-ansi": { + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", "version": "7.0.0", "dev": true, "license": "MIT", @@ -8055,39 +5565,15 @@ }, "node_modules/yallist": { "version": "4.0.0", + "devOptional": true, "license": "ISC" }, - "node_modules/yargs": { - "version": "15.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/yargs-parser": { - "version": "18.1.3", + "version": "20.2.9", "dev": true, "license": "ISC", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, "engines": { - "node": ">=6" + "node": ">=10" } }, "node_modules/yargs-unparser": { @@ -8134,11 +5620,6 @@ "node": ">=8" } }, - "node_modules/yargs/node_modules/y18n": { - "version": "4.0.3", - "dev": true, - "license": "ISC" - }, "node_modules/yn": { "version": "3.1.1", "dev": true, @@ -8157,64 +5638,63 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/eslint-config-custom": { - "version": "0.0.0", + "packages/azure-store": { + "name": "@tus/azure-store", + "version": "0.1.2", "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^6.19.0", - "eslint": "^8.57.0", - "eslint-config-prettier": "^8.10.0", - "eslint-config-turbo": "^1.11.3", - "eslint-plugin-prettier": "^4.2.1", - "prettier": "^2.8.8" + "@azure/storage-blob": "^12.24.0", + "@tus/utils": "^0.5.0", + "debug": "^4.3.4" }, "devDependencies": { - "@types/eslint": "^8.56.5", - "@types/prettier": "^2.7.3" + "@types/debug": "^4.1.12", + "@types/mocha": "^10.0.6", + "@types/node": "^22.10.1", + "mocha": "^11.0.1", + "should": "^13.2.3" + }, + "engines": { + "node": ">=16" } }, "packages/file-store": { "name": "@tus/file-store", - "version": "1.4.0", + "version": "1.5.1", "license": "MIT", "dependencies": { - "@tus/utils": "^0.3.0", + "@tus/utils": "^0.5.0", "debug": "^4.3.4" }, "devDependencies": { "@types/debug": "^4.1.12", "@types/mocha": "^10.0.6", - "@types/node": "^20.11.5", - "eslint": "^8.57.0", - "eslint-config-custom": "^0.0.0", - "mocha": "^10.4.0", + "@types/node": "^22.10.1", + "mocha": "^11.0.1", "should": "^13.2.3" }, "engines": { "node": ">=16" }, "optionalDependencies": { - "@redis/client": "^1.5.13" + "@redis/client": "^1.6.0" } }, "packages/gcs-store": { "name": "@tus/gcs-store", - "version": "1.3.0", + "version": "1.4.1", "license": "MIT", "dependencies": { - "@tus/utils": "^0.3.0", + "@tus/utils": "^0.5.0", "debug": "^4.3.4" }, "devDependencies": { "@google-cloud/storage": "^7.12.0", - "@tus/server": "^1.7.0", + "@tus/server": "^1.10.0", "@types/debug": "^4.1.12", "@types/mocha": "^10.0.6", - "@types/node": "^20.11.5", - "eslint": "^8.57.0", - "eslint-config-custom": "^0.0.0", - "mocha": "^10.4.0", + "@types/node": "^22.10.1", + "mocha": "^11.0.1", "should": "^13.2.3" }, "engines": { @@ -8226,12 +5706,12 @@ }, "packages/s3-store": { "name": "@tus/s3-store", - "version": "1.5.0", + "version": "1.7.0", "license": "MIT", "dependencies": { - "@aws-sdk/client-s3": "^3.490.0", + "@aws-sdk/client-s3": "^3.717.0", "@shopify/semaphore": "^3.1.0", - "@tus/utils": "^0.3.0", + "@tus/utils": "^0.5.1", "debug": "^4.3.4", "multistream": "^4.1.0" }, @@ -8239,10 +5719,8 @@ "@types/debug": "^4.1.12", "@types/mocha": "^10.0.6", "@types/multistream": "^4.1.3", - "@types/node": "^20.11.5", - "eslint": "^8.57.0", - "eslint-config-custom": "^0.0.0", - "mocha": "^10.4.0", + "@types/node": "^22.10.1", + "mocha": "^11.0.1", "should": "^13.2.3" }, "engines": { @@ -8251,10 +5729,10 @@ }, "packages/server": { "name": "@tus/server", - "version": "1.7.0", + "version": "1.10.1", "license": "MIT", "dependencies": { - "@tus/utils": "^0.3.0", + "@tus/utils": "^0.5.1", "debug": "^4.3.4", "lodash.throttle": "^4.1.1" }, @@ -8262,15 +5740,13 @@ "@types/debug": "^4.1.12", "@types/lodash.throttle": "^4.1.9", "@types/mocha": "^10.0.6", - "@types/node": "^20.11.5", + "@types/node": "^22.10.1", "@types/sinon": "^17.0.3", "@types/supertest": "^2.0.16", - "eslint": "^8.57.0", - "eslint-config-custom": "^0.0.0", - "mocha": "^10.4.0", - "node-mocks-http": "^1.14.1", + "mocha": "^11.0.1", + "node-mocks-http": "^1.16.1", "should": "^13.2.3", - "sinon": "^17.0.1", + "sinon": "^18.0.0", "supertest": "^6.3.4", "ts-node": "^10.9.2" }, @@ -8278,20 +5754,20 @@ "node": ">=16" }, "optionalDependencies": { - "@redis/client": "^1.5.13" + "@redis/client": "^1.6.0", + "ioredis": "^5.4.1" } }, "packages/utils": { "name": "@tus/utils", - "version": "0.3.0", + "version": "0.5.1", "license": "MIT", "devDependencies": { "@types/debug": "^4.1.12", "@types/mocha": "^10.0.6", - "@types/node": "^20.11.5", - "eslint": "^8.57.0", - "eslint-config-custom": "^0.0.0", - "mocha": "^10.4.0", + "@types/node": "^22.10.1", + "ioredis": "^5.4.1", + "mocha": "^11.0.1", "should": "^13.2.3", "ts-node": "^10.9.2" }, @@ -8302,22 +5778,22 @@ "test": { "dependencies": { "@google-cloud/storage": "^7.12.0", - "@tus/file-store": "^1.4.0", - "@tus/gcs-store": "^1.3.0", - "@tus/s3-store": "^1.5.0", - "@tus/server": "^1.7.0" + "@tus/file-store": "^1.5.1", + "@tus/gcs-store": "^1.4.1", + "@tus/s3-store": "^1.7.0", + "@tus/server": "^1.10.1" }, "devDependencies": { "@types/mocha": "^10.0.6", - "@types/node": "^20.11.5", + "@types/node": "^22.10.1", "@types/rimraf": "^3.0.2", "@types/sinon": "^17.0.3", "@types/supertest": "^2.0.16", "@types/throttle": "^1.0.4", - "mocha": "^10.4.0", + "mocha": "^11.0.1", "rimraf": "^3.0.2", "should": "^13.2.3", - "sinon": "^17.0.1", + "sinon": "^18.0.0", "supertest": "^6.3.4", "throttle": "^1.0.3", "ts-node": "^10.9.2" diff --git a/package.json b/package.json index bfe6fb9d..a940681c 100644 --- a/package.json +++ b/package.json @@ -1,33 +1,22 @@ { "$schema": "https://json.schemastore.org/package.json", "private": true, - "workspaces": [ - "packages/*", - "demo", - "test" - ], + "workspaces": ["packages/*", "test"], "scripts": { "build": "tsc --build", - "demo": "npm run --workspace demo start", - "demo:gcs": "npm run --workspace demo start:gcs", - "demo:s3": "npm run --workspace demo start:s3", - "lint": "eslint .", - "format": "eslint --fix .", + "lint": "biome lint --write .", + "format": "biome format --write .", + "format:check": "biome format --error-on-warnings .", "pretest": "tsc --build", - "test": "turbo run test", + "test": "npm test -w ./packages", "version": "changeset version", "release": "gh workflow run release", - "release:local": "turbo run build && changeset publish" + "release:local": "npm run build && changeset publish" }, "devDependencies": { + "@biomejs/biome": "1.9.4", "@changesets/changelog-github": "^0.5.0", - "@changesets/cli": "^2.27.1", - "eslint": "^8.57.0", - "eslint-config-custom": "^0.0.0", - "eslint-plugin-prettier": "^4.2.1", - "prettier": "^2.8.8", - "turbo": "^1.13.0", - "typescript": "^5.5.4" - }, - "version": "0.0.0" + "@changesets/cli": "^2.27.10", + "typescript": "^5.6.2" + } } diff --git a/packages/azure-store/CHANGELOG.md b/packages/azure-store/CHANGELOG.md new file mode 100644 index 00000000..c5445afa --- /dev/null +++ b/packages/azure-store/CHANGELOG.md @@ -0,0 +1,20 @@ +# @tus/azure-store + +## 0.1.2 + +### Patch Changes + +- 37dcd55: Correctly publish dist folder + +## 0.1.1 + +### Patch Changes + +- Updated dependencies [8f19a53] + - @tus/utils@0.5.0 + +## 0.1.0 + +### Minor Changes + +- 919cd85: Add basic store for Azure diff --git a/packages/azure-store/LICENSE b/packages/azure-store/LICENSE new file mode 100644 index 00000000..b9829433 --- /dev/null +++ b/packages/azure-store/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 tus - Resumable File Uploads + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/packages/azure-store/README.md b/packages/azure-store/README.md new file mode 100644 index 00000000..853b88de --- /dev/null +++ b/packages/azure-store/README.md @@ -0,0 +1,114 @@ +# `@tus/azure-store` + +Azure Store based on the Append Blob Client [Azure Blob AppendBlobClient](https://learn.microsoft.com/en-us/rest/api/storageservices/append-block). + +## Contents + +- [Install](#install) +- [Use](#use) +- [API](#api) + - [`new AzureStore(options)`](#new-azurestoreoptions) +- [Extensions](#extensions) +- [Types](#types) +- [Compatibility](#compatibility) +- [Contribute](#contribute) +- [License](#license) + +## Install + +In Node.js (16.0+), install with npm: + +```bash +npm install @tus/azure-store +``` + +## Use + +```js +const {Server} = require('@tus/server') +const {AzureStore} = require('@tus/azure-store') + +const server = new Server({ + path: '/files', + datastore: new AzureStore({ + account: process.env.AZURE_ACCOUNT_ID, + accountKey: process.env.AZURE_ACCOUNT_KEY, + containerName: process.env.AZURE_CONTAINER_NAME, + }), +}) +// ... +``` + +## API + +This package exports `AzureStore`. There is no default export. + +### `new AzureStore(options)` + +Creates a new azure store with options. + +#### `options.account` + +Azure account ID (`string`). + +#### `options.accountKey` + +Azure account key (`string`). + +#### `options.containerName` + +Azure storage container name (`string`). + +#### `options.cache` + +Provide your own cache solution for the metadata of uploads ([`KvStore`][]) to reduce the calls to storage server. +Default is ([`MemoryKvStore`][]) which stores the data in memory. + +## Extensions + +The tus protocol supports optional [extensions][]. Below is a table of the supported +extensions in `@tus/azure-store`. More will be added in the future releases. + +| Extension | `@tus/file-store` | +| ------------------------ | ----------------- | +| [Creation][] | ✅ | +| [Creation With Upload][] | ✅ | +| [Expiration][] | ❌ | +| [Checksum][] | ❌ | +| [Termination][] | ❌ | +| [Concatenation][] | ❌ | + +## Types + +This package is fully typed with TypeScript. + +## Compatibility + +This package requires Node.js 16.0+. + +## Contribute + +See +[`contributing.md`](https://github.com/tus/tus-node-server/blob/main/.github/contributing.md). + +## License + +[MIT](https://github.com/tus/tus-node-server/blob/master/license) © +[tus](https://github.com/tus) + +[extensions]: https://tus.io/protocols/resumable-upload.html#protocol-extensions +[creation]: https://tus.io/protocols/resumable-upload.html#creation +[creation with upload]: + https://tus.io/protocols/resumable-upload.html#creation-with-upload +[expiration]: https://tus.io/protocols/resumable-upload.html#expiration +[checksum]: https://tus.io/protocols/resumable-upload.html#checksum +[termination]: https://tus.io/protocols/resumable-upload.html#termination +[concatenation]: https://tus.io/protocols/resumable-upload.html#concatenation +[`cleanUpExpiredUploads`]: + https://github.com/tus/tus-node-server/tree/main/packages/server#cleanupexpireduploads +[kvstores]: https://github.com/tus/tus-node-server/tree/main/packages/server#kvstores +[`KvStore`]: + https://github.com/tus/tus-node-server/blob/main/packages/utils/src/kvstores/Types.ts + +[`MemoryKvStore`]: + https://github.com/tus/tus-node-server/blob/main/packages/utils/src/kvstores/MemoryKvStore.ts diff --git a/packages/azure-store/package.json b/packages/azure-store/package.json new file mode 100644 index 00000000..b43211e1 --- /dev/null +++ b/packages/azure-store/package.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://json.schemastore.org/package.json", + "name": "@tus/azure-store", + "version": "0.1.2", + "description": "Azure blob storage for @tus/server", + "main": "dist/index.js", + "homepage": "https://github.com/tus/tus-node-server#readme", + "bugs": "https://github.com/tus/tus-node-server/issues", + "repository": "tus/tus-node-server", + "files": [ + "README.md", + "LICENSE", + "dist", + "src" + ], + "license": "MIT", + "scripts": { + "build": "tsc --build", + "test": "mocha --exit --extension ts --require ts-node/register" + }, + "dependencies": { + "@tus/utils": "^0.5.0", + "@azure/storage-blob": "^12.24.0", + "debug": "^4.3.4" + }, + "devDependencies": { + "@types/debug": "^4.1.12", + "@types/mocha": "^10.0.6", + "@types/node": "^22.10.1", + "mocha": "^11.0.1", + "should": "^13.2.3" + }, + "engines": { + "node": ">=16" + } +} diff --git a/packages/azure-store/src/index.ts b/packages/azure-store/src/index.ts new file mode 100644 index 00000000..cd41c923 --- /dev/null +++ b/packages/azure-store/src/index.ts @@ -0,0 +1,250 @@ +import type stream from 'node:stream' +import debug from 'debug' +import { + DataStore, + Upload, + ERRORS, + type KvStore, + MemoryKvStore, + TUS_RESUMABLE, +} from '@tus/utils' +import { + type AppendBlobClient, + type BlobGetPropertiesResponse, + BlobServiceClient, + type ContainerClient, + StorageSharedKeyCredential, +} from '@azure/storage-blob' + +type Options = { + cache?: KvStore + account: string + accountKey: string + containerName: string +} + +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 + + constructor(options: 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.accountKey) { + throw new Error('Azure store must have a account key') + } + if (!options.containerName) { + throw new Error('Azure store must have a container name') + } + + const storageAccountBaseUrl = `https://${options.account}.blob.core.windows.net` + const sharedKeyCredential = new StorageSharedKeyCredential( + options.account, + options.accountKey + ) + + this.blobServiceClient = new BlobServiceClient( + storageAccountBaseUrl, + sharedKeyCredential + ) + 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. + */ + private async saveMetadata(appendBlobClient: AppendBlobClient, upload: Upload) { + log(`[${upload.id}] saving metadata`) + + await this.cache.set(appendBlobClient.url, upload) + + await appendBlobClient.setMetadata( + { + tus_version: TUS_RESUMABLE, + upload: JSON.stringify(upload), + }, + {} + ) + + 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) + + if (cached) { + log(`[${cached.id}] metadata returned from cache`) + return cached + } + + let propertyData: BlobGetPropertiesResponse + 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) as Upload + + 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 + */ + public async read(file_id: string) { + 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. + */ + public async create(upload: 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 + */ + public async getUpload(id: string): Promise { + 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. + */ + public async write( + stream: stream.Readable, + id: string, + offset: number + ): Promise { + 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: Buffer[] = [] + + stream.on('data', async (chunk: Buffer) => { + 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.') + } + }) + } + + public async declareUploadLength(id: string, upload_length: number) { + 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) + } +} diff --git a/packages/azure-store/test/index.ts b/packages/azure-store/test/index.ts new file mode 100644 index 00000000..1a9b567c --- /dev/null +++ b/packages/azure-store/test/index.ts @@ -0,0 +1,32 @@ +import 'should' +import path from 'node:path' +import {AzureStore} from '../src' +import * as shared from 'test/stores.test' + +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 +}) diff --git a/packages/azure-store/tsconfig.build.json b/packages/azure-store/tsconfig.build.json new file mode 100644 index 00000000..06719e77 --- /dev/null +++ b/packages/azure-store/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig.json", + "references": [{ "path": "../utils/tsconfig.build.json" }], + "extends": "../../tsconfig.base.json", + "include": ["src"], + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + } +} diff --git a/packages/azure-store/tsconfig.json b/packages/azure-store/tsconfig.json new file mode 100644 index 00000000..823c3da5 --- /dev/null +++ b/packages/azure-store/tsconfig.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig.json", + "references": [ + { "path": "./tsconfig.build.json" }, + { "path": "../../test/tsconfig.json" } + ], + "extends": "../../tsconfig.base.json", + "exclude": ["src"], + "compilerOptions": { + "noEmit": true + } +} diff --git a/packages/eslint-config-custom/index.js b/packages/eslint-config-custom/index.js deleted file mode 100644 index 2ccbf0c2..00000000 --- a/packages/eslint-config-custom/index.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = { - env: {es6: true, node: true, mocha: true}, - parser: '@typescript-eslint/parser', - extends: [ - 'turbo', - 'plugin:@typescript-eslint/recommended', - 'plugin:prettier/recommended', - ], - plugins: ['@typescript-eslint', 'prettier'], - rules: { - 'no-new': 'off', - complexity: 'off', - camelcase: 'off', - 'no-warning-comments': 'off', - 'prettier/prettier': 'error', - '@typescript-eslint/no-explicit-any': 'error', - '@typescript-eslint/ban-ts-comment': 'warn', - '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/no-unused-vars': 'error', - 'capitalized-comments': 'off', - }, - ignorePatterns: ['eslint-config-custom', 'demo', 'dist', 'node_modules'], -} diff --git a/packages/eslint-config-custom/package.json b/packages/eslint-config-custom/package.json deleted file mode 100644 index 6634bb83..00000000 --- a/packages/eslint-config-custom/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/package.json", - "name": "eslint-config-custom", - "private": true, - "version": "0.0.0", - "main": "index.js", - "license": "MIT", - "publishConfig": { - "access": "public" - }, - "dependencies": { - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^6.19.0", - "eslint": "^8.57.0", - "eslint-config-prettier": "^8.10.0", - "eslint-config-turbo": "^1.11.3", - "eslint-plugin-prettier": "^4.2.1", - "prettier": "^2.8.8" - }, - "devDependencies": { - "@types/eslint": "^8.56.5", - "@types/prettier": "^2.7.3" - } -} diff --git a/packages/file-store/CHANGELOG.md b/packages/file-store/CHANGELOG.md index 092f1d74..e994b5d0 100644 --- a/packages/file-store/CHANGELOG.md +++ b/packages/file-store/CHANGELOG.md @@ -1,5 +1,23 @@ # @tus/file-store +## 1.5.1 + +### Patch Changes + +- Updated dependencies [8f19a53] + - @tus/utils@0.5.0 + +## 1.5.0 + +### Minor Changes + +- de28c6e: Publish source maps and declaration maps + +### Patch Changes + +- Updated dependencies [de28c6e] + - @tus/utils@0.4.0 + ## 1.4.0 ### Minor Changes diff --git a/packages/file-store/package.json b/packages/file-store/package.json index d8b7715d..c5448bb9 100644 --- a/packages/file-store/package.json +++ b/packages/file-store/package.json @@ -1,39 +1,31 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@tus/file-store", - "version": "1.4.0", + "version": "1.5.1", "description": "Local file storage for @tus/server", "main": "dist/index.js", "homepage": "https://github.com/tus/tus-node-server#readme", "bugs": "https://github.com/tus/tus-node-server/issues", "repository": "tus/tus-node-server", - "files": [ - "README.md", - "LICENSE", - "dist" - ], + "files": ["README.md", "LICENSE", "dist", "src"], "license": "MIT", "scripts": { "build": "tsc --build", - "lint": "eslint .", - "format": "eslint --fix .", "test": "mocha --exit --extension ts --require ts-node/register" }, "dependencies": { - "@tus/utils": "^0.3.0", + "@tus/utils": "^0.5.0", "debug": "^4.3.4" }, "devDependencies": { "@types/debug": "^4.1.12", "@types/mocha": "^10.0.6", - "@types/node": "^20.11.5", - "eslint": "^8.57.0", - "eslint-config-custom": "^0.0.0", - "mocha": "^10.4.0", + "@types/node": "^22.10.1", + "mocha": "^11.0.1", "should": "^13.2.3" }, "optionalDependencies": { - "@redis/client": "^1.5.13" + "@redis/client": "^1.6.0" }, "engines": { "node": ">=16" diff --git a/packages/file-store/src/index.ts b/packages/file-store/src/index.ts index 163adc2d..e54af0f8 100644 --- a/packages/file-store/src/index.ts +++ b/packages/file-store/src/index.ts @@ -3,11 +3,11 @@ import fs from 'node:fs' import fsProm from 'node:fs/promises' import path from 'node:path' import stream from 'node:stream' -import http from 'node:http' +import type http from 'node:http' import debug from 'debug' -import {Configstore, FileConfigstore} from './configstores' +import {type Configstore, FileConfigstore} from './configstores' import {DataStore, Upload, ERRORS} from '@tus/utils' export * from './configstores' diff --git a/packages/file-store/test/index.ts b/packages/file-store/test/index.ts index ea8bc3c5..21d7ed3e 100644 --- a/packages/file-store/test/index.ts +++ b/packages/file-store/test/index.ts @@ -92,7 +92,7 @@ describe('FileStore', function () { }) describe('FileConfigstore', () => { - it('should ignore random files in directory when calling list()', async function () { + it('should ignore random files in directory when calling list()', async () => { const store = new FileConfigstore(storePath) const files = ['tus', 'tus.json', 'tu', 'tuss.json', 'random'] for (const file of files) { diff --git a/packages/file-store/tsconfig.build.json b/packages/file-store/tsconfig.build.json index 1342a95a..06719e77 100644 --- a/packages/file-store/tsconfig.build.json +++ b/packages/file-store/tsconfig.build.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/tsconfig.json", - "references": [{"path": "../utils/tsconfig.build.json"}], + "references": [{ "path": "../utils/tsconfig.build.json" }], "extends": "../../tsconfig.base.json", "include": ["src"], "compilerOptions": { diff --git a/packages/file-store/tsconfig.json b/packages/file-store/tsconfig.json index 22f7865a..823c3da5 100644 --- a/packages/file-store/tsconfig.json +++ b/packages/file-store/tsconfig.json @@ -1,6 +1,9 @@ { "$schema": "https://json.schemastore.org/tsconfig.json", - "references": [{"path": "./tsconfig.build.json"}, {"path": "../../test/tsconfig.json"}], + "references": [ + { "path": "./tsconfig.build.json" }, + { "path": "../../test/tsconfig.json" } + ], "extends": "../../tsconfig.base.json", "exclude": ["src"], "compilerOptions": { diff --git a/packages/gcs-store/CHANGELOG.md b/packages/gcs-store/CHANGELOG.md index 99a90468..f4a8e444 100644 --- a/packages/gcs-store/CHANGELOG.md +++ b/packages/gcs-store/CHANGELOG.md @@ -1,5 +1,23 @@ # @tus/gcs-store +## 1.4.1 + +### Patch Changes + +- Updated dependencies [8f19a53] + - @tus/utils@0.5.0 + +## 1.4.0 + +### Minor Changes + +- de28c6e: Publish source maps and declaration maps + +### Patch Changes + +- Updated dependencies [de28c6e] + - @tus/utils@0.4.0 + ## 1.3.0 ### Minor Changes diff --git a/packages/gcs-store/package.json b/packages/gcs-store/package.json index 465d972e..93172a5d 100644 --- a/packages/gcs-store/package.json +++ b/packages/gcs-store/package.json @@ -1,37 +1,29 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@tus/gcs-store", - "version": "1.3.0", + "version": "1.4.1", "description": "Google Cloud Storage for @tus/server", "main": "dist/index.js", "homepage": "https://github.com/tus/tus-node-server#readme", "bugs": "https://github.com/tus/tus-node-server/issues", "repository": "tus/tus-node-server", "license": "MIT", - "files": [ - "README.md", - "LICENSE", - "dist" - ], + "files": ["README.md", "LICENSE", "dist", "src"], "scripts": { "build": "tsc --build", - "lint": "eslint .", - "format": "eslint --fix .", "test": "mocha --timeout 30000 --exit --extension ts --require ts-node/register" }, "dependencies": { - "@tus/utils": "^0.3.0", + "@tus/utils": "^0.5.0", "debug": "^4.3.4" }, "devDependencies": { "@google-cloud/storage": "^7.12.0", - "@tus/server": "^1.7.0", + "@tus/server": "^1.10.0", "@types/debug": "^4.1.12", "@types/mocha": "^10.0.6", - "@types/node": "^20.11.5", - "eslint": "^8.57.0", - "eslint-config-custom": "^0.0.0", - "mocha": "^10.4.0", + "@types/node": "^22.10.1", + "mocha": "^11.0.1", "should": "^13.2.3" }, "peerDependencies": { diff --git a/packages/gcs-store/src/index.ts b/packages/gcs-store/src/index.ts index f82781e6..0e1441bd 100644 --- a/packages/gcs-store/src/index.ts +++ b/packages/gcs-store/src/index.ts @@ -1,6 +1,6 @@ -import {Bucket} from '@google-cloud/storage' +import type {Bucket, CreateWriteStreamOptions} from '@google-cloud/storage' import stream from 'node:stream' -import http from 'node:http' +import type http from 'node:http' import debug from 'debug' import {ERRORS, TUS_RESUMABLE, Upload, DataStore} from '@tus/utils' @@ -37,7 +37,7 @@ export class GCSStore extends DataStore { file.storage = {type: 'gcs', path: file.id, bucket: this.bucket.name} - const options = { + const options: CreateWriteStreamOptions = { metadata: { metadata: { tus_version: TUS_RESUMABLE, @@ -45,6 +45,9 @@ export class GCSStore extends DataStore { }, }, } + if (file.metadata?.contentType) { + options.contentType = file.metadata.contentType + } const fake_stream = new stream.PassThrough() fake_stream.end() fake_stream @@ -133,7 +136,7 @@ export class GCSStore extends DataStore { return } - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: todo this.bucket.file(id).getMetadata((error: any, metadata: any) => { if (error && error.code === 404) { return reject(ERRORS.FILE_NOT_FOUND) diff --git a/packages/gcs-store/tsconfig.build.json b/packages/gcs-store/tsconfig.build.json index a34ce5d0..d199726e 100644 --- a/packages/gcs-store/tsconfig.build.json +++ b/packages/gcs-store/tsconfig.build.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/tsconfig.json", - "references": [{"path": "../utils//tsconfig.build.json"}], + "references": [{ "path": "../utils//tsconfig.build.json" }], "extends": "../../tsconfig.base.json", "include": ["src"], "compilerOptions": { diff --git a/packages/gcs-store/tsconfig.json b/packages/gcs-store/tsconfig.json index 22f7865a..823c3da5 100644 --- a/packages/gcs-store/tsconfig.json +++ b/packages/gcs-store/tsconfig.json @@ -1,6 +1,9 @@ { "$schema": "https://json.schemastore.org/tsconfig.json", - "references": [{"path": "./tsconfig.build.json"}, {"path": "../../test/tsconfig.json"}], + "references": [ + { "path": "./tsconfig.build.json" }, + { "path": "../../test/tsconfig.json" } + ], "extends": "../../tsconfig.base.json", "exclude": ["src"], "compilerOptions": { diff --git a/packages/s3-store/CHANGELOG.md b/packages/s3-store/CHANGELOG.md index f46c2f97..a45f3279 100644 --- a/packages/s3-store/CHANGELOG.md +++ b/packages/s3-store/CHANGELOG.md @@ -1,5 +1,42 @@ # @tus/s3-store +## 1.7.0 + +### Minor Changes + +- b1c07bc: Change private modifier to protected + +### Patch Changes + +- 8236c05: Bump @aws-sdk/client-s3 from 3.703.0 to 3.717.0 +- Updated dependencies [42c6267] + - @tus/utils@0.5.1 + +## 1.6.2 + +### Patch Changes + +- 32d847d: Fix increment for part numbers +- fdad8ff: Bump @aws-sdk/client-s3 from 3.701.0 to 3.703.0 + +## 1.6.1 + +### Patch Changes + +- Updated dependencies [8f19a53] + - @tus/utils@0.5.0 + +## 1.6.0 + +### Minor Changes + +- de28c6e: Publish source maps and declaration maps + +### Patch Changes + +- Updated dependencies [de28c6e] + - @tus/utils@0.4.0 + ## 1.5.0 ### Minor Changes diff --git a/packages/s3-store/README.md b/packages/s3-store/README.md index bf34df0f..5f6e152a 100644 --- a/packages/s3-store/README.md +++ b/packages/s3-store/README.md @@ -146,7 +146,7 @@ to abort incomplete multipart uploads. Unlike other stores, the expiration extension on the S3 store does not need to call [`server.cleanUpExpiredUploads()`][cleanExpiredUploads]. The store creates a -`Tus-Complete` tag for all objects, including `.part` and `.info` files, to indicate +`Tus-Completed` tag for all objects, including `.part` and `.info` files, to indicate whether an upload is finished. This means you could setup a [lifecyle][] policy to automatically clean them up without a CRON job. @@ -156,7 +156,7 @@ automatically clean them up without a CRON job. { "Filter": { "Tag": { - "Key": "Tus-Complete", + "Key": "Tus-Completed", "Value": "false" } }, diff --git a/packages/s3-store/package.json b/packages/s3-store/package.json index dc468d81..309f11e9 100644 --- a/packages/s3-store/package.json +++ b/packages/s3-store/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@tus/s3-store", - "version": "1.5.0", + "version": "1.7.0", "description": "AWS S3 store for @tus/server", "main": "dist/index.js", "homepage": "https://github.com/tus/tus-node-server#readme", @@ -11,18 +11,17 @@ "files": [ "README.md", "LICENSE", - "dist" + "dist", + "src" ], "scripts": { "build": "tsc --build", - "lint": "eslint .", - "format": "eslint --fix .", "test": "mocha --timeout 40000 --exit --extension ts --require ts-node/register" }, "dependencies": { - "@aws-sdk/client-s3": "^3.490.0", + "@aws-sdk/client-s3": "^3.717.0", "@shopify/semaphore": "^3.1.0", - "@tus/utils": "^0.3.0", + "@tus/utils": "^0.5.1", "debug": "^4.3.4", "multistream": "^4.1.0" }, @@ -30,10 +29,8 @@ "@types/debug": "^4.1.12", "@types/mocha": "^10.0.6", "@types/multistream": "^4.1.3", - "@types/node": "^20.11.5", - "eslint": "^8.57.0", - "eslint-config-custom": "^0.0.0", - "mocha": "^10.4.0", + "@types/node": "^22.10.1", + "mocha": "^11.0.1", "should": "^13.2.3" }, "engines": { diff --git a/packages/s3-store/src/index.ts b/packages/s3-store/src/index.ts index 88b2b632..5768f2c0 100644 --- a/packages/s3-store/src/index.ts +++ b/packages/s3-store/src/index.ts @@ -3,7 +3,8 @@ import fs, {promises as fsProm} from 'node:fs' import stream, {promises as streamProm} from 'node:stream' import type {Readable} from 'node:stream' -import AWS, {NoSuchKey, NotFound, S3, S3ClientConfig} from '@aws-sdk/client-s3' +import type AWS from '@aws-sdk/client-s3' +import {NoSuchKey, NotFound, S3, type S3ClientConfig} from '@aws-sdk/client-s3' import debug from 'debug' import { @@ -12,18 +13,18 @@ import { Upload, ERRORS, TUS_RESUMABLE, - KvStore, + type KvStore, MemoryKvStore, } from '@tus/utils' -import {Semaphore, Permit} from '@shopify/semaphore' +import {Semaphore, type Permit} from '@shopify/semaphore' import MultiStream from 'multistream' import crypto from 'node:crypto' import path from 'node:path' const log = debug('tus-node-server:stores:s3store') -type Options = { +export type Options = { // The preferred part size for parts send to S3. Can not be lower than 5MiB or more than 5GiB. // The server calculates the optimal part size, which takes this size into account, // but may increase it to not exceed the S3 10K parts limit. @@ -81,13 +82,13 @@ function calcOffsetFromParts(parts?: Array) { // For each incoming PATCH request (a call to `write`), a new part is uploaded // to S3. export class S3Store extends DataStore { - private bucket: string - private cache: KvStore - private client: S3 - private preferredPartSize: number - private expirationPeriodInMilliseconds = 0 - private useTags = true - private partUploadSemaphore: Semaphore + protected bucket: string + protected cache: KvStore + protected client: S3 + protected preferredPartSize: number + protected expirationPeriodInMilliseconds = 0 + protected useTags = true + protected partUploadSemaphore: Semaphore public maxMultipartParts = 10_000 as const public minPartSize = 5_242_880 as const // 5MiB public maxUploadSize = 5_497_558_138_880 as const // 5TiB @@ -130,7 +131,7 @@ export class S3Store extends DataStore { * on the S3 object's `Metadata` field, so that only a `headObject` * is necessary to retrieve the data. */ - private async saveMetadata(upload: Upload, uploadId: string) { + protected async saveMetadata(upload: Upload, uploadId: string) { log(`[${upload.id}] saving metadata`) await this.client.putObject({ Bucket: this.bucket, @@ -145,7 +146,7 @@ export class S3Store extends DataStore { log(`[${upload.id}] metadata file saved`) } - private async completeMetadata(upload: Upload) { + protected async completeMetadata(upload: Upload) { if (!this.shouldUseExpirationTags()) { return } @@ -168,7 +169,7 @@ export class S3Store extends DataStore { * There's a small and simple caching mechanism to avoid multiple * HTTP calls to S3. */ - private async getMetadata(id: string): Promise { + protected async getMetadata(id: string): Promise { const cached = await this.cache.get(id) if (cached) { return cached @@ -184,7 +185,7 @@ export class S3Store extends DataStore { 'upload-id': Metadata?.['upload-id'] as string, file: new Upload({ id, - size: file.size ? Number.parseInt(file.size, 10) : undefined, + size: Number.isFinite(file.size) ? Number.parseInt(file.size, 10) : undefined, offset: Number.parseInt(file.offset, 10), metadata: file.metadata, creation_date: file.creation_date, @@ -195,11 +196,11 @@ export class S3Store extends DataStore { return metadata } - private infoKey(id: string) { + protected infoKey(id: string) { return `${id}.info` } - private partKey(id: string, isIncomplete = false) { + protected partKey(id: string, isIncomplete = false) { if (isIncomplete) { id += '.part' } @@ -211,7 +212,7 @@ export class S3Store extends DataStore { return id } - private async uploadPart( + protected async uploadPart( metadata: MetadataValue, readStream: fs.ReadStream | Readable, partNumber: number @@ -227,7 +228,7 @@ export class S3Store extends DataStore { return data.ETag as string } - private async uploadIncompletePart( + protected async uploadIncompletePart( id: string, readStream: fs.ReadStream | Readable ): Promise { @@ -241,7 +242,7 @@ export class S3Store extends DataStore { return data.ETag as string } - private async downloadIncompletePart(id: string) { + protected async downloadIncompletePart(id: string) { const incompletePart = await this.getIncompletePart(id) if (!incompletePart) { @@ -287,7 +288,11 @@ export class S3Store extends DataStore { return fileReader } - return {size: incompletePartSize, path: filePath, createReader: createReadStream} + return { + size: incompletePartSize, + path: filePath, + createReader: createReadStream, + } } catch (err) { fsProm.rm(filePath).catch(() => { /* ignore */ @@ -296,7 +301,7 @@ export class S3Store extends DataStore { } } - private async getIncompletePart(id: string): Promise { + protected async getIncompletePart(id: string): Promise { try { const data = await this.client.getObject({ Bucket: this.bucket, @@ -312,7 +317,7 @@ export class S3Store extends DataStore { } } - private async getIncompletePartSize(id: string): Promise { + protected async getIncompletePartSize(id: string): Promise { try { const data = await this.client.headObject({ Bucket: this.bucket, @@ -327,7 +332,7 @@ export class S3Store extends DataStore { } } - private async deleteIncompletePart(id: string): Promise { + protected async deleteIncompletePart(id: string): Promise { await this.client.deleteObject({ Bucket: this.bucket, Key: this.partKey(id, true), @@ -337,7 +342,7 @@ export class S3Store extends DataStore { /** * Uploads a stream to s3 using multiple parts */ - private async uploadParts( + protected async uploadParts( metadata: MetadataValue, readStream: stream.Readable, currentPartNumber: number, @@ -362,14 +367,14 @@ export class S3Store extends DataStore { .on('chunkFinished', ({path, size: partSize}) => { pendingChunkFilepath = null - const partNumber = currentPartNumber++ const acquiredPermit = permit + const partNumber = currentPartNumber++ offset += partSize const isFinalPart = size === offset - // eslint-disable-next-line no-async-promise-executor + // biome-ignore lint/suspicious/noAsyncPromiseExecutor: it's fine const deferred = new Promise(async (resolve, reject) => { try { // Only the first chunk of each PATCH request can prepend @@ -424,7 +429,7 @@ export class S3Store extends DataStore { * Completes a multipart upload on S3. * This is where S3 concatenates all the uploaded parts. */ - private async finishMultipartUpload(metadata: MetadataValue, parts: Array) { + protected async finishMultipartUpload(metadata: MetadataValue, parts: Array) { const response = await this.client.completeMultipartUpload({ Bucket: this.bucket, Key: metadata.file.id, @@ -445,7 +450,7 @@ export class S3Store extends DataStore { * Gets the number of complete parts/chunks already uploaded to S3. * Retrieves only consecutive parts. */ - private async retrieveParts( + protected async retrieveParts( id: string, partNumberMarker?: string ): Promise> { @@ -468,7 +473,7 @@ export class S3Store extends DataStore { } if (!partNumberMarker) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + // biome-ignore lint/style/noNonNullAssertion: it's fine parts.sort((a, b) => a.PartNumber! - b.PartNumber!) } @@ -478,12 +483,12 @@ export class S3Store extends DataStore { /** * Removes cached data for a given file. */ - private async clearCache(id: string) { + protected async clearCache(id: string) { log(`[${id}] removing cached data`) await this.cache.delete(id) } - private calcOptimalPartSize(size?: number): number { + protected calcOptimalPartSize(size?: number): number { // When upload size is not know we assume largest possible value (`maxUploadSize`) if (size === undefined) { size = this.maxUploadSize @@ -531,7 +536,11 @@ export class S3Store extends DataStore { upload.creation_date = new Date().toISOString() const res = await this.client.createMultipartUpload(request) - upload.storage = {type: 's3', path: res.Key as string, bucket: this.bucket} + upload.storage = { + type: 's3', + path: res.Key as string, + bucket: this.bucket, + } await this.saveMetadata(upload, res.UploadId as string) log(`[${upload.id}] multipart upload created (${res.UploadId})`) @@ -553,7 +562,7 @@ export class S3Store extends DataStore { // Metadata request needs to happen first const metadata = await this.getMetadata(id) const parts = await this.retrieveParts(id) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + // biome-ignore lint/style/noNonNullAssertion: it's fine const partNumber: number = parts.length > 0 ? parts[parts.length - 1].PartNumber! : 0 const nextPartNumber = partNumber + 1 @@ -711,17 +720,20 @@ export class S3Store extends DataStore { ) }) || [] - const objectsToDelete = expiredUploads.reduce((all, expiredUpload) => { - all.push( - { - key: this.infoKey(expiredUpload.Key as string), - }, - { - key: this.partKey(expiredUpload.Key as string, true), - } - ) - return all - }, [] as {key: string}[]) + const objectsToDelete = expiredUploads.reduce( + (all, expiredUpload) => { + all.push( + { + key: this.infoKey(expiredUpload.Key as string), + }, + { + key: this.partKey(expiredUpload.Key as string, true), + } + ) + return all + }, + [] as {key: string}[] + ) const deletions: Promise[] = [] @@ -764,7 +776,7 @@ export class S3Store extends DataStore { return deleted } - private async uniqueTmpFileName(template: string): Promise { + protected async uniqueTmpFileName(template: string): Promise { let tries = 0 const maxTries = 10 diff --git a/packages/s3-store/test/index.ts b/packages/s3-store/test/index.ts index 6abcf32c..014892f3 100644 --- a/packages/s3-store/test/index.ts +++ b/packages/s3-store/test/index.ts @@ -11,7 +11,16 @@ import {Upload} from '@tus/utils' const fixturesPath = path.resolve('../', '../', 'test', 'fixtures') const storePath = path.resolve('../', '../', 'test', 'output', 's3-store') -describe('S3DataStore', function () { +const s3ClientConfig = { + bucket: process.env.AWS_BUCKET as string, + credentials: { + accessKeyId: process.env.AWS_ACCESS_KEY_ID as string, + secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY as string, + }, + region: process.env.AWS_REGION, +} + +describe('S3DataStore', () => { before(function () { this.testFileSize = 960_244 this.testFileName = 'test.mp4' @@ -21,14 +30,7 @@ describe('S3DataStore', function () { beforeEach(function () { this.datastore = new S3Store({ partSize: 8 * 1024 * 1024, // Each uploaded part will have ~8MiB, - s3ClientConfig: { - bucket: process.env.AWS_BUCKET as string, - credentials: { - accessKeyId: process.env.AWS_ACCESS_KEY_ID as string, - secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY as string, - }, - region: process.env.AWS_REGION, - }, + s3ClientConfig, }) }) @@ -196,6 +198,86 @@ describe('S3DataStore', function () { assert.equal(offset, incompleteSize) }) + it('should use strictly sequential part numbers when uploading multiple chunks', async () => { + const store = new S3Store({ + partSize: 5 * 1024 * 1024, + maxConcurrentPartUploads: 1, + s3ClientConfig, + }) + + // @ts-expect-error private method + const uploadPartSpy = sinon.spy(store, 'uploadPart') + + const size = 15 * 1024 * 1024 + const upload = new Upload({ + id: shared.testId('increment-bug'), + size: size, + offset: 0, + }) + + await store.create(upload) + + // Write all 15 MB in a single call (S3Store will internally chunk to ~3 parts): + const offset = await store.write(Readable.from(Buffer.alloc(size)), upload.id, 0) + + assert.equal(offset, size) + + const finalUpload = await store.getUpload(upload.id) + assert.equal(finalUpload.offset, size, 'getUpload offset should match total size') + + const partNumbers = uploadPartSpy.getCalls().map((call) => call.args[2]) + + for (let i = 0; i < partNumbers.length; i++) { + if (i === 0) { + assert.equal(partNumbers[i], 1, 'First part number must be 1') + } else { + const prev = partNumbers[i - 1] + const curr = partNumbers[i] + assert.equal( + curr, + prev + 1, + `Part numbers should increment by 1. Found jump from ${prev} to ${curr}` + ) + } + } + }) + + it('should successfully upload a zero byte file', async function () { + const store = this.datastore as S3Store + const size = 0 + const upload = new Upload({ + id: shared.testId('zero-byte-file'), + size, + offset: 0, + }) + + await store.create(upload) + + const offset = await store.write( + Readable.from(Buffer.alloc(size)), + upload.id, + upload.offset + ) + assert.equal(offset, size, 'Write should return 0 offset') + + // Check .info file via getUpload + const finalUpload = await store.getUpload(upload.id) + assert.equal(finalUpload.offset, size, '.info file should show 0 offset') + + // @ts-expect-error private + const s3Client = store.client + try { + const headResult = await s3Client.getObject({ + Bucket: s3ClientConfig.bucket, + Key: upload.id, + }) + + assert.equal(headResult.ContentLength, size, 'File should exist in S3 with 0 bytes') + } catch (error) { + assert.fail(`Zero byte file was not uploaded to S3: ${error.message}`) + } + }) + shared.shouldHaveStoreMethods() shared.shouldCreateUploads() shared.shouldRemoveUploads() // Termination extension diff --git a/packages/s3-store/tsconfig.build.json b/packages/s3-store/tsconfig.build.json index a34ce5d0..d199726e 100644 --- a/packages/s3-store/tsconfig.build.json +++ b/packages/s3-store/tsconfig.build.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/tsconfig.json", - "references": [{"path": "../utils//tsconfig.build.json"}], + "references": [{ "path": "../utils//tsconfig.build.json" }], "extends": "../../tsconfig.base.json", "include": ["src"], "compilerOptions": { diff --git a/packages/s3-store/tsconfig.json b/packages/s3-store/tsconfig.json index 22f7865a..823c3da5 100644 --- a/packages/s3-store/tsconfig.json +++ b/packages/s3-store/tsconfig.json @@ -1,6 +1,9 @@ { "$schema": "https://json.schemastore.org/tsconfig.json", - "references": [{"path": "./tsconfig.build.json"}, {"path": "../../test/tsconfig.json"}], + "references": [ + { "path": "./tsconfig.build.json" }, + { "path": "../../test/tsconfig.json" } + ], "extends": "../../tsconfig.base.json", "exclude": ["src"], "compilerOptions": { diff --git a/packages/server/CHANGELOG.md b/packages/server/CHANGELOG.md index 93afd841..f1743289 100644 --- a/packages/server/CHANGELOG.md +++ b/packages/server/CHANGELOG.md @@ -1,5 +1,44 @@ # @tus/server +## 1.10.1 + +### Patch Changes + +- 42c6267: Consistent cancellation across streams and locks, fixing lock on file never being unlocked when the request ends prematurely. +- Updated dependencies [42c6267] + - @tus/utils@0.5.1 + +## 1.10.0 + +### Minor Changes + +- 8f19a53: Add ioredis as optional dependency + +### Patch Changes + +- f465a0f: Send Tus-Version header in OPTIONS +- Updated dependencies [8f19a53] + - @tus/utils@0.5.0 + +## 1.9.0 + +### Minor Changes + +- a3c3a99: add Content-Type and Content-Disposition headers on GetHandler.send response + +## 1.8.0 + +### Minor Changes + +- de28c6e: Publish source maps and declaration maps +- ca03351: - Add `allowedCredentials` option for the Access-Control-Allow-Credentials header + - Add `allowedOrigins` option for setting domains in Access-Control-Allow-Origin + +### Patch Changes + +- Updated dependencies [de28c6e] + - @tus/utils@0.4.0 + ## 1.7.0 ### Minor Changes diff --git a/packages/server/README.md b/packages/server/README.md index 491d72d1..a49d202a 100644 --- a/packages/server/README.md +++ b/packages/server/README.md @@ -69,6 +69,16 @@ Max file size (in bytes) allowed when uploading (`number` | (`(req, id: string | null) => Promise | number`)). When providing a function during the OPTIONS request the id will be `null`. +#### `options.allowedCredentials` + +Sets `Access-Control-Allow-Credentials` (`boolean`, default: `false`). + +#### `options.allowedOrigins` + +Trusted origins (`string[]`). + +Sends the client's origin back in `Access-Control-Allow-Origin` if it matches. + #### `options.postReceiveInterval` Interval in milliseconds for sending progress of an upload over @@ -332,7 +342,6 @@ import S3Store, {type MetadataValue} from '@tus/s3-store' import {createClient} from '@redis/client' const client = await createClient().connect() -const path = './uploads' const prefix = 'foo' // prefix for the key (foo${id}) new S3Store({ @@ -341,6 +350,22 @@ new S3Store({ }) ``` +#### `IoRedisKvStore` + +```ts +import { IoRedisKvStore } from '@tus/server'; +import S3Store, { type MetadataValue } from '@tus/s3-store'; +import Redis from 'ioredis'; + +const client = new Redis(); +const prefix = 'foo'; // prefix for the key (foo${id}) + +new S3Store({ + // ... + cache: new IoRedisKvStore(client, prefix), +}); +``` + ## Examples ### Example: integrate tus into Express diff --git a/packages/server/package.json b/packages/server/package.json index f5a634e4..6681fb27 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@tus/server", - "version": "1.7.0", + "version": "1.10.1", "description": "Tus resumable upload protocol in Node.js", "main": "dist/index.js", "homepage": "https://github.com/tus/tus-node-server#readme", @@ -11,16 +11,15 @@ "files": [ "README.md", "LICENSE", - "dist" + "dist", + "src" ], "scripts": { "build": "tsc --build", - "lint": "eslint .", - "format": "eslint --fix .", "test": "mocha --timeout 40000 --exit --extension ts --require ts-node/register" }, "dependencies": { - "@tus/utils": "^0.3.0", + "@tus/utils": "^0.5.1", "debug": "^4.3.4", "lodash.throttle": "^4.1.1" }, @@ -28,20 +27,19 @@ "@types/debug": "^4.1.12", "@types/lodash.throttle": "^4.1.9", "@types/mocha": "^10.0.6", - "@types/node": "^20.11.5", + "@types/node": "^22.10.1", "@types/sinon": "^17.0.3", "@types/supertest": "^2.0.16", - "eslint": "^8.57.0", - "eslint-config-custom": "^0.0.0", - "mocha": "^10.4.0", - "node-mocks-http": "^1.14.1", + "mocha": "^11.0.1", + "node-mocks-http": "^1.16.1", "should": "^13.2.3", - "sinon": "^17.0.1", + "sinon": "^18.0.0", "supertest": "^6.3.4", "ts-node": "^10.9.2" }, "optionalDependencies": { - "@redis/client": "^1.5.13" + "@redis/client": "^1.6.0", + "ioredis": "^5.4.1" }, "engines": { "node": ">=16" diff --git a/packages/server/src/handlers/BaseHandler.ts b/packages/server/src/handlers/BaseHandler.ts index 9973341d..c7df950f 100644 --- a/packages/server/src/handlers/BaseHandler.ts +++ b/packages/server/src/handlers/BaseHandler.ts @@ -1,11 +1,11 @@ import EventEmitter from 'node:events' import stream from 'node:stream/promises' -import {addAbortSignal, PassThrough} from 'node:stream' +import {PassThrough, Readable} from 'node:stream' import type http from 'node:http' import type {ServerOptions} from '../types' import type {DataStore, CancellationContext} from '@tus/utils' -import {ERRORS, Upload, StreamLimiter, EVENTS} from '@tus/utils' +import {ERRORS, type Upload, StreamLimiter, EVENTS} from '@tus/utils' import throttle from 'lodash.throttle' const reExtractFileID = /([^/]+)\/?$/ @@ -78,8 +78,8 @@ export class BaseHandler extends EventEmitter { } protected extractHostAndProto(req: http.IncomingMessage) { - let proto - let host + let proto: string | undefined + let host: string | undefined if (this.options.respectForwardedHeaders) { const forwarded = req.headers.forwarded as string | undefined @@ -96,7 +96,7 @@ export class BaseHandler extends EventEmitter { proto ??= forwardProto as string } - host ??= forwardHost + host ??= forwardHost as string } host ??= req.headers.host @@ -121,7 +121,7 @@ export class BaseHandler extends EventEmitter { const lock = locker.newLock(id) - await lock.lock(() => { + await lock.lock(context.signal, () => { context.cancel() }) @@ -129,11 +129,12 @@ export class BaseHandler extends EventEmitter { } protected writeToStore( - req: http.IncomingMessage, + data: Readable, upload: Upload, maxFileSize: number, context: CancellationContext ) { + // biome-ignore lint/suspicious/noAsyncPromiseExecutor: return new Promise(async (resolve, reject) => { // Abort early if the operation has been cancelled. if (context.signal.aborted) { @@ -144,16 +145,25 @@ export class BaseHandler extends EventEmitter { // Create a PassThrough stream as a proxy to manage the request stream. // This allows for aborting the write process without affecting the incoming request stream. const proxy = new PassThrough() - addAbortSignal(context.signal, proxy) + + // gracefully terminate the proxy stream when the request is aborted + const onAbort = () => { + data.unpipe(proxy) + + if (!proxy.closed) { + proxy.end() + } + } + context.signal.addEventListener('abort', onAbort, {once: true}) proxy.on('error', (err) => { - req.unpipe(proxy) + data.unpipe(proxy) reject(err.name === 'AbortError' ? ERRORS.ABORTED : err) }) const postReceive = throttle( (offset: number) => { - this.emit(EVENTS.POST_RECEIVE_V2, req, {...upload, offset}) + this.emit(EVENTS.POST_RECEIVE_V2, data, {...upload, offset}) }, this.options.postReceiveInterval, {leading: false} @@ -165,23 +175,18 @@ export class BaseHandler extends EventEmitter { postReceive(tempOffset) }) - req.on('error', () => { - if (!proxy.closed) { - // we end the stream gracefully here so that we can upload the remaining bytes to the store - // as an incompletePart - proxy.end() - } - }) - // Pipe the request stream through the proxy. We use the proxy instead of the request stream directly // to ensure that errors in the pipeline do not cause the request stream to be destroyed, // which would result in a socket hangup error for the client. stream - .pipeline(req.pipe(proxy), new StreamLimiter(maxFileSize), async (stream) => { + .pipeline(data.pipe(proxy), new StreamLimiter(maxFileSize), async (stream) => { return this.store.write(stream as StreamLimiter, upload.id, upload.offset) }) .then(resolve) .catch(reject) + .finally(() => { + context.signal.removeEventListener('abort', onAbort) + }) }) } @@ -206,7 +211,7 @@ export class BaseHandler extends EventEmitter { configuredMaxSize ??= await this.getConfiguredMaxSize(req, file.id) // Parse the Content-Length header from the request (default to 0 if not set). - const length = parseInt(req.headers['content-length'] || '0', 10) + const length = Number.parseInt(req.headers['content-length'] || '0', 10) const offset = file.offset const hasContentLengthSet = req.headers['content-length'] !== undefined @@ -224,9 +229,8 @@ export class BaseHandler extends EventEmitter { if (hasConfiguredMaxSizeSet) { return configuredMaxSize - offset - } else { - return Number.MAX_SAFE_INTEGER } + return Number.MAX_SAFE_INTEGER } // Check if the upload fits into the file's size when the size is not deferred. diff --git a/packages/server/src/handlers/DeleteHandler.ts b/packages/server/src/handlers/DeleteHandler.ts index cd92afba..9ae69352 100644 --- a/packages/server/src/handlers/DeleteHandler.ts +++ b/packages/server/src/handlers/DeleteHandler.ts @@ -1,5 +1,5 @@ import {BaseHandler} from './BaseHandler' -import {ERRORS, EVENTS, CancellationContext} from '@tus/utils' +import {ERRORS, EVENTS, type CancellationContext} from '@tus/utils' import type http from 'node:http' diff --git a/packages/server/src/handlers/GetHandler.ts b/packages/server/src/handlers/GetHandler.ts index 717294e2..326da26a 100644 --- a/packages/server/src/handlers/GetHandler.ts +++ b/packages/server/src/handlers/GetHandler.ts @@ -1,7 +1,7 @@ import stream from 'node:stream' import {BaseHandler} from './BaseHandler' -import {ERRORS} from '@tus/utils' +import {ERRORS, type Upload} from '@tus/utils' import type http from 'node:http' import type {RouteHandler} from '../types' @@ -9,6 +9,50 @@ import type {RouteHandler} from '../types' export class GetHandler extends BaseHandler { paths: Map = new Map() + /** + * reMimeType is a RegExp for check mime-type form compliance with RFC1341 + * for support mime-type and extra parameters, for example: + * + * ``` + * text/plain; charset=utf-8 + * ``` + * + * See: https://datatracker.ietf.org/doc/html/rfc1341 (Page 6) + */ + reMimeType = + // biome-ignore lint/suspicious/noControlCharactersInRegex: it's fine + /^(?:application|audio|example|font|haptics|image|message|model|multipart|text|video|x-(?:[0-9A-Za-z!#$%&'*+.^_`|~-]+))\/([0-9A-Za-z!#$%&'*+.^_`|~-]+)((?:[ ]*;[ ]*[0-9A-Za-z!#$%&'*+.^_`|~-]+=(?:[0-9A-Za-z!#$%&'*+.^_`|~-]+|"(?:[^"\\]|\.)*"))*)$/ + + /** + * mimeInlineBrowserWhitelist is a set containing MIME types which should be + * allowed to be rendered by browser inline, instead of being forced to be + * downloaded. For example, HTML or SVG files are not allowed, since they may + * contain malicious JavaScript. In a similar fashion PDF is not on this list + * as their parsers commonly contain vulnerabilities which can be exploited. + */ + mimeInlineBrowserWhitelist = new Set([ + 'text/plain', + + 'image/png', + 'image/jpeg', + 'image/gif', + 'image/bmp', + 'image/webp', + + 'audio/wave', + 'audio/wav', + 'audio/x-wav', + 'audio/x-pn-wav', + 'audio/webm', + 'audio/ogg', + + 'video/mp4', + 'video/webm', + 'video/ogg', + + 'application/ogg', + ]) + registerPath(path: string, handler: RouteHandler): void { this.paths.set(path, handler) } @@ -19,7 +63,7 @@ export class GetHandler extends BaseHandler { async send( req: http.IncomingMessage, res: http.ServerResponse - // TODO: always return void or a stream? + // biome-ignore lint/suspicious/noConfusingVoidType: it's fine ): Promise { if (this.paths.has(req.url as string)) { const handler = this.paths.get(req.url as string) as RouteHandler @@ -45,12 +89,71 @@ export class GetHandler extends BaseHandler { throw ERRORS.FILE_NOT_FOUND } + const {contentType, contentDisposition} = this.filterContentType(stats) + // @ts-expect-error exists if supported const file_stream = await this.store.read(id) - const headers = {'Content-Length': stats.offset} + const headers = { + 'Content-Length': stats.offset, + 'Content-Type': contentType, + 'Content-Disposition': contentDisposition, + } res.writeHead(200, headers) return stream.pipeline(file_stream, res, () => { // We have no need to handle streaming errors }) } + + /** + * filterContentType returns the values for the Content-Type and + * Content-Disposition headers for a given upload. These values should be used + * in responses for GET requests to ensure that only non-malicious file types + * are shown directly in the browser. It will extract the file name and type + * from the "filename" and "filetype". + * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition + */ + filterContentType(stats: Upload): { + contentType: string + contentDisposition: string + } { + let contentType: string + let contentDisposition: string + + const {filetype, filename} = stats.metadata ?? {} + + if (filetype && this.reMimeType.test(filetype)) { + // If the filetype from metadata is well formed, we forward use this + // for the Content-Type header. However, only whitelisted mime types + // will be allowed to be shown inline in the browser + contentType = filetype + + if (this.mimeInlineBrowserWhitelist.has(filetype)) { + contentDisposition = 'inline' + } else { + contentDisposition = 'attachment' + } + } else { + // If the filetype from the metadata is not well formed, we use a + // default type and force the browser to download the content + contentType = 'application/octet-stream' + contentDisposition = 'attachment' + } + + // Add a filename to Content-Disposition if one is available in the metadata + if (filename) { + contentDisposition += `; filename=${this.quote(filename)}` + } + + return { + contentType, + contentDisposition, + } + } + + /** + * Convert string to quoted string literals + */ + quote(value: string) { + return `"${value.replace(/"/g, '\\"')}"` + } } diff --git a/packages/server/src/handlers/HeadHandler.ts b/packages/server/src/handlers/HeadHandler.ts index 2e7ae7cc..664d4ee7 100644 --- a/packages/server/src/handlers/HeadHandler.ts +++ b/packages/server/src/handlers/HeadHandler.ts @@ -1,6 +1,6 @@ import {BaseHandler} from './BaseHandler' -import {ERRORS, Metadata, Upload, CancellationContext} from '@tus/utils' +import {ERRORS, Metadata, type Upload, type CancellationContext} from '@tus/utils' import type http from 'node:http' diff --git a/packages/server/src/handlers/OptionsHandler.ts b/packages/server/src/handlers/OptionsHandler.ts index 9bb19664..15b7d358 100644 --- a/packages/server/src/handlers/OptionsHandler.ts +++ b/packages/server/src/handlers/OptionsHandler.ts @@ -9,18 +9,18 @@ export class OptionsHandler extends BaseHandler { async send(req: http.IncomingMessage, res: http.ServerResponse) { const maxSize = await this.getConfiguredMaxSize(req, null) + res.setHeader('Tus-Version', '1.0.0') + if (this.store.extensions.length > 0) { + res.setHeader('Tus-Extension', this.store.extensions.join(',')) + } if (maxSize) { res.setHeader('Tus-Max-Size', maxSize) } const allowedHeaders = [...HEADERS, ...(this.options.allowedHeaders ?? [])] - res.setHeader('Access-Control-Allow-Methods', ALLOWED_METHODS) res.setHeader('Access-Control-Allow-Headers', allowedHeaders.join(', ')) res.setHeader('Access-Control-Max-Age', MAX_AGE) - if (this.store.extensions.length > 0) { - res.setHeader('Tus-Extension', this.store.extensions.join(',')) - } return this.write(res, 204) } diff --git a/packages/server/src/handlers/PatchHandler.ts b/packages/server/src/handlers/PatchHandler.ts index acb8a6be..554b507c 100644 --- a/packages/server/src/handlers/PatchHandler.ts +++ b/packages/server/src/handlers/PatchHandler.ts @@ -3,7 +3,7 @@ import debug from 'debug' import {BaseHandler} from './BaseHandler' import type http from 'node:http' -import {ERRORS, EVENTS, CancellationContext, Upload} from '@tus/utils' +import {ERRORS, EVENTS, type CancellationContext, type Upload} from '@tus/utils' const log = debug('tus-node-server:handlers:patch') diff --git a/packages/server/src/handlers/PostHandler.ts b/packages/server/src/handlers/PostHandler.ts index f6cb47ed..1140c52b 100644 --- a/packages/server/src/handlers/PostHandler.ts +++ b/packages/server/src/handlers/PostHandler.ts @@ -7,12 +7,12 @@ import { Metadata, EVENTS, ERRORS, - DataStore, - CancellationContext, + type DataStore, + type CancellationContext, } from '@tus/utils' import {validateHeader} from '../validators/HeaderValidator' -import http from 'node:http' +import type http from 'node:http' import type {ServerOptions, WithRequired} from '../types' const log = debug('tus-node-server:handlers:post') @@ -60,7 +60,7 @@ export class PostHandler extends BaseHandler { throw ERRORS.INVALID_LENGTH } - let metadata + let metadata: ReturnType<(typeof Metadata)['parse']> | undefined if ('upload-metadata' in req.headers) { try { metadata = Metadata.parse(upload_metadata) @@ -69,7 +69,7 @@ export class PostHandler extends BaseHandler { } } - let id + let id: string try { id = await this.options.namingFunction(req, metadata) } catch (error) { @@ -208,7 +208,7 @@ export class PostHandler extends BaseHandler { responseData.status === 201 || (responseData.status >= 300 && responseData.status < 400) ) { - responseData.headers['Location'] = url + responseData.headers.Location = url } const writtenRes = this.write( diff --git a/packages/server/src/lockers/MemoryLocker.ts b/packages/server/src/lockers/MemoryLocker.ts index da70777c..393e0a89 100644 --- a/packages/server/src/lockers/MemoryLocker.ts +++ b/packages/server/src/lockers/MemoryLocker.ts @@ -1,4 +1,4 @@ -import {ERRORS, Lock, Locker, RequestRelease} from '@tus/utils' +import {ERRORS, type Lock, type Locker, type RequestRelease} from '@tus/utils' /** * MemoryLocker is an implementation of the Locker interface that manages locks in memory. @@ -49,11 +49,14 @@ class MemoryLock implements Lock { private timeout: number = 1000 * 30 ) {} - async lock(requestRelease: RequestRelease): Promise { + async lock(stopSignal: AbortSignal, requestRelease: RequestRelease): Promise { const abortController = new AbortController() + + const abortSignal = AbortSignal.any([stopSignal, abortController.signal]) + const lock = await Promise.race([ - this.waitTimeout(abortController.signal), - this.acquireLock(this.id, requestRelease, abortController.signal), + this.waitTimeout(abortSignal), + this.acquireLock(this.id, requestRelease, abortSignal), ]) abortController.abort() @@ -68,12 +71,12 @@ class MemoryLock implements Lock { requestRelease: RequestRelease, signal: AbortSignal ): Promise { + const lock = this.locker.locks.get(id) + if (signal.aborted) { - return false + return typeof lock !== 'undefined' } - const lock = this.locker.locks.get(id) - if (!lock) { const lock = { requestRelease, diff --git a/packages/server/src/server.ts b/packages/server/src/server.ts index 51867a27..cc56be5b 100644 --- a/packages/server/src/server.ts +++ b/packages/server/src/server.ts @@ -69,7 +69,7 @@ export declare interface Server { const log = debug('tus-node-server') -// eslint-disable-next-line no-redeclare +// biome-ignore lint/suspicious/noUnsafeDeclarationMerging: it's fine export class Server extends EventEmitter { datastore: DataStore handlers: Handlers @@ -147,10 +147,15 @@ export class Server extends EventEmitter { async handle( req: http.IncomingMessage, res: http.ServerResponse - // TODO: this return type does not make sense + // biome-ignore lint/suspicious/noConfusingVoidType: it's fine ): Promise { const context = this.createContext(req) + // Once the request is closed we abort the context to clean up underline resources + req.on('close', () => { + context.abort() + }) + log(`[TusServer] handle: ${req.method} ${req.url}`) // Allow overriding the HTTP method. The reason for this is // that some libraries/environments to not support PATCH and @@ -219,9 +224,11 @@ export class Server extends EventEmitter { } // Enable CORS + res.setHeader('Access-Control-Allow-Origin', this.getCorsOrigin(req)) res.setHeader('Access-Control-Expose-Headers', EXPOSED_HEADERS) - if (req.headers.origin) { - res.setHeader('Access-Control-Allow-Origin', req.headers.origin) + + if (this.options.allowedCredentials === true) { + res.setHeader('Access-Control-Allow-Credentials', 'true') } // Invoke the handler for the method requested @@ -233,6 +240,23 @@ export class Server extends EventEmitter { return this.write(context, req, res, 404, 'Not found\n') } + private getCorsOrigin(req: http.IncomingMessage): string { + const origin = req.headers.origin + const isOriginAllowed = + this.options.allowedOrigins?.some((allowedOrigin) => allowedOrigin === origin) ?? + true + + if (origin && isOriginAllowed) { + return origin + } + + if (this.options.allowedOrigins && this.options.allowedOrigins.length > 0) { + return this.options.allowedOrigins[0] + } + + return '*' + } + write( context: CancellationContext, req: http.IncomingMessage, @@ -256,7 +280,7 @@ export class Server extends EventEmitter { // that is no longer needed, thereby saving resources. // @ts-expect-error not explicitly typed but possible - headers['Connection'] = 'close' + headers.Connection = 'close' // An event listener is added to the response ('res') for the 'finish' event. // The 'finish' event is triggered when the response has been sent to the client. @@ -270,10 +294,21 @@ export class Server extends EventEmitter { res.writeHead(status, headers) res.write(body) + + // Abort the context once the response is sent. + // Useful for clean-up when the server uses keep-alive + if (!isAborted) { + res.on('finish', () => { + if (!req.closed) { + context.abort() + } + }) + } + return res.end() } - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: todo listen(...args: any[]): http.Server { return http.createServer(this.handle.bind(this)).listen(...args) } diff --git a/packages/server/src/types.ts b/packages/server/src/types.ts index 405408f5..b1a816ff 100644 --- a/packages/server/src/types.ts +++ b/packages/server/src/types.ts @@ -34,6 +34,16 @@ export type ServerOptions = { */ allowedHeaders?: string[] + /** + * Set `Access-Control-Allow-Credentials` to true or false (the default) + */ + allowedCredentials?: boolean + + /** + * Add trusted origins to `Access-Control-Allow-Origin`. + */ + allowedOrigins?: string[] + /** * Interval in milliseconds for sending progress of an upload over `EVENTS.POST_RECEIVE_V2` */ @@ -53,7 +63,10 @@ export type ServerOptions = { * Control how the Upload-ID is extracted from the request. * @param req - The incoming HTTP request. */ - getFileIdFromRequest?: (req: http.IncomingMessage, lastPath?: string) => string | void + getFileIdFromRequest?: ( + req: http.IncomingMessage, + lastPath?: string + ) => string | undefined /** * Control how you want to name files. @@ -154,9 +167,9 @@ export type ServerOptions = { res: http.ServerResponse, err: Error | {status_code: number; body: string} ) => - | Promise<{status_code: number; body: string} | void> + | Promise<{status_code: number; body: string} | undefined> | {status_code: number; body: string} - | void + | undefined } export type RouteHandler = (req: http.IncomingMessage, res: http.ServerResponse) => void diff --git a/packages/server/src/validators/HeaderValidator.ts b/packages/server/src/validators/HeaderValidator.ts index ed0f5af5..6dd627fb 100644 --- a/packages/server/src/validators/HeaderValidator.ts +++ b/packages/server/src/validators/HeaderValidator.ts @@ -7,7 +7,7 @@ export const validators = new Map([ // The Upload-Offset request and response header indicates a byte offset within a resource. // The value MUST be a non-negative integer. 'upload-offset', - function (value) { + (value) => { const n = Number(value) return Number.isInteger(n) && String(n) === value && n >= 0 }, @@ -16,7 +16,7 @@ export const validators = new Map([ // The Upload-Length request and response header indicates the size of the entire upload in bytes. // The value MUST be a non-negative integer. 'upload-length', - function (value) { + (value) => { const n = Number(value) return Number.isInteger(n) && String(n) === value && n >= 0 }, @@ -26,9 +26,7 @@ export const validators = new Map([ // is not known currently and will be transferred later. // Its value MUST be 1. If the length of an upload is not deferred, this header MUST be omitted. 'upload-defer-length', - function (value) { - return value === '1' - }, + (value) => value === '1', ], [ 'upload-metadata', @@ -37,7 +35,7 @@ export const validators = new Map([ // 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. - function (value) { + (value) => { try { Metadata.parse(value) return true @@ -48,7 +46,7 @@ export const validators = new Map([ ], [ 'x-forwarded-proto', - function (value) { + (value) => { if (value === 'http' || value === 'https') { return true } @@ -59,7 +57,7 @@ export const validators = new Map([ // The Tus-Version response header MUST be a comma-separated list of protocol versions supported by the Server. // The list MUST be sorted by Server's preference where the first one is the most preferred one. 'tus-version', - function (value) { + (value) => { // @ts-expect-error we can compare a literal return TUS_VERSION.includes(value) }, @@ -71,16 +69,9 @@ export const validators = new Map([ // it MUST respond with the 412 Precondition Failed status and MUST include the Tus-Version header into the response. // In addition, the Server MUST NOT process the request. 'tus-resumable', - function (value) { - return value === TUS_RESUMABLE - }, - ], - [ - 'content-type', - function (value) { - return value === 'application/offset+octet-stream' - }, + (value) => value === TUS_RESUMABLE, ], + ['content-type', (value) => value === 'application/offset+octet-stream'], [ // The Upload-Concat request and response header MUST be set in both partial and final upload creation requests. // It indicates whether the upload is either a partial or final upload. @@ -89,7 +80,7 @@ export const validators = new Map([ // of partial upload URLs that will be concatenated. // The partial uploads URLs MAY be absolute or relative and MUST NOT contain spaces as defined in RFC 3986. 'upload-concat', - function (value) { + (value) => { if (!value) return false const valid_partial = value === 'partial' const valid_final = value.startsWith('final;') diff --git a/packages/server/test/BaseHandler.test.ts b/packages/server/test/BaseHandler.test.ts index 291650a7..fccd612b 100644 --- a/packages/server/test/BaseHandler.test.ts +++ b/packages/server/test/BaseHandler.test.ts @@ -1,5 +1,5 @@ import {strict as assert} from 'node:assert' -import http from 'node:http' +import type http from 'node:http' import httpMocks from 'node-mocks-http' @@ -87,7 +87,7 @@ describe('BaseHandler', () => { }) const id = '123' const url = handler.generateUrl(req, id) - assert.equal(url, `http://localhost/path/123?customParam=1`) + assert.equal(url, 'http://localhost/path/123?customParam=1') }) it('should allow extracting the request id with a custom function', () => { @@ -95,7 +95,7 @@ describe('BaseHandler', () => { path: '/path', locker: new MemoryLocker(), getFileIdFromRequest: (req: http.IncomingMessage) => { - return req.url?.split('/').pop() + '-custom' + return `${req.url?.split('/').pop()}-custom` }, }) @@ -103,6 +103,6 @@ describe('BaseHandler', () => { url: '/upload/1234', }) const url = handler.getFileIdFromRequest(req) - assert.equal(url, `1234-custom`) + assert.equal(url, '1234-custom') }) }) diff --git a/packages/server/test/DeleteHandler.test.ts b/packages/server/test/DeleteHandler.test.ts index c6d024ad..a54262ad 100644 --- a/packages/server/test/DeleteHandler.test.ts +++ b/packages/server/test/DeleteHandler.test.ts @@ -6,7 +6,7 @@ import type http from 'node:http' import sinon from 'sinon' import httpMocks from 'node-mocks-http' -import {ERRORS, EVENTS, DataStore, CancellationContext} from '@tus/utils' +import {ERRORS, EVENTS, DataStore, type CancellationContext} from '@tus/utils' import {DeleteHandler} from '../src/handlers/DeleteHandler' import {MemoryLocker} from '../src' diff --git a/packages/server/test/GetHandler.test.ts b/packages/server/test/GetHandler.test.ts index cf9811c9..88282e16 100644 --- a/packages/server/test/GetHandler.test.ts +++ b/packages/server/test/GetHandler.test.ts @@ -3,7 +3,7 @@ import 'should' import {strict as assert} from 'node:assert' import fs from 'node:fs' import stream from 'node:stream' -import http from 'node:http' +import type http from 'node:http' import sinon from 'sinon' import httpMocks from 'node-mocks-http' @@ -39,7 +39,7 @@ describe('GetHandler', () => { const store = sinon.createStubInstance(FileStore) const handler = new GetHandler(store, {path, locker: new MemoryLocker()}) const spy_getFileIdFromRequest = sinon.spy(handler, 'getFileIdFromRequest') - req.url = `/not_a_valid_file_path` + req.url = '/not_a_valid_file_path' await assert.rejects(() => handler.send(req, res), {status_code: 404}) assert.equal(spy_getFileIdFromRequest.callCount, 1) }) @@ -108,19 +108,116 @@ describe('GetHandler', () => { assert.equal(res.statusCode, 200) // TODO: this is the get handler but Content-Length is only send in 204 OPTIONS requests? // assert.equal(res.getHeader('Content-Length'), size) + + assert.equal(res.getHeader('Content-Type'), 'application/octet-stream') + assert.equal(res.getHeader('Content-Disposition'), 'attachment') + assert.equal(store.getUpload.calledOnceWith(fileId), true) assert.equal(store.read.calledOnceWith(fileId), true) }) }) + describe('filterContentType', () => { + it('should return default headers value without metadata', () => { + const fakeStore = sinon.stub(new DataStore()) + const handler = new GetHandler(fakeStore, serverOptions) + const size = 512 + const upload = new Upload({id: '1234', offset: size, size}) + + const res = handler.filterContentType(upload) + + assert.deepEqual(res, { + contentType: 'application/octet-stream', + contentDisposition: 'attachment', + }) + }) + + it('should return headers allow render in browser when filetype is in whitelist', () => { + const fakeStore = sinon.stub(new DataStore()) + const handler = new GetHandler(fakeStore, serverOptions) + const size = 512 + const upload = new Upload({ + id: '1234', + offset: size, + size, + metadata: {filetype: 'image/png', filename: 'pet.png'}, + }) + + const res = handler.filterContentType(upload) + + assert.deepEqual(res, { + contentType: 'image/png', + contentDisposition: 'inline; filename="pet.png"', + }) + }) + + it('should return headers force download when filetype is not in whitelist', () => { + const fakeStore = sinon.stub(new DataStore()) + const handler = new GetHandler(fakeStore, serverOptions) + const size = 512 + const upload = new Upload({ + id: '1234', + offset: size, + size, + metadata: {filetype: 'application/zip', filename: 'pets.zip'}, + }) + + const res = handler.filterContentType(upload) + + assert.deepEqual(res, { + contentType: 'application/zip', + contentDisposition: 'attachment; filename="pets.zip"', + }) + }) + + it('should return headers when filetype is not a valid form', () => { + const fakeStore = sinon.stub(new DataStore()) + const handler = new GetHandler(fakeStore, serverOptions) + const size = 512 + const upload = new Upload({ + id: '1234', + offset: size, + size, + metadata: {filetype: 'image_png', filename: 'pet.png'}, + }) + + const res = handler.filterContentType(upload) + + assert.deepEqual(res, { + contentType: 'application/octet-stream', + contentDisposition: 'attachment; filename="pet.png"', + }) + }) + }) + + describe('quote', () => { + it('should return simple quoted string', () => { + const fakeStore = sinon.stub(new DataStore()) + const handler = new GetHandler(fakeStore, serverOptions) + + const res = handler.quote('pet.png') + + assert.equal(res, '"pet.png"') + }) + + it('should return quoted string when include quotes', () => { + const fakeStore = sinon.stub(new DataStore()) + const handler = new GetHandler(fakeStore, serverOptions) + + const res = handler.quote('"pet.png"') + + assert.equal(res, '"\\"pet.png\\""') + }) + }) + describe('registerPath()', () => { it('should call registered path handler', async () => { const fakeStore = sinon.stub(new DataStore()) const handler = new GetHandler(fakeStore, serverOptions) - const customPath1 = `/path1` + const customPath1 = '/path1' const pathHandler1 = sinon.spy() handler.registerPath(customPath1, pathHandler1) - const customPath2 = `/path2` + const customPath2 = '/path2' const pathHandler2 = sinon.spy() handler.registerPath(customPath2, pathHandler2) req.url = `${customPath1}` @@ -137,7 +234,7 @@ describe('GetHandler', () => { const fakeStore = sinon.stub(new DataStore()) const handler = new GetHandler(fakeStore, serverOptions) const spy_getFileIdFromRequest = sinon.spy(handler, 'getFileIdFromRequest') - const customPath = `/path` + const customPath = '/path' handler.registerPath(customPath, () => {}) req.url = `${customPath}` await handler.send(req, res) diff --git a/packages/server/test/HeadHandler.test.ts b/packages/server/test/HeadHandler.test.ts index 5a33340f..3bb179fd 100644 --- a/packages/server/test/HeadHandler.test.ts +++ b/packages/server/test/HeadHandler.test.ts @@ -1,10 +1,10 @@ import {strict as assert} from 'node:assert' -import http from 'node:http' +import type http from 'node:http' import sinon from 'sinon' import httpMocks from 'node-mocks-http' -import {ERRORS, DataStore, Upload, CancellationContext} from '@tus/utils' +import {ERRORS, DataStore, Upload, type CancellationContext} from '@tus/utils' import {HeadHandler} from '../src/handlers/HeadHandler' import {MemoryLocker} from '../src' diff --git a/packages/server/test/Locker.test.ts b/packages/server/test/Locker.test.ts index 0f377025..bef07f0a 100644 --- a/packages/server/test/Locker.test.ts +++ b/packages/server/test/Locker.test.ts @@ -6,6 +6,7 @@ describe('MemoryLocker', () => { it('will acquire a lock by notifying another to release it', async () => { const locker = new MemoryLocker() const lockId = 'upload-id-1' + const abortController = new AbortController() const cancel = sinon.spy() const cancel2 = sinon.spy() @@ -13,12 +14,12 @@ describe('MemoryLocker', () => { const lock1 = locker.newLock(lockId) const lock2 = locker.newLock(lockId) - await lock1.lock(async () => { + await lock1.lock(abortController.signal, async () => { await lock1.unlock() cancel() }) - await lock2.lock(async () => { + await lock2.lock(abortController.signal, async () => { cancel2() }) @@ -32,19 +33,21 @@ describe('MemoryLocker', () => { const locker = new MemoryLocker({ acquireLockTimeout: 500, }) + const abortController = new AbortController() + const lockId = 'upload-id-1' const lock = locker.newLock(lockId) const cancel = sinon.spy() - await lock.lock(async () => { + await lock.lock(abortController.signal, async () => { cancel() // We note that the function has been called, but do not // release the lock }) try { - await lock.lock(async () => { + await lock.lock(abortController.signal, async () => { throw new Error('panic should not be called') }) } catch (e) { @@ -57,18 +60,20 @@ describe('MemoryLocker', () => { it('request lock and unlock', async () => { const locker = new MemoryLocker() const lockId = 'upload-id-1' + const abortController = new AbortController() + const lock = locker.newLock(lockId) const lock2 = locker.newLock(lockId) const cancel = sinon.spy() - await lock.lock(() => { + await lock.lock(abortController.signal, () => { cancel() setTimeout(async () => { await lock.unlock() }, 50) }) - await lock2.lock(() => { + await lock2.lock(abortController.signal, () => { throw new Error('should not be called') }) @@ -79,4 +84,38 @@ describe('MemoryLocker', () => { `request released called more times than expected - ${cancel.callCount}` ) }) + + it('will stop trying to acquire the lock if the abort signal is aborted', async () => { + const locker = new MemoryLocker() + const lockId = 'upload-id-1' + const abortController = new AbortController() + + const cancel = sinon.spy() + const cancel2 = sinon.spy() + + const lock1 = locker.newLock(lockId) + const lock2 = locker.newLock(lockId) + + await lock1.lock(abortController.signal, async () => { + // do not unlock when requested + cancel() + }) + + // Abort signal is aborted after lock2 tries to acquire the lock + setTimeout(() => { + abortController.abort() + }, 100) + + try { + await lock2.lock(abortController.signal, async () => { + cancel2() + }) + assert(false, 'lock2 should not have been acquired') + } catch (e) { + assert(e === ERRORS.ERR_LOCK_TIMEOUT, `error returned is not correct ${e}`) + } + + assert(cancel.callCount > 1, `calls count dont match ${cancel.callCount} !== 1`) + assert(cancel2.callCount === 0, `calls count dont match ${cancel.callCount} !== 1`) + }) }) diff --git a/packages/server/test/OptionsHandler.test.ts b/packages/server/test/OptionsHandler.test.ts index 5a161057..7fdae268 100644 --- a/packages/server/test/OptionsHandler.test.ts +++ b/packages/server/test/OptionsHandler.test.ts @@ -1,16 +1,20 @@ import 'should' import {strict as assert} from 'node:assert' -import http from 'node:http' +import type http from 'node:http' import httpMocks from 'node-mocks-http' import {OptionsHandler} from '../src/handlers/OptionsHandler' import {DataStore, ALLOWED_METHODS, ALLOWED_HEADERS, MAX_AGE} from '@tus/utils' -import {MemoryLocker} from '../src' +import {MemoryLocker, type ServerOptions} from '../src' describe('OptionsHandler', () => { - const options = {path: '/test/output', locker: new MemoryLocker()} + const options: ServerOptions = { + path: '/test/output', + locker: new MemoryLocker(), + maxSize: 1024, + } const store = new DataStore() const handler = new OptionsHandler(store, options) @@ -27,6 +31,8 @@ describe('OptionsHandler', () => { 'Access-Control-Allow-Methods': ALLOWED_METHODS, 'Access-Control-Allow-Headers': ALLOWED_HEADERS, 'Access-Control-Max-Age': MAX_AGE, + 'Tus-Version': '1.0.0', + 'Tus-Max-Size': 1024, } await handler.send(req, res) // eslint-disable-next-line guard-for-in diff --git a/packages/server/test/PatchHandler.test.ts b/packages/server/test/PatchHandler.test.ts index e3a41f34..a17fe804 100644 --- a/packages/server/test/PatchHandler.test.ts +++ b/packages/server/test/PatchHandler.test.ts @@ -1,18 +1,18 @@ import 'should' import {strict as assert} from 'node:assert' -import http from 'node:http' +import type http from 'node:http' import sinon from 'sinon' import httpMocks from 'node-mocks-http' import {PatchHandler} from '../src/handlers/PatchHandler' -import {EVENTS, Upload, DataStore, CancellationContext} from '@tus/utils' +import {EVENTS, Upload, DataStore, type CancellationContext} from '@tus/utils' import {EventEmitter} from 'node:events' import {addPipableStreamBody} from './utils' import {MemoryLocker} from '../src' import streamP from 'node:stream/promises' -import stream from 'node:stream' +import stream, {PassThrough} from 'node:stream' describe('PatchHandler', () => { const path = '/test/output' @@ -51,7 +51,7 @@ describe('PatchHandler', () => { return assert.rejects(() => handler.send(req, res, context), {status_code: 403}) }) - it('should call onUploadFinished hook', async function () { + it('should call onUploadFinished hook', async () => { const spy = sinon.stub().resolvesArg(1) const handler = new PatchHandler(store, { path: '/test/output', @@ -245,4 +245,69 @@ describe('PatchHandler', () => { assert.equal(context.signal.aborted, true) } }) + + it('should gracefully terminate request stream when context is cancelled', async () => { + handler = new PatchHandler(store, {path, locker: new MemoryLocker()}) + + const bodyStream = new PassThrough() // 20kb buffer + const req = addPipableStreamBody( + httpMocks.createRequest({ + method: 'PATCH', + url: `${path}/1234`, + body: bodyStream, + }) + ) + + const abortController = new AbortController() + context = { + cancel: () => abortController.abort(), + abort: () => abortController.abort(), + signal: abortController.signal, + } + + const res = httpMocks.createResponse({req}) + req.headers = { + 'upload-offset': '0', + 'content-type': 'application/offset+octet-stream', + } + req.url = `${path}/file` + + let accumulatedBuffer: Buffer = Buffer.alloc(0) + + store.getUpload.resolves(new Upload({id: '1234', offset: 0})) + store.write.callsFake(async (readable: http.IncomingMessage | stream.Readable) => { + const writeStream = new stream.PassThrough() + const chunks: Buffer[] = [] + + writeStream.on('data', (chunk) => { + chunks.push(chunk) // Accumulate chunks in the outer buffer + }) + + await streamP.pipeline(readable, writeStream) + + accumulatedBuffer = Buffer.concat([accumulatedBuffer, ...chunks]) + + return writeStream.readableLength + }) + store.declareUploadLength.resolves() + + await new Promise((resolve, reject) => { + handler.send(req, res, context).then(resolve).catch(reject) + + // sends the first 20kb + bodyStream.write(Buffer.alloc(1024 * 20)) + + // write 15kb + bodyStream.write(Buffer.alloc(1024 * 15)) + + // simulate that the request was cancelled + setTimeout(() => { + context.abort() + }, 200) + }) + + // We expect that all the data was written to the store, 35kb + assert.equal(accumulatedBuffer.byteLength, 35 * 1024) + bodyStream.end() + }) }) diff --git a/packages/server/test/PostHandler.test.ts b/packages/server/test/PostHandler.test.ts index b4790de8..be6bca1d 100644 --- a/packages/server/test/PostHandler.test.ts +++ b/packages/server/test/PostHandler.test.ts @@ -2,12 +2,12 @@ import 'should' import {strict as assert} from 'node:assert' -import http from 'node:http' +import type http from 'node:http' import httpMocks from 'node-mocks-http' import sinon from 'sinon' -import {EVENTS, Upload, DataStore, CancellationContext} from '@tus/utils' +import {EVENTS, Upload, DataStore, type CancellationContext} from '@tus/utils' import {PostHandler} from '../src/handlers/PostHandler' import {addPipableStreamBody} from './utils' import {MemoryLocker} from '../src' @@ -55,19 +55,25 @@ describe('PostHandler', () => { const handler = new PostHandler(fake_store, SERVER_OPTIONS) req.headers = {} - return assert.rejects(() => handler.send(req, res, context), {status_code: 400}) + return assert.rejects(() => handler.send(req, res, context), { + status_code: 400, + }) }) it('must 400 if the Upload-Length and Upload-Defer-Length headers are both present', async () => { const handler = new PostHandler(fake_store, SERVER_OPTIONS) req.headers = {'upload-length': '512', 'upload-defer-length': '1'} - return assert.rejects(() => handler.send(req, res, context), {status_code: 400}) + return assert.rejects(() => handler.send(req, res, context), { + status_code: 400, + }) }) it("must 501 if the 'concatenation' extension is not supported", async () => { const handler = new PostHandler(fake_store, SERVER_OPTIONS) req.headers = {'upload-concat': 'partial'} - return assert.rejects(() => handler.send(req, res, context), {status_code: 501}) + return assert.rejects(() => handler.send(req, res, context), { + status_code: 501, + }) }) it('should send error when naming function throws', async () => { @@ -81,7 +87,9 @@ describe('PostHandler', () => { }) req.headers = {'upload-length': '1000'} - return assert.rejects(() => handler.send(req, res, context), {status_code: 400}) + return assert.rejects(() => handler.send(req, res, context), { + status_code: 400, + }) }) it('should call custom namingFunction', async () => { @@ -119,7 +127,9 @@ describe('PostHandler', () => { const handler = new PostHandler(fake_store, SERVER_OPTIONS) req.headers = {'upload-length': '1000'} - return assert.rejects(() => handler.send(req, res, context), {status_code: 500}) + return assert.rejects(() => handler.send(req, res, context), { + status_code: 500, + }) }) }) @@ -284,7 +294,7 @@ describe('PostHandler', () => { handler.send(req, res, context) }) - it('should call onUploadCreate hook', async function () { + it('should call onUploadCreate hook', async () => { const store = sinon.createStubInstance(DataStore) const spy = sinon.stub().resolvesArg(1) const handler = new PostHandler(store, { @@ -306,7 +316,7 @@ describe('PostHandler', () => { assert.equal(upload.size, 1024) }) - it('should call onUploadFinish hook when creation-with-upload is used', async function () { + it('should call onUploadFinish hook when creation-with-upload is used', async () => { const store = sinon.createStubInstance(DataStore) const spy = sinon.stub().resolvesArg(1) const handler = new PostHandler(store, { @@ -330,7 +340,7 @@ describe('PostHandler', () => { assert.equal(upload.size, 1024) }) - it('should call onUploadFinish hook for empty file without content-type', async function () { + it('should call onUploadFinish hook for empty file without content-type', async () => { const store = sinon.createStubInstance(DataStore) const spy = sinon.stub().resolvesArg(1) const handler = new PostHandler(store, { @@ -348,7 +358,7 @@ describe('PostHandler', () => { assert.equal(upload.size, 0) }) - it('does not set Location header if onUploadFinish hook returned a not eligible status code', async function () { + it('does not set Location header if onUploadFinish hook returned a not eligible status code', async () => { const store = sinon.createStubInstance(DataStore) const handler = new PostHandler(store, { path: '/test/output', diff --git a/packages/server/test/Server.test.ts b/packages/server/test/Server.test.ts index 2b77f126..c29da467 100644 --- a/packages/server/test/Server.test.ts +++ b/packages/server/test/Server.test.ts @@ -165,6 +165,19 @@ describe('Server', () => { }) }) + it('OPTIONS should return returns custom headers in Access-Control-Allow-Credentials', (done) => { + server.options.allowedCredentials = true + + request(listener) + .options('/') + .expect(204, '', (err, res) => { + res.headers.should.have.property('access-control-allow-credentials') + res.headers['access-control-allow-credentials'].should.containEql('true') + server.options.allowedCredentials = undefined + done(err) + }) + }) + it('HEAD should 404 non files', (done) => { request(listener) .head('/') @@ -252,8 +265,37 @@ describe('Server', () => { done() }) - it('should allow overriding the HTTP method', async () => { + it('should allow overriding the HTTP origin', async () => { + const origin = 'vimeo.com' + const req = httpMocks.createRequest({ + headers: {origin}, + method: 'OPTIONS', + url: '/', + }) + // @ts-expect-error todo + const res = new http.ServerResponse({method: 'OPTIONS'}) + await server.handle(req, res) + assert.equal(res.hasHeader('Access-Control-Allow-Origin'), true) + }) + + it('should allow overriding the HTTP origin only if match allowedOrigins', async () => { + const origin = 'vimeo.com' + server.options.allowedOrigins = ['vimeo.com'] + const req = httpMocks.createRequest({ + headers: {origin}, + method: 'OPTIONS', + url: '/', + }) + // @ts-expect-error todo + const res = new http.ServerResponse({method: 'OPTIONS'}) + await server.handle(req, res) + assert.equal(res.hasHeader('Access-Control-Allow-Origin'), true) + assert.equal(res.getHeader('Access-Control-Allow-Origin'), 'vimeo.com') + }) + + it('should allow overriding the HTTP origin only if match allowedOrigins with multiple allowed domains', async () => { const origin = 'vimeo.com' + server.options.allowedOrigins = ['google.com', 'vimeo.com'] const req = httpMocks.createRequest({ headers: {origin}, method: 'OPTIONS', @@ -263,6 +305,35 @@ describe('Server', () => { const res = new http.ServerResponse({method: 'OPTIONS'}) await server.handle(req, res) assert.equal(res.hasHeader('Access-Control-Allow-Origin'), true) + assert.equal(res.getHeader('Access-Control-Allow-Origin'), 'vimeo.com') + }) + + it(`should now allow overriding the HTTP origin if doesn't match allowedOrigins`, async () => { + const origin = 'vimeo.com' + server.options.allowedOrigins = ['google.com'] + const req = httpMocks.createRequest({ + headers: {origin}, + method: 'OPTIONS', + url: '/', + }) + // @ts-expect-error todo + const res = new http.ServerResponse({method: 'OPTIONS'}) + await server.handle(req, res) + assert.equal(res.hasHeader('Access-Control-Allow-Origin'), true) + assert.equal(res.getHeader('Access-Control-Allow-Origin'), 'google.com') + }) + + it('should return Access-Control-Allow-Origin if no origin header', async () => { + server.options.allowedOrigins = ['google.com'] + const req = httpMocks.createRequest({ + method: 'OPTIONS', + url: '/', + }) + // @ts-expect-error todo + const res = new http.ServerResponse({method: 'OPTIONS'}) + await server.handle(req, res) + assert.equal(res.hasHeader('Access-Control-Allow-Origin'), true) + assert.equal(res.getHeader('Access-Control-Allow-Origin'), 'google.com') }) it('should not invoke handlers if onIncomingRequest throws', (done) => { @@ -289,7 +360,7 @@ describe('Server', () => { path: route, datastore: new FileStore({directory}), namingFunction() { - return `foo/bar/id` + return 'foo/bar/id' }, generateUrl(_, {proto, host, path, id}) { id = Buffer.from(id, 'utf-8').toString('base64url') @@ -413,7 +484,7 @@ describe('Server', () => { .set('Upload-Offset', '0') .set('Content-Type', 'application/offset+octet-stream') .end((err) => { - assert.equal(received, 4) + assert.ok(received >= 4, 'should have received 4 or more events') done(err) }) }) @@ -495,8 +566,8 @@ describe('Server', () => { path: '/test/output', datastore: new FileStore({directory}), onUploadFinish(_, __, upload) { - assert.ok(upload.storage!.path, 'should have storage.path') - assert.ok(upload.storage!.type, 'should have storage.type') + assert.ok(upload.storage?.path, 'should have storage.path') + assert.ok(upload.storage?.type, 'should have storage.type') throw {body: 'no', status_code: 500} }, }) diff --git a/packages/server/test/utils.ts b/packages/server/test/utils.ts index 8e2b906f..aae8d03b 100644 --- a/packages/server/test/utils.ts +++ b/packages/server/test/utils.ts @@ -1,32 +1,47 @@ -import httpMocks from 'node-mocks-http' -import stream from 'node:stream' +import type httpMocks from 'node-mocks-http' +import stream, {Readable, Transform, TransformCallback} from 'node:stream' import type http from 'node:http' export function addPipableStreamBody< - T extends httpMocks.MockRequest + T extends httpMocks.MockRequest, >(mockRequest: T) { // Create a Readable stream that simulates the request body const bodyStream = new stream.Duplex({ read() { - this.push( - mockRequest.body instanceof Buffer - ? mockRequest.body - : JSON.stringify(mockRequest.body) - ) - this.push(null) + // This function is intentionally left empty since the data flow + // is controlled by event listeners registered outside of this method. }, }) + // Handle cases where the body is a Readable stream + if (mockRequest.body instanceof Readable) { + // Pipe the mockRequest.body to the bodyStream + mockRequest.body.on('data', (chunk) => { + bodyStream.push(chunk) // Push the chunk to the bodyStream + }) + + mockRequest.body.on('end', () => { + bodyStream.push(null) // Signal the end of the stream + }) + } else { + // Handle cases where the body is not a stream (e.g., Buffer or plain object) + const bodyBuffer = + mockRequest.body instanceof Buffer + ? mockRequest.body + : Buffer.from(JSON.stringify(mockRequest.body)) + + // Push the bodyBuffer and signal the end of the stream + bodyStream.push(bodyBuffer) + bodyStream.push(null) + } + // Add the pipe method to the mockRequest // @ts-ignore - mockRequest.pipe = function (dest: stream.Writable) { - return bodyStream.pipe(dest) - } + mockRequest.pipe = (dest: stream.Writable) => bodyStream.pipe(dest) // Add the unpipe method to the mockRequest // @ts-ignore - mockRequest.unpipe = function (dest: stream.Writable) { - return bodyStream.unpipe(dest) - } + mockRequest.unpipe = (dest: stream.Writable) => bodyStream.unpipe(dest) + return mockRequest } diff --git a/packages/server/tsconfig.build.json b/packages/server/tsconfig.build.json index 1342a95a..06719e77 100644 --- a/packages/server/tsconfig.build.json +++ b/packages/server/tsconfig.build.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/tsconfig.json", - "references": [{"path": "../utils/tsconfig.build.json"}], + "references": [{ "path": "../utils/tsconfig.build.json" }], "extends": "../../tsconfig.base.json", "include": ["src"], "compilerOptions": { diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json index 3a707d7e..867c29f9 100644 --- a/packages/server/tsconfig.json +++ b/packages/server/tsconfig.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/tsconfig.json", - "references": [{"path": "./tsconfig.build.json"}], + "references": [{ "path": "./tsconfig.build.json" }], "extends": "../../tsconfig.base.json", "exclude": ["src"], "compilerOptions": { diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md index 50ab4d69..51d02144 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -1,5 +1,23 @@ # @tus/utils +## 0.5.1 + +### Patch Changes + +- 42c6267: Consistent cancellation across streams and locks, fixing lock on file never being unlocked when the request ends prematurely. + +## 0.5.0 + +### Minor Changes + +- 8f19a53: Add IoRedisKvStore & use redis.scan instead of discouraged redis.keys + +## 0.4.0 + +### Minor Changes + +- de28c6e: Publish source maps and declaration maps + ## 0.3.0 ### Minor Changes diff --git a/packages/utils/package.json b/packages/utils/package.json index 6c8ca864..7d097f87 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@tus/utils", - "version": "0.3.0", + "version": "0.5.1", "description": "Internal utils for tus Node.js server and stores", "main": "dist/index.js", "homepage": "https://github.com/tus/tus-node-server#readme", @@ -11,21 +11,19 @@ "files": [ "README.md", "LICENSE", - "dist" + "dist", + "src" ], "scripts": { "build": "tsc --build", - "lint": "eslint .", - "format": "eslint --fix .", "test": "mocha --timeout 40000 --exit --extension ts --require ts-node/register" }, "devDependencies": { "@types/debug": "^4.1.12", "@types/mocha": "^10.0.6", - "@types/node": "^20.11.5", - "eslint": "^8.57.0", - "eslint-config-custom": "^0.0.0", - "mocha": "^10.4.0", + "@types/node": "^22.10.1", + "ioredis": "^5.4.1", + "mocha": "^11.0.1", "should": "^13.2.3", "ts-node": "^10.9.2" }, diff --git a/packages/utils/src/kvstores/FileKvStore.ts b/packages/utils/src/kvstores/FileKvStore.ts index 9c705058..8bbee4d7 100644 --- a/packages/utils/src/kvstores/FileKvStore.ts +++ b/packages/utils/src/kvstores/FileKvStore.ts @@ -1,8 +1,8 @@ import fs from 'node:fs/promises' import path from 'node:path' -import {KvStore} from './Types' -import {Upload} from '../models' +import type {KvStore} from './Types' +import type {Upload} from '../models' /** * FileConfigstore writes the `Upload` JSON metadata to disk next the uploaded file itself. diff --git a/packages/utils/src/kvstores/IoRedisKvStore.ts b/packages/utils/src/kvstores/IoRedisKvStore.ts new file mode 100644 index 00000000..8d4a1891 --- /dev/null +++ b/packages/utils/src/kvstores/IoRedisKvStore.ts @@ -0,0 +1,54 @@ +import type {Redis as IoRedis} from 'ioredis' +import type {KvStore} from './Types' +import type {Upload} from '../models' + +export class IoRedisKvStore implements KvStore { + constructor( + private redis: IoRedis, + private prefix = '' + ) { + this.redis = redis + this.prefix = prefix + } + + private prefixed(key: string): string { + return `${this.prefix}${key}` + } + + async get(key: string): Promise { + return this.deserializeValue(await this.redis.get(this.prefixed(key))) + } + + async set(key: string, value: T): Promise { + await this.redis.set(this.prefixed(key), this.serializeValue(value)) + } + + async delete(key: string): Promise { + await this.redis.del(this.prefixed(key)) + } + + async list(): Promise> { + 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) + } + + private serializeValue(value: T): string { + return JSON.stringify(value) + } + + private deserializeValue(buffer: string | null): T | undefined { + return buffer ? JSON.parse(buffer) : undefined + } +} diff --git a/packages/utils/src/kvstores/MemoryKvStore.ts b/packages/utils/src/kvstores/MemoryKvStore.ts index 83420d77..8c01a528 100644 --- a/packages/utils/src/kvstores/MemoryKvStore.ts +++ b/packages/utils/src/kvstores/MemoryKvStore.ts @@ -1,5 +1,5 @@ -import {Upload} from '../models' -import {KvStore} from './Types' +import type {Upload} from '../models' +import type {KvStore} from './Types' /** * Memory based configstore. diff --git a/packages/utils/src/kvstores/RedisKvStore.ts b/packages/utils/src/kvstores/RedisKvStore.ts index 667680d1..c1550ecd 100644 --- a/packages/utils/src/kvstores/RedisKvStore.ts +++ b/packages/utils/src/kvstores/RedisKvStore.ts @@ -1,6 +1,6 @@ -import {RedisClientType} from '@redis/client' -import {KvStore} from './Types' -import {Upload} from '../models' +import type {RedisClientType} from '@redis/client' +import type {KvStore} from './Types' +import type {Upload} from '../models' /** * Redis based configstore. @@ -8,7 +8,10 @@ import {Upload} from '../models' * @author Mitja Puzigaća */ export class RedisKvStore implements KvStore { - constructor(private redis: RedisClientType, private prefix: string = '') { + constructor( + private redis: RedisClientType, + private prefix = '' + ) { this.redis = redis this.prefix = prefix } @@ -26,7 +29,14 @@ export class RedisKvStore implements KvStore { } async list(): Promise> { - return this.redis.keys(this.prefix + '*') + 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) } private serializeValue(value: T): string { diff --git a/packages/utils/src/kvstores/Types.ts b/packages/utils/src/kvstores/Types.ts index 280a8585..740d3410 100644 --- a/packages/utils/src/kvstores/Types.ts +++ b/packages/utils/src/kvstores/Types.ts @@ -1,4 +1,4 @@ -import {Upload} from '../models' +import type {Upload} from '../models' export interface KvStore { get(key: string): Promise diff --git a/packages/utils/src/kvstores/index.ts b/packages/utils/src/kvstores/index.ts index 0ec840c1..5d2aff72 100644 --- a/packages/utils/src/kvstores/index.ts +++ b/packages/utils/src/kvstores/index.ts @@ -1,4 +1,5 @@ export {FileKvStore} from './FileKvStore' export {MemoryKvStore} from './MemoryKvStore' export {RedisKvStore} from './RedisKvStore' +export {IoRedisKvStore} from './IoRedisKvStore' export {KvStore} from './Types' diff --git a/packages/utils/src/models/DataStore.ts b/packages/utils/src/models/DataStore.ts index fb05b614..e399696a 100644 --- a/packages/utils/src/models/DataStore.ts +++ b/packages/utils/src/models/DataStore.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ import EventEmitter from 'node:events' import {Upload} from './Upload' @@ -10,7 +9,7 @@ export class DataStore extends EventEmitter { extensions: string[] = [] hasExtension(extension: string) { - return this.extensions && this.extensions.includes(extension) + return this.extensions?.includes(extension) } /** @@ -50,7 +49,12 @@ export class DataStore extends EventEmitter { * the upload. */ async getUpload(id: string): Promise { - return new Upload({id, size: 0, offset: 0, storage: {type: 'datastore', path: ''}}) + return new Upload({ + id, + size: 0, + offset: 0, + storage: {type: 'datastore', path: ''}, + }) } /** diff --git a/packages/utils/src/models/Locker.ts b/packages/utils/src/models/Locker.ts index e4365f4b..c05ed54f 100644 --- a/packages/utils/src/models/Locker.ts +++ b/packages/utils/src/models/Locker.ts @@ -26,6 +26,6 @@ export interface Locker { * */ export interface Lock { - lock(cancelReq: RequestRelease): Promise + lock(signal: AbortSignal, cancelReq: RequestRelease): Promise unlock(): Promise } diff --git a/packages/utils/src/models/Metadata.ts b/packages/utils/src/models/Metadata.ts index d81f5a21..a17cc6cd 100644 --- a/packages/utils/src/models/Metadata.ts +++ b/packages/utils/src/models/Metadata.ts @@ -1,4 +1,4 @@ -import {Upload} from './Upload' +import type {Upload} from './Upload' const ASCII_SPACE = ' '.codePointAt(0) const ASCII_COMMA = ','.codePointAt(0) diff --git a/packages/utils/src/models/StreamLimiter.ts b/packages/utils/src/models/StreamLimiter.ts index 9b040e5e..8a35df96 100644 --- a/packages/utils/src/models/StreamLimiter.ts +++ b/packages/utils/src/models/StreamLimiter.ts @@ -1,4 +1,4 @@ -import {Transform, TransformCallback} from 'stream' +import {Transform, type TransformCallback} from 'node:stream' import {ERRORS} from '../constants' // TODO: create HttpError and use it everywhere instead of throwing objects diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json index 3a707d7e..867c29f9 100644 --- a/packages/utils/tsconfig.json +++ b/packages/utils/tsconfig.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/tsconfig.json", - "references": [{"path": "./tsconfig.build.json"}], + "references": [{ "path": "./tsconfig.build.json" }], "extends": "../../tsconfig.base.json", "exclude": ["src"], "compilerOptions": { diff --git a/test/package.json b/test/package.json index bff25578..8dd0d7b0 100644 --- a/test/package.json +++ b/test/package.json @@ -11,22 +11,22 @@ }, "dependencies": { "@google-cloud/storage": "^7.12.0", - "@tus/file-store": "^1.4.0", - "@tus/gcs-store": "^1.3.0", - "@tus/s3-store": "^1.5.0", - "@tus/server": "^1.7.0" + "@tus/file-store": "^1.5.1", + "@tus/gcs-store": "^1.4.1", + "@tus/s3-store": "^1.7.0", + "@tus/server": "^1.10.1" }, "devDependencies": { "@types/mocha": "^10.0.6", - "@types/node": "^20.11.5", + "@types/node": "^22.10.1", "@types/rimraf": "^3.0.2", "@types/sinon": "^17.0.3", "@types/supertest": "^2.0.16", "@types/throttle": "^1.0.4", - "mocha": "^10.4.0", + "mocha": "^11.0.1", "rimraf": "^3.0.2", "should": "^13.2.3", - "sinon": "^17.0.1", + "sinon": "^18.0.0", "supertest": "^6.3.4", "throttle": "^1.0.3", "ts-node": "^10.9.2" diff --git a/test/src/e2e.test.ts b/test/src/e2e.test.ts index 6917bac7..009c1b6a 100644 --- a/test/src/e2e.test.ts +++ b/test/src/e2e.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable max-nested-callbacks */ import path from 'node:path' import fs from 'node:fs' import {strict as assert} from 'node:assert' @@ -8,16 +7,16 @@ import request from 'supertest' import {Storage} from '@google-cloud/storage' import {MemoryLocker, Server, TUS_RESUMABLE} from '@tus/server' -import {Configstore, MemoryConfigstore} from '@tus/file-store' +import {type Configstore, MemoryConfigstore} from '@tus/file-store' import {FileStore} from '@tus/file-store' import {GCSStore} from '@tus/gcs-store' import http from 'node:http' import sinon from 'sinon' import Throttle from 'throttle' -import {Agent} from 'http' -import {Buffer} from 'buffer' -import {AddressInfo} from 'net' +import {Agent} from 'node:http' +import {Buffer} from 'node:buffer' +import type {AddressInfo} from 'node:net' const STORE_PATH = '/test' const PROJECT_ID = 'tus-node-server' @@ -53,7 +52,7 @@ describe('EndToEnd', () => { let file_id: string let deferred_file_id: string - before(async function () { + before(async () => { await fs.promises.mkdir(FILES_DIRECTORY, {recursive: true}) server = new Server({ path: STORE_PATH, @@ -65,19 +64,20 @@ describe('EndToEnd', () => { after((done) => { // Remove the files directory - rimraf(FILES_DIRECTORY, (err) => { + rimraf(FILES_DIRECTORY, async (err) => { if (err) { return done(err) } // Clear the config - // @ts-expect-error we can consider a generic to pass to // datastore to narrow down the store type - const uploads = (server.datastore.configstore as Configstore).list?.() ?? [] + const uploads = + // @ts-expect-error we can consider a generic to pass to + (server.datastore.configstore as Configstore).list?.() ?? [] for (const upload in uploads) { // @ts-expect-error we can consider a generic to pass to // datastore to narrow down the store type - await(server.datastore.configstore as Configstore).delete(upload) + await (server.datastore.configstore as Configstore).delete(upload) } listener.close() return done() @@ -289,19 +289,20 @@ describe('EndToEnd', () => { after((done) => { // Remove the files directory - rimraf(FILES_DIRECTORY, (err) => { + rimraf(FILES_DIRECTORY, async (err) => { if (err) { return done(err) } // Clear the config - // @ts-expect-error we can consider a generic to pass to // datastore to narrow down the store type - const uploads = (server.datastore.configstore as Configstore).list?.() ?? [] + const uploads = + // @ts-expect-error we can consider a generic to pass to + (server.datastore.configstore as Configstore).list?.() ?? [] for (const upload in uploads) { // @ts-expect-error we can consider a generic to pass to // datastore to narrow down the store type - await(server.datastore.configstore as Configstore).delete(upload) + await (server.datastore.configstore as Configstore).delete(upload) } listener.close() return done() @@ -309,7 +310,7 @@ describe('EndToEnd', () => { }) it('will allow terminating finished uploads', async () => { - const body = Buffer.alloc(parseInt(TEST_FILE_SIZE, 10)) + const body = Buffer.alloc(Number.parseInt(TEST_FILE_SIZE, 10)) const res = await agent .post(STORE_PATH) .set('Tus-Resumable', TUS_RESUMABLE) @@ -346,7 +347,7 @@ describe('EndToEnd', () => { const listener = server.listen() const agent = request.agent(listener) - const body = Buffer.alloc(parseInt(TEST_FILE_SIZE, 10)) + const body = Buffer.alloc(Number.parseInt(TEST_FILE_SIZE, 10)) const res = await agent .post(STORE_PATH) .set('Tus-Resumable', TUS_RESUMABLE) @@ -601,7 +602,7 @@ describe('EndToEnd', () => { .expect(204) .expect('Tus-Resumable', TUS_RESUMABLE) - return parseInt(res.headers['upload-offset'] || '0', 0) + return Number.parseInt(res.headers['upload-offset'] || '0', 0) } let offset = 0 @@ -716,7 +717,7 @@ describe('EndToEnd', () => { .send(body) .expect(204) .expect('Tus-Resumable', TUS_RESUMABLE) - return parseInt(res.headers['upload-offset'] || '0', 0) + return Number.parseInt(res.headers['upload-offset'] || '0', 0) } let offset = 0 @@ -1055,19 +1056,20 @@ describe('EndToEnd', () => { after((done) => { // Remove the files directory - rimraf(FILES_DIRECTORY, (err) => { + rimraf(FILES_DIRECTORY, async (err) => { if (err) { return done(err) } // Clear the config - // @ts-expect-error we can consider a generic to pass to // datastore to narrow down the store type - const uploads = (server.datastore.configstore as Configstore).list?.() ?? [] + const uploads = + // @ts-expect-error we can consider a generic to pass to + (server.datastore.configstore as Configstore).list?.() ?? [] for (const upload in uploads) { // @ts-expect-error we can consider a generic to pass to // datastore to narrow down the store type - await(server.datastore.configstore as Configstore).delete(upload) + await (server.datastore.configstore as Configstore).delete(upload) } listener.close() return done() @@ -1087,7 +1089,7 @@ describe('EndToEnd', () => { assert.equal(res.headers['tus-resumable'], TUS_RESUMABLE) // Save the id for subsequent tests const file_id = res.headers.location.split('/').pop() - const file_size = parseInt(TEST_FILE_SIZE, 10) + const file_size = Number.parseInt(TEST_FILE_SIZE, 10) // Slow down writing const originalWrite = server.datastore.write.bind(server.datastore) @@ -1096,7 +1098,7 @@ describe('EndToEnd', () => { return originalWrite(stream.pipe(throttleStream), ...args) }) - const data = Buffer.alloc(parseInt(TEST_FILE_SIZE, 10), 'a') + const data = Buffer.alloc(Number.parseInt(TEST_FILE_SIZE, 10), 'a') const httpAgent = new Agent({ maxSockets: 2, maxFreeSockets: 10, @@ -1134,7 +1136,7 @@ describe('EndToEnd', () => { // Verify that we are able to resume even if the first request // was cancelled by the second request trying to acquire the lock - const offset = parseInt(res2.value.headers['upload-offset'], 10) + const offset = Number.parseInt(res2.value.headers['upload-offset'], 10) const finishedUpload = await createPatchReq(offset) diff --git a/test/src/s3.e2e.ts b/test/src/s3.e2e.ts index 802d723d..4c6fed6a 100644 --- a/test/src/s3.e2e.ts +++ b/test/src/s3.e2e.ts @@ -1,8 +1,8 @@ import {S3Store} from '@tus/s3-store' import {Server, TUS_RESUMABLE} from '@tus/server' -import {SuperAgentTest} from 'supertest' +import type {SuperAgentTest} from 'supertest' import request from 'supertest' -import http from 'node:http' +import type http from 'node:http' import {describe} from 'node:test' import {strict as assert} from 'node:assert' import {S3, S3ServiceException} from '@aws-sdk/client-s3' @@ -71,7 +71,7 @@ const patchUpload = async ( const res = await req.send(data).expect(204) - return {offset: parseInt(res.headers['upload-offset'], 10)} + return {offset: Number.parseInt(res.headers['upload-offset'], 10)} } describe('S3 Store E2E', () => { @@ -122,7 +122,7 @@ describe('S3 Store E2E', () => { const {TagSet} = await s3Client.getObjectTagging({ Bucket: s3Credentials.bucket, - Key: uploadId + '.info', + Key: `${uploadId}.info`, }) assert( @@ -144,7 +144,7 @@ describe('S3 Store E2E', () => { const {TagSet} = await s3Client.getObjectTagging({ Bucket: s3Credentials.bucket, - Key: uploadId + '.info', + Key: `${uploadId}.info`, }) assert( @@ -172,7 +172,7 @@ describe('S3 Store E2E', () => { const {TagSet} = await s3Client.getObjectTagging({ Bucket: s3Credentials.bucket, - Key: uploadId + '.info', + Key: `${uploadId}.info`, }) assert.equal(TagSet?.length, 0) @@ -205,7 +205,7 @@ describe('S3 Store E2E', () => { const {TagSet} = await s3Client.getObjectTagging({ Bucket: s3Credentials.bucket, - Key: uploadId + '.info', + Key: `${uploadId}.info`, }) assert.equal(TagSet?.length, 0) @@ -222,11 +222,11 @@ describe('S3 Store E2E', () => { const [infoFile, partFile] = await Promise.all([ s3Client.getObject({ Bucket: s3Credentials.bucket, - Key: uploadId + '.info', + Key: `${uploadId}.info`, }), s3Client.getObject({ Bucket: s3Credentials.bucket, - Key: uploadId + '.part', + Key: `${uploadId}.part`, }), ]) @@ -245,11 +245,11 @@ describe('S3 Store E2E', () => { const files = await Promise.allSettled([ s3Client.getObject({ Bucket: s3Credentials.bucket, - Key: uploadId + '.info', + Key: `${uploadId}.info`, }), s3Client.getObject({ Bucket: s3Credentials.bucket, - Key: uploadId + '.part', + Key: `${uploadId}.part`, }), ]) diff --git a/test/src/stores.test.ts b/test/src/stores.test.ts index bdf97d30..5463ca4e 100644 --- a/test/src/stores.test.ts +++ b/test/src/stores.test.ts @@ -6,14 +6,11 @@ import {setTimeout as promSetTimeout} from 'node:timers/promises' import {Upload, Uid} from '@tus/server' -// In CI we run multiple jobs in parallel, -// so we need to make sure that the IDs are unique. export function testId(id: string) { - // eslint-disable-next-line turbo/no-undeclared-env-vars - return `${id}-${process.env.GITHUB_JOB ?? Uid.rand()}` + return `${id}-${Uid.rand()}` } -export const shouldHaveStoreMethods = function () { +export const shouldHaveStoreMethods = () => { describe('the class', () => { it('must have a write method', function (done) { this.datastore.should.have.property('write') @@ -27,7 +24,7 @@ export const shouldHaveStoreMethods = function () { }) } -export const shouldCreateUploads = function () { +export const shouldCreateUploads = () => { describe('create', () => { const file = new Upload({ id: testId('create-test'), @@ -77,7 +74,7 @@ export const shouldCreateUploads = function () { }) } -export const shouldExpireUploads = function () { +export const shouldExpireUploads = () => { describe('expiration extension', () => { it("should report 'expiration' extension", function () { assert.equal(this.datastore.hasExtension('expiration'), true) @@ -102,7 +99,7 @@ export const shouldExpireUploads = function () { }) } -export const shouldRemoveUploads = function () { +export const shouldRemoveUploads = () => { const file = new Upload({id: testId('remove-test'), size: 1000, offset: 0}) describe('remove (termination extension)', () => { @@ -128,7 +125,9 @@ export const shouldRemoveUploads = function () { }) await this.datastore.create(file) - const readable = fs.createReadStream(this.testFilePath, {highWaterMark: 100 * 1024}) + 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() @@ -152,7 +151,7 @@ export const shouldRemoveUploads = function () { }) } -export const shouldWriteUploads = function () { +export const shouldWriteUploads = () => { describe('write', () => { it('should reject write streams that can not be open', async function () { const stream = fs.createReadStream(this.testFilePath) @@ -197,8 +196,8 @@ export const shouldWriteUploads = function () { }) } -export const shouldHandleOffset = function () { - describe('getUpload', function () { +export const shouldHandleOffset = () => { + describe('getUpload', () => { it('should reject non-existant files', function () { return this.datastore.getUpload('doesnt_exist').should.be.rejected() }) @@ -223,7 +222,7 @@ export const shouldHandleOffset = function () { }) } -export const shouldDeclareUploadLength = function () { +export const shouldDeclareUploadLength = () => { describe('declareUploadLength', () => { it('should reject non-existant files', function () { return this.datastore.declareUploadLength('doesnt_exist', '10').should.be.rejected() diff --git a/test/tsconfig.json b/test/tsconfig.json index 2c512eed..e27cf8a4 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -1,10 +1,11 @@ { "$schema": "https://json.schemastore.org/tsconfig.json", "references": [ - {"path": "../packages/file-store/tsconfig.build.json"}, - {"path": "../packages/gcs-store/tsconfig.build.json"}, - {"path": "../packages/s3-store/tsconfig.build.json"}, - {"path": "../packages/server/tsconfig.build.json"} + { "path": "../packages/azure-store/tsconfig.build.json" }, + { "path": "../packages/file-store/tsconfig.build.json" }, + { "path": "../packages/gcs-store/tsconfig.build.json" }, + { "path": "../packages/s3-store/tsconfig.build.json" }, + { "path": "../packages/server/tsconfig.build.json" } ], "extends": "../tsconfig.base.json", "include": ["src"], diff --git a/tsconfig.base.json b/tsconfig.base.json index a9598a7e..fa960cdc 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -7,6 +7,8 @@ "target": "es2020", "strict": true, "declaration": true, + "declarationMap": true, + "sourceMap": true, "useUnknownInCatchVariables": false } } diff --git a/tsconfig.json b/tsconfig.json index e4ba358d..d92eef87 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,11 +2,12 @@ "$schema": "https://json.schemastore.org/tsconfig.json", "files": [], "references": [ - {"path": "packages/file-store/tsconfig.json"}, - {"path": "packages/gcs-store/tsconfig.json"}, - {"path": "packages/s3-store/tsconfig.json"}, - {"path": "packages/server/tsconfig.json"}, - {"path": "packages/utils/tsconfig.json"}, - {"path": "test/tsconfig.json"} + { "path": "packages/azure-store/tsconfig.json" }, + { "path": "packages/file-store/tsconfig.json" }, + { "path": "packages/gcs-store/tsconfig.json" }, + { "path": "packages/s3-store/tsconfig.json" }, + { "path": "packages/server/tsconfig.json" }, + { "path": "packages/utils/tsconfig.json" }, + { "path": "test/tsconfig.json" } ] } diff --git a/turbo.json b/turbo.json deleted file mode 100644 index 4c16bee6..00000000 --- a/turbo.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "https://turbo.build/schema.json", - "pipeline": { - "build": { - "dependsOn": ["^build"], - "outputs": ["dist/**"] - }, - "test": { - "dependsOn": ["build"], - "env": [ - "AWS_BUCKET", - "AWS_ACCESS_KEY_ID", - "AWS_SECRET_ACCESS_KEY", - "AWS_REGION", - "GITHUB_JOB" - ], - "outputs": [] - }, - "lint": { - "outputs": [] - }, - "format": { - "outputs": [] - } - } -}